File indexing completed on 2024-09-29 05:04:10
0001 /*************************************************************************** 0002 * Copyright (C) 2003-2005 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #ifndef CANVASITEMPARTS_H 0012 #define CANVASITEMPARTS_H 0013 0014 //#include <canvas.h> // 2018.10.16 - not needed 0015 #include "canvasitems.h" 0016 #include <QIcon> 0017 #include <QPointer> 0018 #include <QSlider> 0019 #include <QToolButton> 0020 0021 class Cells; 0022 class CIWidgetMgr; 0023 class CNItem; 0024 class SliderWidget; 0025 class ToolButton; 0026 class QString; 0027 0028 class GuiPart : /* public QObject, */ public KtlQCanvasRectangle 0029 { 0030 Q_OBJECT 0031 public: 0032 /** 0033 * Create a GuiPart. Control the position using setGuiPartSize, instead 0034 * of calling KtlQCanvasRectangle::setSize. This allows GuiPart to know 0035 * when its size has been changed 0036 */ 0037 GuiPart(CNItem *parent, const QRect &r, KtlQCanvas *canvas); 0038 ~GuiPart() override; 0039 0040 virtual QRect recommendedRect() const 0041 { 0042 return m_originalRect; 0043 } 0044 void setOriginalRect(const QRect &r) 0045 { 0046 m_originalRect = r; 0047 } 0048 0049 virtual void updateConnectorPoints(bool add); 0050 0051 /** 0052 * Set the angle that the GuiPart draws itself (if the GuiPart chooses 0053 * to use it by calling initPainter and deinitPainter from drawShape). 0054 * Note that this doesn't affect the rectangle position that the 0055 * GuiPart is in. The rotation is taken to be about the center of the 0056 * rectangle. 0057 */ 0058 void setAngleDegrees(int angleDegrees); 0059 /** 0060 * Control the size. Call this instead of KtlQCanvasRectangle::setSize. In 0061 * turn, this function will notify subclasses via posChanged(); 0062 */ 0063 void setGuiPartSize(int width, int height); 0064 /** 0065 * Returns the rectangle to draw in to compensate for rotation of 0066 * the QPainter 0067 */ 0068 QRect drawRect(); 0069 0070 int angleDegrees() const 0071 { 0072 return m_angleDegrees; 0073 } 0074 CNItem *parent() const 0075 { 0076 return p_parent; 0077 } 0078 0079 protected: 0080 /** 0081 * Called when the size or angle changes 0082 */ 0083 virtual void posChanged() 0084 { 0085 ; 0086 } 0087 /** 0088 * Rotate / etc the painter. You must call deinitPainter after 0089 * calling this function. 0090 */ 0091 void initPainter(QPainter &p); 0092 /** 0093 * Complement function to initPainter - restores painter to normal 0094 * transform 0095 */ 0096 void deinitPainter(QPainter &p); 0097 int m_angleDegrees; 0098 CNItem *p_parent; 0099 bool b_pointsAdded; 0100 QRect m_originalRect; 0101 0102 private slots: 0103 void slotMoveBy(double dx, double dy); 0104 }; 0105 0106 /** 0107 @short Stores internal information about text associated with CNItem 0108 @author David Saxton 0109 */ 0110 class Text : public GuiPart 0111 { 0112 Q_OBJECT 0113 public: 0114 Text(const QString &text, CNItem *parent, const QRect &r, KtlQCanvas *canvas, int flags = Qt::AlignHCenter | Qt::AlignVCenter); 0115 ~Text() override; 0116 0117 /** 0118 * Set the text, returning true if the size of this Text on the canvas 0119 * has changed. 0120 */ 0121 bool setText(const QString &text); 0122 QRect recommendedRect() const override; 0123 void drawShape(QPainter &p) override; 0124 /** 0125 * The text flags (see QPainter::drawText) - Qt::AlignmentFlags and 0126 * Qt::TextFlags OR'd together. 0127 */ 0128 int flags() const 0129 { 0130 return m_flags; 0131 } 0132 /** 0133 * @see flags 0134 */ 0135 void setFlags(int flags); 0136 0137 protected: 0138 QString m_text; 0139 int m_flags; 0140 }; 0141 typedef QMap<QString, QPointer<Text>> TextMap; 0142 0143 /** 0144 @short Base class for embedding Qt Widgets into the canvas 0145 @author David Saxton 0146 */ 0147 class Widget : public GuiPart 0148 { 0149 public: 0150 Widget(const QString &id, CNItem *parent, const QRect &r, KtlQCanvas *canvas); 0151 ~Widget() override; 0152 0153 virtual QWidget *widget() const = 0; 0154 QString id() const 0155 { 0156 return m_id; 0157 } 0158 0159 /** 0160 * Set the widget enabled/disabled 0161 */ 0162 void setEnabled(bool enabled); 0163 0164 virtual void enterEvent(QEvent *) {}; 0165 virtual void leaveEvent(QEvent *) {}; 0166 0167 /** 0168 * Mouse was pressed. pos is given relative to CNItem position. 0169 */ 0170 virtual void mousePressEvent(QMouseEvent *e) 0171 { 0172 Q_UNUSED(e); 0173 } 0174 /** 0175 * Mouse was released. pos is given relative to CNItem position. 0176 */ 0177 virtual void mouseReleaseEvent(QMouseEvent *e) 0178 { 0179 Q_UNUSED(e); 0180 } 0181 /** 0182 * Mouse was double clicked. pos is given relative to CNItem position. 0183 */ 0184 virtual void mouseDoubleClickEvent(QMouseEvent *e) 0185 { 0186 Q_UNUSED(e); 0187 } 0188 /** 0189 * Mouse was moved. pos is given relative to CNItem position. 0190 */ 0191 virtual void mouseMoveEvent(QMouseEvent *e) 0192 { 0193 Q_UNUSED(e); 0194 } 0195 /** 0196 * Mouse was scrolled. pos is given relative to CNItem position. 0197 */ 0198 virtual void wheelEvent(QWheelEvent *e) 0199 { 0200 Q_UNUSED(e); 0201 } 0202 0203 void drawShape(QPainter &p) override; 0204 0205 protected: 0206 void posChanged() override; 0207 QString m_id; 0208 }; 0209 0210 class ToolButton : public QToolButton 0211 { 0212 public: 0213 ToolButton(QWidget *parent); 0214 0215 void mousePressEvent(QMouseEvent *e) override 0216 { 0217 QToolButton::mousePressEvent(e); 0218 } 0219 void mouseReleaseEvent(QMouseEvent *e) override 0220 { 0221 QToolButton::mouseReleaseEvent(e); 0222 } 0223 void mouseDoubleClickEvent(QMouseEvent *e) override 0224 { 0225 QToolButton::mouseDoubleClickEvent(e); 0226 } 0227 void mouseMoveEvent(QMouseEvent *e) override 0228 { 0229 QToolButton::mouseMoveEvent(e); 0230 } 0231 void wheelEvent(QWheelEvent *e) override 0232 { 0233 QToolButton::wheelEvent(e); 0234 } 0235 void enterEvent(QEvent *) override 0236 { 0237 QToolButton::enterEvent(nullptr); 0238 } 0239 void leaveEvent(QEvent *) override 0240 { 0241 QToolButton::leaveEvent(nullptr); 0242 } 0243 0244 // Not overriding because it complains about it being wrong for some 0245 // reason, so just wrap the function. 0246 void initStyleOpt(QStyleOptionToolButton *option) const 0247 { 0248 QToolButton::initStyleOption(option); 0249 } 0250 0251 void setAngleDegrees(int angleDegrees) 0252 { 0253 m_angleDegrees = angleDegrees; 0254 } 0255 0256 protected: 0257 virtual void drawButtonLabel(QPainter *p); 0258 0259 int m_angleDegrees; 0260 QFont m_font; 0261 }; 0262 0263 /** 0264 @short Stores internal information about button associated with CNItem 0265 @author David Saxton 0266 */ 0267 class Button : public Widget 0268 { 0269 Q_OBJECT 0270 public: 0271 Button(const QString &id, CNItem *parent, bool isToggle, const QRect &r, KtlQCanvas *canvas); 0272 ~Button() override; 0273 0274 void mousePressEvent(QMouseEvent *e) override; 0275 void mouseReleaseEvent(QMouseEvent *e) override; 0276 void enterEvent(QEvent *) override; 0277 void leaveEvent(QEvent *) override; 0278 0279 /** 0280 * Set the text displayed inside the button 0281 */ 0282 void setText(const QString &text); 0283 void setToggle(bool toggle); 0284 bool isToggle() const 0285 { 0286 return b_isToggle; 0287 } 0288 QWidget *widget() const override; 0289 bool state() const; 0290 void setIcon(const QIcon &); 0291 void setState(bool state); 0292 QRect recommendedRect() const override; 0293 0294 void drawShape(QPainter &p) override; 0295 0296 protected: 0297 void posChanged() override; 0298 0299 private slots: 0300 void slotStateChanged(); 0301 0302 private: 0303 bool b_isToggle; // i.e. whether it should be depressed when the mouse is released 0304 ToolButton *m_button; 0305 }; 0306 0307 class SliderWidget : public QSlider 0308 { 0309 public: 0310 SliderWidget(QWidget *parent); 0311 0312 void mousePressEvent(QMouseEvent *e) override 0313 { 0314 QSlider::mousePressEvent(e); 0315 } 0316 void mouseReleaseEvent(QMouseEvent *e) override 0317 { 0318 QSlider::mouseReleaseEvent(e); 0319 } 0320 void mouseDoubleClickEvent(QMouseEvent *e) override 0321 { 0322 QSlider::mouseDoubleClickEvent(e); 0323 } 0324 void mouseMoveEvent(QMouseEvent *e) override 0325 { 0326 QSlider::mouseMoveEvent(e); 0327 } 0328 void wheelEvent(QWheelEvent *e) override 0329 { 0330 QSlider::wheelEvent(e); 0331 } 0332 void enterEvent(QEvent *) override 0333 { 0334 QSlider::enterEvent(nullptr); 0335 } 0336 void leaveEvent(QEvent *) override 0337 { 0338 QSlider::leaveEvent(nullptr); 0339 } 0340 0341 // Not overriding because it complains about it being wrong for some 0342 // reason, so just wrap the function. 0343 void initStyleOpt(QStyleOptionSlider *option) const 0344 { 0345 QSlider::initStyleOption(option); 0346 } 0347 }; 0348 0349 /** 0350 @short Stores internal information about a QSlider associated with CNItem 0351 @author David Saxton 0352 */ 0353 class Slider : public Widget 0354 { 0355 Q_OBJECT 0356 public: 0357 Slider(const QString &id, CNItem *parent, const QRect &r, KtlQCanvas *canvas); 0358 ~Slider() override; 0359 0360 void mousePressEvent(QMouseEvent *e) override; 0361 void mouseReleaseEvent(QMouseEvent *e) override; 0362 void mouseDoubleClickEvent(QMouseEvent *e) override; 0363 void mouseMoveEvent(QMouseEvent *e) override; 0364 void wheelEvent(QWheelEvent *e) override; 0365 void enterEvent(QEvent *) override; 0366 void leaveEvent(QEvent *) override; 0367 0368 QWidget *widget() const override; 0369 int value() const; 0370 void setValue(int value); 0371 void setOrientation(Qt::Orientation o); 0372 0373 void drawShape(QPainter &p) override; 0374 0375 protected: 0376 void posChanged() override; 0377 0378 private slots: 0379 void slotValueChanged(int value); 0380 0381 private: 0382 bool m_bSliderInverted; ///< In some orientations, the slider is reflected 0383 SliderWidget *m_slider; 0384 Qt::Orientation m_orientation; 0385 }; 0386 0387 #endif