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 #include "KChartRelativePosition.h"
0010 
0011 #include "KChartEnums.h"
0012 #include "KChartMeasure.h"
0013 #include "KChartPosition.h"
0014 #include "KChartAbstractArea.h"
0015 #include "KChartMath_p.h"
0016 
0017 #include <QWidget>
0018 #include <QLayout>
0019 
0020 using namespace KChart;
0021 
0022 class Q_DECL_HIDDEN RelativePosition::Private {
0023     friend class ::KChart::RelativePosition;
0024 public:
0025     Private();
0026     ~Private();
0027 
0028 private:
0029     QObject* area;
0030     PositionPoints points;
0031     Position position;
0032     Qt::Alignment alignment;
0033     Measure horizontalPadding;
0034     Measure verticalPadding;
0035     qreal rotation;
0036 };
0037 
0038 
0039 RelativePosition::Private::Private()
0040     : area( nullptr ),
0041       alignment( Qt::AlignCenter ),
0042       rotation( 0 )
0043 {
0044 
0045 }
0046 
0047 RelativePosition::Private::~Private()
0048 {}
0049 
0050 
0051 
0052 RelativePosition::RelativePosition()
0053     : _d( new Private )
0054 {
0055 
0056 }
0057 
0058 RelativePosition::RelativePosition( const RelativePosition& r )
0059     : _d( new Private( *r._d ) )
0060 {
0061 
0062 }
0063 
0064 RelativePosition & RelativePosition::operator=( const RelativePosition & other ) {
0065     RelativePosition copy( other );
0066     copy.swap( *this );
0067     return *this;
0068 }
0069 
0070 RelativePosition::~RelativePosition()
0071 {
0072     delete _d;
0073 }
0074 
0075 #define d d_func()
0076 
0077 void RelativePosition::setReferenceArea( QObject * area ) {
0078     d->area = area;
0079     if ( area )
0080         setReferencePoints( PositionPoints() );
0081 }
0082 
0083 QObject * RelativePosition::referenceArea() const {
0084     return d->area;
0085 }
0086 
0087 void RelativePosition::setReferencePoints( const PositionPoints& points ) {
0088     d->points = points;
0089     if ( !points.isNull() )
0090         setReferenceArea( nullptr );
0091 }
0092 const PositionPoints RelativePosition::referencePoints() const{
0093     return d->points;
0094 }
0095 
0096 void RelativePosition::setReferencePosition( Position pos ) {
0097     d->position = pos;
0098 }
0099 
0100 void RelativePosition::resetReferencePosition() {
0101     d->position = Position::Unknown;
0102 }
0103 
0104 Position RelativePosition::referencePosition() const {
0105     return d->position;
0106 }
0107 
0108 void RelativePosition::setAlignment( Qt::Alignment align ) {
0109     d->alignment = align;
0110 }
0111 
0112 Qt::Alignment RelativePosition::alignment() const {
0113     return d->alignment;
0114 }
0115 
0116 void RelativePosition::setHorizontalPadding( const Measure & pad ) {
0117     d->horizontalPadding = pad;
0118 }
0119 
0120 Measure RelativePosition::horizontalPadding() const {
0121     return d->horizontalPadding;
0122 }
0123 
0124 void RelativePosition::setVerticalPadding( const Measure & pad ) {
0125     d->verticalPadding = pad;
0126 }
0127 
0128 Measure RelativePosition::verticalPadding() const {
0129     return d->verticalPadding;
0130 }
0131 
0132 void RelativePosition::setRotation( qreal rot ) {
0133     d->rotation = rot;
0134 }
0135 
0136 qreal RelativePosition::rotation() const {
0137     return d->rotation;
0138 }
0139 
0140 
0141 const QPointF RelativePosition::referencePoint( qreal* polarDegrees ) const
0142 {
0143     bool useRect = ( d->area != nullptr );
0144     QRect rect;
0145     if ( useRect ) {
0146         if ( const QWidget* widget = qobject_cast< const QWidget* >( d->area ) ) {
0147             const QLayout* layout = widget->layout();
0148             rect = layout ? layout->geometry() : widget->geometry();
0149         } else if ( const AbstractArea* kdcArea = qobject_cast< const AbstractArea* >( d->area ) ) {
0150             rect = kdcArea->geometry();
0151         } else {
0152             useRect = false;
0153         }
0154     }
0155 
0156     QPointF pt;
0157     qreal angle = 0.0;
0158     if ( useRect ) {
0159         pt = PositionPoints( rect ).point( d->position );
0160     } else {
0161         pt = d->points.point( d->position );
0162         angle = d->points.degrees( d->position.value() );
0163     }
0164 
0165     if ( polarDegrees ) {
0166         *polarDegrees = angle;
0167     }
0168    return pt;
0169 }
0170 
0171 
0172 const QPointF RelativePosition::calculatedPoint( const QSizeF& autoSize ) const
0173 {
0174     const qreal dx = horizontalPadding().calculatedValue( autoSize, KChartEnums::MeasureOrientationHorizontal );
0175     const qreal dy = verticalPadding().calculatedValue( autoSize, KChartEnums::MeasureOrientationVertical );
0176 
0177     qreal polarDegrees;
0178     QPointF pt( referencePoint( &polarDegrees ) );
0179     if ( polarDegrees == 0.0 ) {
0180         pt += QPointF( dx, dy );
0181     } else {
0182         const qreal rad = DEGTORAD( polarDegrees);
0183         const qreal sinDeg = sin(rad);
0184         const qreal cosDeg = cos(rad);
0185         pt.setX( pt.x() + dx * cosDeg + dy * sinDeg );
0186         pt.setY( pt.y() - dx * sinDeg + dy * cosDeg );
0187     }
0188     return pt;
0189 }
0190 
0191 
0192 bool RelativePosition::operator==( const RelativePosition& r ) const
0193 {
0194     return  d->area              == r.referenceArea() &&
0195             d->position          == r.referencePosition() &&
0196             d->alignment         == r.alignment() &&
0197             d->horizontalPadding == r.horizontalPadding() &&
0198             d->verticalPadding   == r.verticalPadding() &&
0199             d->rotation          == r.rotation() ;
0200 }
0201 
0202 #undef d
0203 
0204 
0205 #if !defined(QT_NO_DEBUG_STREAM)
0206 QDebug operator<<(QDebug dbg, const KChart::RelativePosition& rp)
0207 {
0208     dbg << "KChart::RelativePosition("
0209     << "referencearea="<<rp.referenceArea()
0210     << "referenceposition="<<rp.referencePosition()
0211     << "alignment="<<rp.alignment()
0212     << "horizontalpadding="<<rp.horizontalPadding()
0213     << "verticalpadding="<<rp.verticalPadding()
0214     << "rotation="<<rp.rotation()
0215     << ")";
0216     return dbg;
0217 }
0218 #endif /* QT_NO_DEBUG_STREAM */