File indexing completed on 2024-05-12 15:54:17

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 KCHARTLAYOUTITEMS_H
0021 #define KCHARTLAYOUTITEMS_H
0022 
0023 #include <QBrush>
0024 #include <QFont>
0025 #include <QFontMetricsF>
0026 #include <QLayout>
0027 #include <QLayoutItem>
0028 #include <QPen>
0029 
0030 #include "KChartTextAttributes.h"
0031 #include "KChartMarkerAttributes.h"
0032 
0033 QT_BEGIN_NAMESPACE
0034 class QPainter;
0035 class KTextDocument;
0036 QT_END_NAMESPACE
0037 
0038 // TODO remove
0039 QRectF rotatedRect( const QRectF& pt, qreal rotation );
0040 
0041 namespace KChart {
0042     class AbstractDiagram;
0043     class PaintContext;
0044 
0045     /**
0046      * Base class for all layout items of KChart
0047      * \internal
0048      */
0049     class KCHART_EXPORT AbstractLayoutItem : public QLayoutItem
0050     {
0051     public:
0052         AbstractLayoutItem( Qt::Alignment itemAlignment = Qt::Alignment() ) :
0053             QLayoutItem( itemAlignment ),
0054             mParent( nullptr ),
0055             mParentLayout( nullptr ) {}
0056 
0057         /**
0058          * Default impl: just call paint.
0059          *
0060          * Derived classes like KChart::AbstractArea are providing
0061          * additional action here.
0062          */
0063         virtual void paintAll( QPainter& painter );
0064 
0065         virtual void paint( QPainter* ) = 0;
0066 
0067 
0068         /**
0069           * Default impl: Paint the complete item using its layouted position and size.
0070           */
0071         virtual void paintCtx( PaintContext* context );
0072 
0073         /**
0074             Inform the item about its widget: This enables the item,
0075             to trigger that widget's update, whenever the size of the item's
0076             contents has changed.
0077 
0078             Thus, you need to call setParentWidget on every item, that
0079             has a non-fixed size.
0080           */
0081         virtual void setParentWidget( QWidget* widget );
0082 
0083         /**
0084             Report changed size hint: ask the parent widget to recalculate the layout.
0085           */
0086         virtual void sizeHintChanged() const;
0087 
0088         void setParentLayout( QLayout* lay )
0089         {
0090             mParentLayout = lay;
0091         }
0092         QLayout* parentLayout()
0093         {
0094             return mParentLayout;
0095         }
0096         void removeFromParentLayout()
0097         {
0098             if ( mParentLayout ) {
0099                 if ( widget() )
0100                     mParentLayout->removeWidget( widget() );
0101                 else
0102                     mParentLayout->removeItem( this );
0103             }
0104         }
0105     protected:
0106         QWidget* mParent;
0107         QLayout* mParentLayout;
0108     };
0109 
0110     /**
0111      * Layout item showing a text
0112      *\internal
0113      */
0114     class KCHART_EXPORT TextLayoutItem : public AbstractLayoutItem
0115     {
0116     public:
0117         TextLayoutItem();
0118         TextLayoutItem( const QString& text,
0119                         const TextAttributes& attributes,
0120                         const QObject* autoReferenceArea,
0121                         KChartEnums::MeasureOrientation autoReferenceOrientation,
0122                         Qt::Alignment alignment = Qt::Alignment() );
0123 
0124         void setAutoReferenceArea( const QObject* area );
0125         const QObject* autoReferenceArea() const;
0126 
0127         void setText(const QString & text);
0128         QString text() const;
0129 
0130         void setTextAlignment( Qt::Alignment );
0131         Qt::Alignment textAlignment() const;
0132 
0133         /**
0134           \brief Use this to specify the text attributes to be used for this item.
0135 
0136           \sa textAttributes
0137         */
0138         void setTextAttributes( const TextAttributes& a );
0139 
0140         /**
0141           Returns the text attributes to be used for this item.
0142 
0143           \sa setTextAttributes
0144         */
0145         TextAttributes textAttributes() const;
0146 
0147         /** pure virtual in QLayoutItem */
0148         bool isEmpty() const override;
0149         /** pure virtual in QLayoutItem */
0150         Qt::Orientations expandingDirections() const override;
0151         /** pure virtual in QLayoutItem */
0152         QSize maximumSize() const override;
0153         /** pure virtual in QLayoutItem */
0154         QSize minimumSize() const override;
0155         /** pure virtual in QLayoutItem */
0156         QSize sizeHint() const override;
0157         /** pure virtual in QLayoutItem */
0158         void setGeometry( const QRect& r ) override;
0159         /** pure virtual in QLayoutItem */
0160         QRect geometry() const override;
0161 
0162         virtual int marginWidth() const;
0163 
0164         virtual QSize sizeHintUnrotated() const;
0165 
0166         virtual bool intersects( const TextLayoutItem& other, const QPointF& myPos, const QPointF& otherPos ) const;
0167         virtual bool intersects( const TextLayoutItem& other, const QPoint& myPos, const QPoint& otherPos ) const;
0168 
0169         virtual qreal realFontSize() const;
0170         virtual QFont realFont() const;
0171 
0172         void paint( QPainter* ) override;
0173 
0174         QPolygon boundingPolygon() const;
0175     private:
0176         bool maybeUpdateRealFont() const;
0177         QSize unrotatedSizeHint( const QFont& fnt = QFont() ) const;
0178         QSize unrotatedTextSize( QFont fnt = QFont() ) const;
0179         QSize calcSizeHint( const QFont& font ) const;
0180         int marginWidth( const QSize& textSize ) const;
0181 
0182         qreal fitFontSizeToGeometry() const;
0183 
0184         QRect mRect;
0185         QString mText;
0186         Qt::Alignment mTextAlignment;
0187         TextAttributes mAttributes;
0188         const QObject* mAutoReferenceArea;
0189         KChartEnums::MeasureOrientation mAutoReferenceOrientation;
0190         mutable QSize cachedSizeHint;
0191         mutable QPolygon mCachedBoundingPolygon;
0192         mutable qreal cachedFontSize;
0193         mutable QFont cachedFont;
0194     };
0195 
0196     class KCHART_EXPORT TextBubbleLayoutItem : public AbstractLayoutItem
0197     {
0198     public:
0199         TextBubbleLayoutItem();
0200         TextBubbleLayoutItem( const QString& text,
0201                               const TextAttributes& attributes,
0202                               const QObject* autoReferenceArea,
0203                               KChartEnums::MeasureOrientation autoReferenceOrientation,
0204                               Qt::Alignment alignment = Qt::Alignment() );
0205 
0206         ~TextBubbleLayoutItem();
0207 
0208         void setAutoReferenceArea( const QObject* area );
0209         const QObject* autoReferenceArea() const;
0210 
0211         void setText(const QString & text);
0212         QString text() const;
0213 
0214         void setTextAttributes( const TextAttributes& a );
0215         TextAttributes textAttributes() const;
0216 
0217         /** pure virtual in QLayoutItem */
0218         bool isEmpty() const override;
0219         /** pure virtual in QLayoutItem */
0220         Qt::Orientations expandingDirections() const override;
0221         /** pure virtual in QLayoutItem */
0222         QSize maximumSize() const override;
0223         /** pure virtual in QLayoutItem */
0224         QSize minimumSize() const override;
0225         /** pure virtual in QLayoutItem */
0226         QSize sizeHint() const override;
0227         /** pure virtual in QLayoutItem */
0228         void setGeometry( const QRect& r ) override;
0229         /** pure virtual in QLayoutItem */
0230         QRect geometry() const override;
0231 
0232         void paint( QPainter* painter ) override;
0233 
0234     protected:
0235         int borderWidth() const;
0236 
0237     private:
0238         TextLayoutItem* const m_text;
0239     };
0240 
0241     /**
0242      * Layout item showing a data point marker
0243      * \internal
0244      */
0245     class KCHART_EXPORT MarkerLayoutItem : public AbstractLayoutItem
0246     {
0247         public:
0248             MarkerLayoutItem( AbstractDiagram* diagram,
0249                               const MarkerAttributes& marker,
0250                               const QBrush& brush,
0251                               const QPen& pen,
0252                               Qt::Alignment alignment = Qt::Alignment() );
0253 
0254             Qt::Orientations expandingDirections() const override;
0255             QRect geometry() const override;
0256             bool isEmpty() const override;
0257             QSize maximumSize() const override;
0258             QSize minimumSize() const override;
0259             void setGeometry( const QRect& r ) override;
0260             QSize sizeHint() const override;
0261 
0262             void paint( QPainter* ) override;
0263 
0264             static void paintIntoRect(
0265                     QPainter* painter,
0266                     const QRect& rect,
0267                     AbstractDiagram* diagram,
0268                     const MarkerAttributes& marker,
0269                     const QBrush& brush,
0270                     const QPen& pen );
0271 
0272         private:
0273             AbstractDiagram* mDiagram;
0274             QRect mRect;
0275             MarkerAttributes mMarker;
0276             QBrush mBrush;
0277             QPen mPen;
0278     };
0279 
0280     /**
0281      * Layout item showing a coloured line
0282      * \internal
0283      */
0284     class KCHART_EXPORT LineLayoutItem : public AbstractLayoutItem
0285     {
0286         public:
0287             LineLayoutItem( AbstractDiagram* diagram,
0288                             int length,
0289                             const QPen& pen,
0290                             Qt::Alignment mLegendLineSymbolAlignment,
0291                             Qt::Alignment alignment = Qt::Alignment() );
0292 
0293             Qt::Orientations expandingDirections() const override;
0294             QRect geometry() const override;
0295             bool isEmpty() const override;
0296             QSize maximumSize() const override;
0297             QSize minimumSize() const override;
0298             void setGeometry( const QRect& r ) override;
0299             QSize sizeHint() const override;
0300 
0301             void setLegendLineSymbolAlignment(Qt::Alignment legendLineSymbolAlignment);
0302             virtual Qt::Alignment legendLineSymbolAlignment() const;
0303 
0304             void paint( QPainter* ) override;
0305 
0306             static void paintIntoRect(
0307                     QPainter* painter,
0308                     const QRect& rect,
0309                     const QPen& pen,
0310                     Qt::Alignment lineAlignment);
0311 
0312         private:
0313             AbstractDiagram* mDiagram;  //TODO: not used. remove it
0314             int mLength;
0315             QPen mPen;
0316             QRect mRect;
0317             Qt::Alignment mLegendLineSymbolAlignment;
0318     };
0319 
0320     /**
0321      * Layout item showing a coloured line and a data point marker
0322      * \internal
0323      */
0324     class KCHART_EXPORT LineWithMarkerLayoutItem : public AbstractLayoutItem
0325     {
0326         public:
0327             LineWithMarkerLayoutItem( AbstractDiagram* diagram,
0328                                       int lineLength,
0329                                       const QPen& linePen,
0330                                       int markerOffs,
0331                                       const MarkerAttributes& marker,
0332                                       const QBrush& markerBrush,
0333                                       const QPen& markerPen,
0334                                       Qt::Alignment alignment = Qt::Alignment() );
0335 
0336             Qt::Orientations expandingDirections() const override;
0337             QRect geometry() const override;
0338             bool isEmpty() const override;
0339             QSize maximumSize() const override;
0340             QSize minimumSize() const override;
0341             void setGeometry( const QRect& r ) override;
0342             QSize sizeHint() const override;
0343 
0344             void paint( QPainter* ) override;
0345 
0346         private:
0347             AbstractDiagram* mDiagram;
0348             QRect mRect;
0349             int mLineLength;
0350             QPen mLinePen;
0351             int mMarkerOffs;
0352             MarkerAttributes mMarker;
0353             QBrush mMarkerBrush;
0354             QPen mMarkerPen;
0355     };
0356 
0357 
0358     /**
0359      * Layout item showing a horizontal line
0360      * \internal
0361      */
0362     class KCHART_EXPORT HorizontalLineLayoutItem : public AbstractLayoutItem
0363     {
0364     public:
0365         HorizontalLineLayoutItem();
0366 
0367         Qt::Orientations expandingDirections() const override;
0368         QRect geometry() const override;
0369         bool isEmpty() const override;
0370         QSize maximumSize() const override;
0371         QSize minimumSize() const override;
0372         void setGeometry( const QRect& r ) override;
0373         QSize sizeHint() const override;
0374 
0375         void paint( QPainter* ) override;
0376 
0377     private:
0378         QRect mRect;
0379     };
0380 
0381     /**
0382      * Layout item showing a vertial line
0383      * \internal
0384      */
0385     class KCHART_EXPORT VerticalLineLayoutItem : public AbstractLayoutItem
0386     {
0387         public:
0388             VerticalLineLayoutItem();
0389 
0390             Qt::Orientations expandingDirections() const override;
0391             QRect geometry() const override;
0392             bool isEmpty() const override;
0393             QSize maximumSize() const override;
0394             QSize minimumSize() const override;
0395             void setGeometry( const QRect& r ) override;
0396             QSize sizeHint() const override;
0397 
0398             void paint( QPainter* ) override;
0399 
0400         private:
0401             QRect mRect;
0402     };
0403 
0404     /**
0405      * @brief An empty layout item
0406      * \internal
0407      *
0408      * The AutoSpacerLayoutItem is automatically put into each corner cell of
0409      * the planeLayout grid: one of its reference-layouts is a QVBoxLayout (for
0410      * the top, or bottom axes resp.), the other one is a QHBoxLayout (for the
0411      * left/right sided axes).
0412      *
0413      * The spacer reserves enough space so all of the AbstractAreas contained
0414      * in the two reference-layouts can display not only their in-bounds
0415      * content but also their overlapping content reaching out of their area.
0416      *
0417      * KChart's layouting is applying this schema:
0418 \verbatim
0419     +------------------+-------------------------+-----------------+
0420     | +--------------+ | +---------------------+ | +-------------+ |
0421     | |              | | |  QVBoxLayout for    | | |             | |
0422     | |     AUTO     | | |  the top axis/axes  | | |    AUTO     | |
0423     | |    SPACER    | | +---------------------+ | |   SPACER    | |
0424     | |     ITEM     | | |                     | | |    ITEM     | |
0425     | |              | | |                     | | |             | |
0426     | +--------------+ | +---------------------+ | +-------------+ |
0427     +------------------+-------------------------+-----------------+
0428     | +--------+-----+ | +---------------------+ | +-------+-----+ |
0429     | |        |     | | |                     | | |       |     | |
0430     | |        |     | | |                     | | |       |     | |
0431     | | QHBox- |     | | |                     | | | Right |     | |
0432     | | Layout |     | | |                     | | |       |     | |
0433     | |        |     | | |                     | | | axes  |     | |
0434     | | for    |     | | |                     | | |       |     | |
0435     | |        |     | | |                     | | | layout|     | |
0436     | | the    |     | | |      DIAGRAM(s)     | | |       |     | |
0437     | |        |     | | |                     | | |       |     | |
0438     | | left   |     | | |                     | | |       |     | |
0439     | |        |     | | |                     | | |       |     | |
0440     | | axis   |     | | |                     | | |       |     | |
0441     | | or     |     | | |                     | | |       |     | |
0442     | | axes   |     | | |                     | | |       |     | |
0443     | |        |     | | |                     | | |       |     | |
0444     | +--------+-----+ | +---------------------+ | +-------+-----+ |
0445     +------------------+-------------------------+-----------------+
0446     | +--------------+ | +---------------------+ | +-------------+ |
0447     | |              | | |   QVBoxLayout for   | | |             | |
0448     | |    AUTO      | | |   the bottom axes   | | |    AUTO     | |
0449     | |   SPACER     | | +---------------------+ | |   SPACER    | |
0450     | |    ITEM      | | |                     | | |    ITEM     | |
0451     | |              | | |                     | | |             | |
0452     | +--------------+ | +---------------------+ | +-------------+ |
0453     +------------------+-------------------------+-----------------+
0454 \endverbatim
0455      *
0456      * A typical use case is an Abscissa axis with long labels:
0457 \verbatim
0458     2 -|
0459        |
0460     1 -|
0461        |
0462     0 -+------------------------------------
0463        |        |        |        |        |
0464     Monday  Tuesday  Wednesday Thursday Friday
0465 \endverbatim
0466      * The last letters of the word "Friday" would have been
0467      * cut off in previous versions of KChart - that is
0468      * if you did not call KChart::Chart::setGlobalLeading().
0469      *
0470      * Now the word will be shown completely because there
0471      * is an auto-spacer-item taking care for the additional
0472      * space needed in the lower/right corner.
0473      */
0474     class KCHART_EXPORT AutoSpacerLayoutItem : public AbstractLayoutItem
0475     {
0476         public:
0477             AutoSpacerLayoutItem(
0478                     bool layoutIsAtTopPosition, QHBoxLayout *rightLeftLayout,
0479                     bool layoutIsAtLeftPosition,  QVBoxLayout *topBottomLayout );
0480 
0481             Qt::Orientations expandingDirections() const override;
0482             QRect geometry() const override;
0483             bool isEmpty() const override;
0484             QSize maximumSize() const override;
0485             QSize minimumSize() const override;
0486             void setGeometry( const QRect& r ) override;
0487             QSize sizeHint() const override;
0488 
0489             void paint( QPainter* ) override;
0490 
0491         private:
0492             QRect mRect;
0493             bool mLayoutIsAtTopPosition;
0494             QHBoxLayout *mRightLeftLayout;
0495             bool mLayoutIsAtLeftPosition;
0496             QVBoxLayout *mTopBottomLayout;
0497 
0498             mutable QBrush mCommonBrush;
0499             mutable QSize mCachedSize;
0500     };
0501 
0502 }
0503 
0504 #endif /* KCHARTLAYOUTITEMS_H */