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