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 #ifndef KCHARTRELATIVEPOSITION_H
21 #define KCHARTRELATIVEPOSITION_H
22 
23 #include <QDebug>
24 #include <QMetaType>
25 #include <Qt>
26 #include <QPointF>
27 #include <QSizeF>
28 #include "KChartGlobal.h"
29 
30 namespace KChart {
31 
32     class Position;
33     class PositionPoints;
34     class Measure;
35 
36 /**
37   \class RelativePosition KChartRelativePosition.h
38   \brief Defines relative position information: reference area, position
39   in this area (reference position), horizontal / vertical padding, and rotation.
40 
41   See detailed description of \a KChart::Position for an illustration of the
42   different possible reference positions.
43 
44   Using RelativePosition you can specify the relative parts
45   of some position information, and you can specify the absolute parts:
46   the reference area, and the position in this area.
47 
48   \note To get an absolute position, you have three options:
49   \li either you declare both, the relative and the absolute parts,
50       using setReferenceArea for the latter,
51   \li or you specify a set of points, using setReferencePoints,
52   \li or you don't use either, leaving it to KChart to find a suitable reference area.
53   */
54 class KCHART_EXPORT RelativePosition
55 {
56 public:
57     RelativePosition();
58     RelativePosition( const RelativePosition& );
59 
60     RelativePosition & operator=( const RelativePosition & other );
61 
62     ~RelativePosition();
63 
64     /**
65      * \brief Set the reference area to be used to find the anchor point.
66      *
67      * The reference area's type can be either a QWidget subclass or a KChart::AbstractArea subclass.
68      *
69      * \note Usage of reference area and reference points is mutually exclusive:
70      * Only one can be used, so any previously set reference points are cleared
71      * when you call setReferenceArea.
72      *
73      * Also note: In a few cases KChart will ignore your area (or points, resp.) settings!
74      * Relative positioning of data value texts is an example: For these
75      * the reference area is always taken to be the data area.
76      *
77      * \sa setReferencePosition, setAlignment, setHorizontalPadding, setVerticalPadding
78      */
79     void setReferenceArea( QObject* area );
80     QObject* referenceArea() const;
81 
82     /**
83      * \brief Set a set of points from which the anchor point will be selected.
84      *
85      * \note Usage of reference area and reference points is mutually exclusive:
86      * Only one can be used, so any previously set reference area is cleared
87      * when you call setReferencePoints.
88      *
89      * Also note: In a few cases KChart will ignore your points (or area, resp.) settings!
90      * Relative positioning of data value texts is an example: For these
91      * the reference area is always taken to be the data area.
92      *
93      * \sa setReferenceArea, setReferencePosition, setAlignment, setHorizontalPadding, setVerticalPadding
94      */
95     void setReferencePoints( const PositionPoints& points );
96     const PositionPoints referencePoints() const;
97 
98     /**
99      * \brief Set the position of the anchor point.
100      *
101      * The anchor point of a RelativePosition may be one of the pre-defined
102      * points of it's reference area - for details see KChart::Position.
103      *
104      * See detailed description of \a KChart::Position for an illustration of the
105      * different possible reference positions.
106      *
107      *  \sa resetReferencePosition, setReferenceArea, setAlignment, setHorizontalPadding, setVerticalPadding, KChart::Position
108      */
109     void setReferencePosition( Position position );
110 
111     /**
112      * \brief Resets the position of the anchor point to the built-in default.
113      *
114      * If the anchor point of a RelativePosition is reset (or never changed from the
115      * default setting) KChart will choose an appropriate Position at run-time.
116      *
117      * e.g. BarDiagrams will use Position::North / Position::South for positive / negative values.
118      *
119      *  \sa setReferencePosition, setReferenceArea, setAlignment, setHorizontalPadding, setVerticalPadding, KChart::Position
120      */
121     void resetReferencePosition();
122     Position referencePosition() const;
123 
124     /**
125      * Set the alignment of the content placed by this RelativePosition.
126      *
127      * Padding is applied first to obtain the final reference point
128      * for the content's alignment
129      *
130      * \note To print centered content, besides calling setAlignment( Qt::AlignCenter )
131      * you might also want to set zero padding to have your text centered more precisely.
132      *
133      * \sa setReferencePosition, setReferenceArea, setHorizontalPadding, setVerticalPadding
134      */
135     void setAlignment( Qt::Alignment flags );
136     Qt::Alignment alignment() const;
137 
138     /**
139      * Set the width of the horizontal padding between the anchor point and the content
140      * placed by this RelativePosition.
141      *
142      * \note When printing data value texts this Measure is used to find the alignment
143      * point for this text, then alignment() is use to determine how to align the text
144      * relative to that point.
145      * The font height is used as reference size for both horizontal and vertical padding
146      * if the respective padding's Measure is using automatic reference area detection.
147      *
148      * \sa setVerticalPadding, setReferencePosition, setReferenceArea
149      */
150     void setHorizontalPadding( const Measure& padding );
151     Measure horizontalPadding() const;
152 
153     /**
154      * Set the height of the vertical padding between the anchor point and the content
155      * placed by this RelativePosition.
156      *
157      * \note When printing data value texts this Measure is used to find the alignment
158      * point for this text, then alignment() is use to determine how to align the text
159      * relative to that point.
160      * The font height is used as reference size for both horizontal and vertical padding
161      * if the respective padding's Measure is using automatic reference area detection.
162      *
163      * \sa setHorizontalPadding, setReferencePosition, setReferenceArea
164      */
165     void setVerticalPadding( const Measure& padding );
166     Measure verticalPadding() const;
167 
168     void setRotation( qreal rot );
169     qreal rotation() const;
170 
171     /**
172      * \brief Return the reference point, according to the reference area/position, and ignoring padding.
173      *
174      * This method is called at drawing time.
175      * The returned point is used to test if the label of a data value is to be printed: a label
176      * is printed only if its reference point is inside or touching the coordinate plane.
177      *
178      * If polarDegrees is set, the degree information will be returned that was stored for the
179      * respective point. This is used by the PieDiagram class to determine how vertical/horizontal
180      * padding settings should affect the position of the data value texts' reference points.
181      * \sa calculatedPoint, setReferenceArea, setReferencePosition, setHorizontalPadding, setVerticalPadding
182      */
183     const QPointF referencePoint(qreal* polarDegrees = nullptr) const;
184 
185     /**
186      * \brief Calculate a point, accordin to the reference area/position and the padding.
187      *
188      * This method is called at drawing time: The returned point is used as anchor point.
189      * Note that it is the task of the calling code to place the content, taking the alignment
190      * property into account. This class does not know the size of the content so it
191      * cannot place it.
192      *
193      * \sa referencePoint, setReferenceArea, setReferencePosition, setHorizontalPadding, setVerticalPadding
194      */
195     const QPointF calculatedPoint( const QSizeF& autoSize ) const;
196 
197     bool operator==( const RelativePosition& ) const;
198     bool operator!=( const RelativePosition & other ) const;
199 
200 private:
201     KCHART_DECLARE_PRIVATE_BASE_VALUE( RelativePosition )
202 };
203 
204 inline bool RelativePosition::operator!=( const RelativePosition & other ) const { return !operator==( other ); }
205 }
206 
207 #if !defined(QT_NO_DEBUG_STREAM)
208 KCHART_EXPORT QDebug operator<<(QDebug, const KChart::RelativePosition& );
209 #endif /* QT_NO_DEBUG_STREAM */
210 
211 KCHART_DECLARE_SWAP_SPECIALISATION( KChart::RelativePosition )
212 
213 QT_BEGIN_NAMESPACE
214 Q_DECLARE_TYPEINFO( KChart::RelativePosition, Q_MOVABLE_TYPE );
215 QT_END_NAMESPACE
216 
217 Q_DECLARE_METATYPE( KChart::RelativePosition )
218 
219 #endif // KCHARTRELATIVEPOSITION_H
220