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