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