1 /*
2 * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "KChartRelativePosition.h"
21
22 #include "KChartEnums.h"
23 #include "KChartMeasure.h"
24 #include "KChartPosition.h"
25 #include "KChartAbstractArea.h"
26 #include "KChartMath_p.h"
27
28 #include <QWidget>
29 #include <QLayout>
30
31 using namespace KChart;
32
33 class Q_DECL_HIDDEN RelativePosition::Private {
34 friend class ::KChart::RelativePosition;
35 public:
36 Private();
37 ~Private();
38
39 private:
40 QObject* area;
41 PositionPoints points;
42 Position position;
43 Qt::Alignment alignment;
44 Measure horizontalPadding;
45 Measure verticalPadding;
46 qreal rotation;
47 };
48
49
Private()50 RelativePosition::Private::Private()
51 : area( nullptr ),
52 alignment( Qt::AlignCenter ),
53 rotation( 0 )
54 {
55
56 }
57
~Private()58 RelativePosition::Private::~Private()
59 {}
60
61
62
RelativePosition()63 RelativePosition::RelativePosition()
64 : _d( new Private )
65 {
66
67 }
68
RelativePosition(const RelativePosition & r)69 RelativePosition::RelativePosition( const RelativePosition& r )
70 : _d( new Private( *r._d ) )
71 {
72
73 }
74
operator =(const RelativePosition & other)75 RelativePosition & RelativePosition::operator=( const RelativePosition & other ) {
76 RelativePosition copy( other );
77 copy.swap( *this );
78 return *this;
79 }
80
~RelativePosition()81 RelativePosition::~RelativePosition()
82 {
83 delete _d;
84 }
85
86 #define d d_func()
87
setReferenceArea(QObject * area)88 void RelativePosition::setReferenceArea( QObject * area ) {
89 d->area = area;
90 if ( area )
91 setReferencePoints( PositionPoints() );
92 }
93
referenceArea() const94 QObject * RelativePosition::referenceArea() const {
95 return d->area;
96 }
97
setReferencePoints(const PositionPoints & points)98 void RelativePosition::setReferencePoints( const PositionPoints& points ) {
99 d->points = points;
100 if ( !points.isNull() )
101 setReferenceArea( nullptr );
102 }
referencePoints() const103 const PositionPoints RelativePosition::referencePoints() const{
104 return d->points;
105 }
106
setReferencePosition(Position pos)107 void RelativePosition::setReferencePosition( Position pos ) {
108 d->position = pos;
109 }
110
resetReferencePosition()111 void RelativePosition::resetReferencePosition() {
112 d->position = Position::Unknown;
113 }
114
referencePosition() const115 Position RelativePosition::referencePosition() const {
116 return d->position;
117 }
118
setAlignment(Qt::Alignment align)119 void RelativePosition::setAlignment( Qt::Alignment align ) {
120 d->alignment = align;
121 }
122
alignment() const123 Qt::Alignment RelativePosition::alignment() const {
124 return d->alignment;
125 }
126
setHorizontalPadding(const Measure & pad)127 void RelativePosition::setHorizontalPadding( const Measure & pad ) {
128 d->horizontalPadding = pad;
129 }
130
horizontalPadding() const131 Measure RelativePosition::horizontalPadding() const {
132 return d->horizontalPadding;
133 }
134
setVerticalPadding(const Measure & pad)135 void RelativePosition::setVerticalPadding( const Measure & pad ) {
136 d->verticalPadding = pad;
137 }
138
verticalPadding() const139 Measure RelativePosition::verticalPadding() const {
140 return d->verticalPadding;
141 }
142
setRotation(qreal rot)143 void RelativePosition::setRotation( qreal rot ) {
144 d->rotation = rot;
145 }
146
rotation() const147 qreal RelativePosition::rotation() const {
148 return d->rotation;
149 }
150
151
referencePoint(qreal * polarDegrees) const152 const QPointF RelativePosition::referencePoint( qreal* polarDegrees ) const
153 {
154 bool useRect = ( d->area != nullptr );
155 QRect rect;
156 if ( useRect ) {
157 if ( const QWidget* widget = qobject_cast< const QWidget* >( d->area ) ) {
158 const QLayout* layout = widget->layout();
159 rect = layout ? layout->geometry() : widget->geometry();
160 } else if ( const AbstractArea* kdcArea = qobject_cast< const AbstractArea* >( d->area ) ) {
161 rect = kdcArea->geometry();
162 } else {
163 useRect = false;
164 }
165 }
166
167 QPointF pt;
168 qreal angle = 0.0;
169 if ( useRect ) {
170 pt = PositionPoints( rect ).point( d->position );
171 } else {
172 pt = d->points.point( d->position );
173 angle = d->points.degrees( d->position.value() );
174 }
175
176 if ( polarDegrees ) {
177 *polarDegrees = angle;
178 }
179 return pt;
180 }
181
182
calculatedPoint(const QSizeF & autoSize) const183 const QPointF RelativePosition::calculatedPoint( const QSizeF& autoSize ) const
184 {
185 const qreal dx = horizontalPadding().calculatedValue( autoSize, KChartEnums::MeasureOrientationHorizontal );
186 const qreal dy = verticalPadding().calculatedValue( autoSize, KChartEnums::MeasureOrientationVertical );
187
188 qreal polarDegrees;
189 QPointF pt( referencePoint( &polarDegrees ) );
190 if ( polarDegrees == 0.0 ) {
191 pt += QPointF( dx, dy );
192 } else {
193 const qreal rad = DEGTORAD( polarDegrees);
194 const qreal sinDeg = sin(rad);
195 const qreal cosDeg = cos(rad);
196 pt.setX( pt.x() + dx * cosDeg + dy * sinDeg );
197 pt.setY( pt.y() - dx * sinDeg + dy * cosDeg );
198 }
199 return pt;
200 }
201
202
operator ==(const RelativePosition & r) const203 bool RelativePosition::operator==( const RelativePosition& r ) const
204 {
205 return d->area == r.referenceArea() &&
206 d->position == r.referencePosition() &&
207 d->alignment == r.alignment() &&
208 d->horizontalPadding == r.horizontalPadding() &&
209 d->verticalPadding == r.verticalPadding() &&
210 d->rotation == r.rotation() ;
211 }
212
213 #undef d
214
215
216 #if !defined(QT_NO_DEBUG_STREAM)
operator <<(QDebug dbg,const KChart::RelativePosition & rp)217 QDebug operator<<(QDebug dbg, const KChart::RelativePosition& rp)
218 {
219 dbg << "KChart::RelativePosition("
220 << "referencearea="<<rp.referenceArea()
221 << "referenceposition="<<rp.referencePosition()
222 << "alignment="<<rp.alignment()
223 << "horizontalpadding="<<rp.horizontalPadding()
224 << "verticalpadding="<<rp.verticalPadding()
225 << "rotation="<<rp.rotation()
226 << ")";
227 return dbg;
228 }
229 #endif /* QT_NO_DEBUG_STREAM */
230