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