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 */