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