00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2011 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 00014 ** 00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 ** 00018 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "KDChartRelativePosition.h" 00024 00025 #include "KDChartEnums.h" 00026 #include "KDChartMeasure.h" 00027 #include "KDChartPosition.h" 00028 #include "KDChartAbstractArea.h" 00029 00030 #include <QWidget> 00031 #include <QLayout> 00032 00033 #include <KDABLibFakes> 00034 00035 using namespace KDChart; 00036 00037 class RelativePosition::Private { 00038 friend class ::KDChart::RelativePosition; 00039 public: 00040 Private(); 00041 ~Private(); 00042 00043 private: 00044 QObject* area; 00045 PositionPoints points; 00046 Position position; 00047 Qt::Alignment alignment; 00048 Measure horizontalPadding; 00049 Measure verticalPadding; 00050 qreal rotation; 00051 }; 00052 00053 00054 RelativePosition::Private::Private() 00055 : area( 0 ), 00056 alignment( Qt::AlignCenter ), 00057 rotation( 0 ) 00058 { 00059 00060 } 00061 00062 RelativePosition::Private::~Private() 00063 {} 00064 00065 00066 00067 RelativePosition::RelativePosition() 00068 : _d( new Private ) 00069 { 00070 00071 } 00072 00073 RelativePosition::RelativePosition( const RelativePosition& r ) 00074 : _d( new Private( *r._d ) ) 00075 { 00076 00077 } 00078 00079 RelativePosition & RelativePosition::operator=( const RelativePosition & other ) { 00080 RelativePosition copy( other ); 00081 copy.swap( *this ); 00082 return *this; 00083 } 00084 00085 RelativePosition::~RelativePosition() 00086 { 00087 delete _d; 00088 } 00089 00090 #define d d_func() 00091 00092 void RelativePosition::setReferenceArea( QObject * area ) { 00093 d->area = area; 00094 if( area ) 00095 setReferencePoints( PositionPoints() ); 00096 } 00097 00098 QObject * RelativePosition::referenceArea() const { 00099 return d->area; 00100 } 00101 00102 void RelativePosition::setReferencePoints( const PositionPoints& points ){ 00103 d->points = points; 00104 if( !points.isNull() ) 00105 setReferenceArea( 0 ); 00106 } 00107 const PositionPoints RelativePosition::referencePoints() const{ 00108 return d->points; 00109 } 00110 00111 void RelativePosition::setReferencePosition( Position pos ) { 00112 d->position = pos; 00113 } 00114 00115 void RelativePosition::resetReferencePosition() { 00116 d->position = Position::Unknown; 00117 } 00118 00119 Position RelativePosition::referencePosition() const { 00120 return d->position; 00121 } 00122 00123 void RelativePosition::setAlignment( Qt::Alignment align ) { 00124 d->alignment = align; 00125 } 00126 00127 Qt::Alignment RelativePosition::alignment() const { 00128 return d->alignment; 00129 } 00130 00131 void RelativePosition::setHorizontalPadding( const Measure & pad ) { 00132 d->horizontalPadding = pad; 00133 } 00134 00135 Measure RelativePosition::horizontalPadding() const { 00136 return d->horizontalPadding; 00137 } 00138 00139 void RelativePosition::setVerticalPadding( const Measure & pad ) { 00140 d->verticalPadding = pad; 00141 } 00142 00143 Measure RelativePosition::verticalPadding() const { 00144 return d->verticalPadding; 00145 } 00146 00147 void RelativePosition::setRotation( qreal rot ) { 00148 d->rotation = rot; 00149 } 00150 00151 qreal RelativePosition::rotation() const { 00152 return d->rotation; 00153 } 00154 00155 00156 const QPointF RelativePosition::referencePoint(qreal* polarDegrees) const 00157 { 00158 bool useRect = (d->area != 0); 00159 QRect rect; 00160 if( useRect ){ 00161 const QWidget* widget = dynamic_cast<const QWidget*>(d->area); 00162 if( widget ){ 00163 const QLayout * layout = widget->layout(); 00164 rect = layout ? layout->geometry() : widget->geometry(); 00165 }else{ 00166 const AbstractArea* kdcArea = dynamic_cast<const AbstractArea*>(d->area); 00167 if( kdcArea ) 00168 rect = kdcArea->geometry(); 00169 else 00170 useRect = false; 00171 } 00172 } 00173 QPointF pt; 00174 if ( useRect ){ 00175 pt = PositionPoints( rect ).point( d->position ); 00176 if( polarDegrees ) 00177 *polarDegrees = 0.0; 00178 }else{ 00179 pt = d->points.point( d->position ); 00180 if( polarDegrees ) 00181 *polarDegrees = d->points.degrees( d->position.value() ); 00182 } 00183 return pt; 00184 } 00185 00186 00187 const QPointF RelativePosition::calculatedPoint( const QSizeF& autoSize ) const 00188 { 00189 const qreal dx = horizontalPadding().calculatedValue( autoSize, KDChartEnums::MeasureOrientationHorizontal ); 00190 const qreal dy = verticalPadding() .calculatedValue( autoSize, KDChartEnums::MeasureOrientationVertical ); 00191 qreal polarDegrees; 00192 QPointF pt( referencePoint( &polarDegrees ) ); 00193 if( polarDegrees == 0.0 ){ 00194 pt += QPointF(dx, dy); 00195 }else{ 00196 const qreal rad = DEGTORAD( polarDegrees); 00197 const qreal sinDeg = sin(rad); 00198 const qreal cosDeg = cos(rad); 00199 pt.setX( pt.x() + dx * cosDeg + dy * sinDeg ); 00200 pt.setY( pt.y() - dx * sinDeg + dy * cosDeg ); 00201 } 00202 return pt; 00203 } 00204 00205 00206 bool RelativePosition::operator==( const RelativePosition& r ) const 00207 { 00208 return d->area == r.referenceArea() && 00209 d->position == r.referencePosition() && 00210 d->alignment == r.alignment() && 00211 d->horizontalPadding == r.horizontalPadding() && 00212 d->verticalPadding == r.verticalPadding() && 00213 d->rotation == r.rotation() ; 00214 } 00215 00216 #undef d 00217 00218 00219 #if !defined(QT_NO_DEBUG_STREAM) 00220 QDebug operator<<(QDebug dbg, const KDChart::RelativePosition& rp) 00221 { 00222 dbg << "KDChart::RelativePosition(" 00223 << "referencearea="<<rp.referenceArea() 00224 << "referenceposition="<<rp.referencePosition() 00225 << "alignment="<<rp.alignment() 00226 << "horizontalpadding="<<rp.horizontalPadding() 00227 << "verticalpadding="<<rp.verticalPadding() 00228 << "rotation="<<rp.rotation() 00229 << ")"; 00230 return dbg; 00231 } 00232 #endif /* QT_NO_DEBUG_STREAM */