File indexing completed on 2024-05-12 04:20:36
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KCHARTPOSITION_H 0010 #define KCHARTPOSITION_H 0011 0012 #include <QDebug> 0013 #include <Qt> 0014 #include <QMetaType> 0015 #include <QCoreApplication> 0016 #include "KChartGlobal.h" 0017 #include "KChartEnums.h" 0018 #include <QStringList> 0019 QT_BEGIN_NAMESPACE 0020 0021 class QByteArray; 0022 template <typename T> class QList; 0023 QT_END_NAMESPACE 0024 0025 namespace KChart { 0026 0027 /** 0028 * \class Position KChartPosition.h 0029 * \brief Defines a position, using compass terminology. 0030 * 0031 * Using KChart::Position you can specify one of nine 0032 * pre-defined, logical points (see the \c static \c const getter 0033 * methods below), in a similar way, as you would use a 0034 * compass to navigate on a map. 0035 * 0036 * For each piece (slice/bar, etc.) of a chart for example, you can specify the position of the value 0037 * labels. Figure 1 illustrates which cardinal points refer to which points 0038 * on a pie or bar chart, resp. In the graphic, "N" stands for North, "S" for South, etc. 0039 * 0040 * \image html position-alignments.png "Figure 1: Different interpretations of KChart::Position within KChart" 0041 * 0042 * \note Often you will declare a \c Position together with the 0043 * RelativePosition class, to specify a logical point, 0044 * which then will be used to layout your chart at runtime, 0045 * e.g. for specifying the location of a floating Legend box. 0046 * 0047 * For comparing a Position's value with a switch () statement, 0048 * you can use numeric values defined in KChartEnums, like this: 0049 \verbatim 0050 switch ( yourPosition().value() ) { 0051 case KChartEnums::PositionNorthWest: 0052 // your code ... 0053 break; 0054 case KChartEnums::PositionNorth: 0055 // your code ... 0056 break; 0057 } 0058 \endverbatim 0059 * \sa RelativePosition, KChartEnums::PositionValue 0060 */ 0061 class KCHART_EXPORT Position 0062 { 0063 Q_DECLARE_TR_FUNCTIONS( Position ) 0064 Position( int value ); 0065 public: 0066 Position(); 0067 Position( KChartEnums::PositionValue value ); // intentionally non-explicit 0068 0069 KChartEnums::PositionValue value() const; 0070 0071 const char *name() const; 0072 QString printableName() const; 0073 0074 bool isUnknown() const; 0075 0076 bool isWestSide() const; 0077 bool isNorthSide() const; 0078 bool isEastSide() const; 0079 bool isSouthSide() const; 0080 0081 bool isCorner() const; 0082 bool isPole() const; 0083 0084 bool isFloating() const; 0085 0086 static const Position& Unknown; 0087 static const Position& Center; 0088 static const Position& NorthWest; 0089 static const Position& North; 0090 static const Position& NorthEast; 0091 static const Position& East; 0092 static const Position& SouthEast; 0093 static const Position& South; 0094 static const Position& SouthWest; 0095 static const Position& West; 0096 0097 static const Position& Floating; 0098 0099 // boolean flags: 1, 2, 4, 8, ... 0100 enum Option { 0101 IncludeCenter = 0x1, 0102 IncludeFloating = 0x2 }; 0103 Q_DECLARE_FLAGS( Options, Option ) 0104 0105 // Unfortunately the following typecast from int to Options is needed 0106 // as the | operator is not defined yet, this will be done by 0107 // the macro Q_DECLARE_OPERATORS_FOR_FLAGS( KChart::Position::Options ) 0108 // at the bottom of this file. 0109 static QList<QByteArray> names( Options options = Options(IncludeCenter | IncludeFloating) ); 0110 static QStringList printableNames( Options options = Options(IncludeCenter | IncludeFloating) ); 0111 0112 static Position fromName(const char * name); 0113 static Position fromName(const QByteArray & name); 0114 0115 bool operator==( const Position& ) const; 0116 bool operator==( int ) const; 0117 bool operator!=( const Position& ) const; 0118 bool operator!=( int ) const; 0119 0120 private: 0121 int m_value; 0122 }; // End of class Position 0123 0124 inline bool Position::operator!=( const Position & other ) const { return !operator==( other ); } 0125 inline bool Position::operator!=( int other ) const { return !operator==( other ); } 0126 0127 /** 0128 * @brief Stores the absolute target points of a Position 0129 * \internal 0130 */ 0131 class KCHART_EXPORT PositionPoints 0132 { 0133 public: 0134 PositionPoints() {} // all points get initialized with the default automatically 0135 0136 PositionPoints( 0137 QPointF center, 0138 QPointF northWest, 0139 QPointF north, 0140 QPointF northEast, 0141 QPointF east, 0142 QPointF southEast, 0143 QPointF south, 0144 QPointF southWest, 0145 QPointF west ) 0146 : mPositionCenter( center ) 0147 , mPositionNorthWest( northWest ) 0148 , mPositionNorth( north ) 0149 , mPositionNorthEast( northEast ) 0150 , mPositionEast( east ) 0151 , mPositionSouthEast( southEast ) 0152 , mPositionSouth( south ) 0153 , mPositionSouthWest( southWest ) 0154 , mPositionWest( west ) 0155 {} 0156 PositionPoints( 0157 const QPointF& onePointForAllPositions ) 0158 : mPositionCenter( onePointForAllPositions ) 0159 , mPositionNorthWest( onePointForAllPositions ) 0160 , mPositionNorth( onePointForAllPositions ) 0161 , mPositionNorthEast( onePointForAllPositions ) 0162 , mPositionEast( onePointForAllPositions ) 0163 , mPositionSouthEast( onePointForAllPositions ) 0164 , mPositionSouth( onePointForAllPositions ) 0165 , mPositionSouthWest( onePointForAllPositions ) 0166 , mPositionWest( onePointForAllPositions ) 0167 {} 0168 PositionPoints( 0169 const QRectF& rect ) 0170 { 0171 const QRectF r( rect.normalized() ); 0172 mPositionCenter = r.center(); 0173 mPositionNorthWest = r.topLeft(); 0174 mPositionNorth = QPointF(r.center().x(), r.top()); 0175 mPositionNorthEast = r.topRight(); 0176 mPositionEast = QPointF(r.right(), r.center().y()); 0177 mPositionSouthEast = r.bottomRight(); 0178 mPositionSouth = QPointF(r.center().x(), r.bottom()); 0179 mPositionSouthWest = r.bottomLeft(); 0180 mPositionWest = QPointF(r.left(), r.center().y()); 0181 } 0182 PositionPoints( 0183 QPointF northWest, 0184 QPointF northEast, 0185 QPointF southEast, 0186 QPointF southWest ) 0187 : mPositionCenter( (northWest + southEast) / 2.0 ) 0188 , mPositionNorthWest( northWest ) 0189 , mPositionNorth( (northWest + northEast) / 2.0 ) 0190 , mPositionNorthEast( northEast ) 0191 , mPositionEast( (northEast + southEast) / 2.0 ) 0192 , mPositionSouthEast( southEast ) 0193 , mPositionSouth( (southWest + southEast) / 2.0 ) 0194 , mPositionSouthWest( southWest ) 0195 , mPositionWest( (northWest + southWest) / 2.0 ) 0196 {} 0197 0198 void setDegrees( KChartEnums::PositionValue pos, qreal degrees ) 0199 { 0200 mapOfDegrees[pos] = degrees; 0201 } 0202 0203 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) 0204 const qreal degrees( KChartEnums::PositionValue pos ) const 0205 #else 0206 qreal degrees( KChartEnums::PositionValue pos ) const 0207 #endif 0208 { 0209 if ( mapOfDegrees.contains(pos) ) 0210 return mapOfDegrees[pos]; 0211 return 0.0; 0212 } 0213 0214 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE) 0215 const QPointF point( Position position ) const 0216 #else 0217 QPointF point( Position position ) const 0218 #endif 0219 { 0220 //qDebug() << "point( " << position.name() << " )"; 0221 if ( position == Position::Center) 0222 return mPositionCenter; 0223 if ( position == Position::NorthWest) 0224 return mPositionNorthWest; 0225 if ( position == Position::North) 0226 return mPositionNorth; 0227 if ( position == Position::NorthEast) 0228 return mPositionNorthEast; 0229 if ( position == Position::East) 0230 return mPositionEast; 0231 if ( position == Position::SouthEast) 0232 return mPositionSouthEast; 0233 if ( position == Position::South) 0234 return mPositionSouth; 0235 if ( position == Position::SouthWest) 0236 return mPositionSouthWest; 0237 if ( position == Position::West) 0238 return mPositionWest; 0239 return mPositionUnknown; 0240 } 0241 0242 bool isNull() const 0243 { 0244 return 0245 mPositionUnknown.isNull() && 0246 mPositionCenter.isNull() && 0247 mPositionNorthWest.isNull() && 0248 mPositionNorth.isNull() && 0249 mPositionNorthEast.isNull() && 0250 mPositionEast.isNull() && 0251 mPositionSouthEast.isNull() && 0252 mPositionSouth.isNull() && 0253 mPositionSouthWest.isNull() && 0254 mPositionWest.isNull(); 0255 } 0256 0257 QPointF mPositionUnknown; 0258 QPointF mPositionCenter; 0259 QPointF mPositionNorthWest; 0260 QPointF mPositionNorth; 0261 QPointF mPositionNorthEast; 0262 QPointF mPositionEast; 0263 QPointF mPositionSouthEast; 0264 QPointF mPositionSouth; 0265 QPointF mPositionSouthWest; 0266 QPointF mPositionWest; 0267 QMap<KChartEnums::PositionValue, qreal> mapOfDegrees; 0268 0269 }; // End of class PositionPoints 0270 0271 0272 } 0273 0274 0275 #if !defined(QT_NO_DEBUG_STREAM) 0276 KCHART_EXPORT QDebug operator<<(QDebug, const KChart::Position& ); 0277 #endif /* QT_NO_DEBUG_STREAM */ 0278 0279 QT_BEGIN_NAMESPACE 0280 Q_DECLARE_TYPEINFO( KChart::Position, Q_MOVABLE_TYPE ); 0281 Q_DECLARE_OPERATORS_FOR_FLAGS( KChart::Position::Options ) 0282 QT_END_NAMESPACE 0283 0284 Q_DECLARE_METATYPE( KChart::Position ) 0285 0286 #endif // KCHARTPOSITION_H