1 /***************************************************************************
2  *   Copyright (C) 2003-2005 by David Saxton                               *
3  *   david@bluehaze.org                                                    *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  ***************************************************************************/
10 
11 #ifndef CANVASITEMPARTS_H
12 #define CANVASITEMPARTS_H
13 
14 //#include <canvas.h> // 2018.10.16 - not needed
15 #include "canvasitems.h"
16 #include <QPointer>
17 #include <QSlider>
18 #include <QToolButton>
19 #include <QIcon>
20 
21 class Cells;
22 class CIWidgetMgr;
23 class CNItem;
24 class SliderWidget;
25 class ToolButton;
26 class QString;
27 
28 class GuiPart : /* public QObject, */ public KtlQCanvasRectangle
29 {
30 	Q_OBJECT
31 	public:
32 		/**
33 		 * Create a GuiPart. Control the position using setGuiPartSize, instead
34 		 * of calling KtlQCanvasRectangle::setSize. This allows GuiPart to know
35 		 * when its size has been changed
36 		 */
37 		GuiPart( CNItem *parent, const QRect & r, KtlQCanvas * canvas );
38 		~GuiPart() override;
39 
recommendedRect()40 		virtual QRect recommendedRect() const { return m_originalRect; }
setOriginalRect(const QRect & r)41 		void setOriginalRect( const QRect & r ) { m_originalRect = r; }
42 
43 		virtual void updateConnectorPoints( bool add );
44 
45 		/**
46 		 * Set the angle that the GuiPart draws itself (if the GuiPart chooses
47 		 * to use it by calling initPainter and deinitPainter from drawShape).
48 		 * Note that this doesn't affect the rectangle position that the
49 		 * GuiPart is in. The rotation is taken to be about the center of the
50 		 * rectangle.
51 		 */
52 		void setAngleDegrees( int angleDegrees );
53 		/**
54 		 * Control the size. Call this instead of KtlQCanvasRectangle::setSize. In
55 		 * turn, this function will notify subclasses via posChanged();
56 		 */
57 		void setGuiPartSize( int width, int height );
58 		/**
59 		 * Returns the rectangle to draw in to compensate for rotation of
60 		 * the QPainter
61 		 */
62 		QRect drawRect();
63 
angleDegrees()64 		int angleDegrees() const { return m_angleDegrees; }
parent()65 		CNItem *parent() const { return p_parent; }
66 
67 	protected:
68 		/**
69 		 * Called when the size or angle changes
70 		 */
posChanged()71 		virtual void posChanged() {;}
72 		/**
73 		 * Rotate / etc the painter. You must call deinitPainter after
74 		 * calling this function.
75 		 */
76 		void initPainter( QPainter & p );
77 		/**
78 		 * Complement function to initPainter - restores painter to normal
79 		 * transform
80 		 */
81 		void deinitPainter( QPainter & p );
82 		int m_angleDegrees;
83 		CNItem *p_parent;
84 		bool b_pointsAdded;
85 		QRect m_originalRect;
86 
87 	private slots:
88 		void slotMoveBy( double dx, double dy );
89 };
90 
91 
92 /**
93 @short Stores internal information about text associated with CNItem
94 @author David Saxton
95 */
96 class Text : public GuiPart
97 {
98 	Q_OBJECT
99 	public:
100 		Text( const QString &text, CNItem *parent, const QRect & r, KtlQCanvas * canvas, int flags = Qt::AlignHCenter | Qt::AlignVCenter );
101 		~Text() override;
102 
103 		/**
104 		 * Set the text, returning true if the size of this Text on the canvas
105 		 * has changed.
106 		 */
107 		bool setText( const QString & text );
108 		QRect recommendedRect() const override;
109 		void drawShape ( QPainter & p ) override;
110 		/**
111 		 * The text flags (see QPainter::drawText) - Qt::AlignmentFlags and
112 		 * Qt::TextFlags OR'd together.
113 		 */
flags()114 		int flags() const { return m_flags; }
115 		/**
116 		 * @see flags
117 		 */
118 		void setFlags( int flags );
119 
120 	protected:
121 		QString m_text;
122 		int m_flags;
123 };
124 typedef QMap<QString, QPointer<Text> > TextMap;
125 
126 
127 /**
128 @short Base class for embedding Qt Widgets into the canvas
129 @author David Saxton
130 */
131 class Widget : public GuiPart
132 {
133 	public:
134 		Widget( const QString & id, CNItem *parent, const QRect & r, KtlQCanvas * canvas );
135 		~Widget() override;
136 
137 
138 		virtual QWidget *widget() const = 0;
id()139 		QString id() const { return m_id; }
140 
141 		/**
142 		 * Set the widget enabled/disabled
143 		 */
144 		void setEnabled( bool enabled );
145 
enterEvent(QEvent *)146 		virtual void enterEvent(QEvent *) {};
leaveEvent(QEvent *)147 		virtual void leaveEvent(QEvent *) {};
148 
149 		/**
150 		 * Mouse was pressed. pos is given relative to CNItem position.
151 		 */
mousePressEvent(QMouseEvent * e)152 		virtual void mousePressEvent( QMouseEvent *e ) { Q_UNUSED(e); }
153 		/**
154 		 * Mouse was released. pos is given relative to CNItem position.
155 		 */
mouseReleaseEvent(QMouseEvent * e)156 		virtual void mouseReleaseEvent( QMouseEvent *e ) { Q_UNUSED(e); }
157 		/**
158 		 * Mouse was double clicked. pos is given relative to CNItem position.
159 		 */
mouseDoubleClickEvent(QMouseEvent * e)160 		virtual void mouseDoubleClickEvent( QMouseEvent *e ) { Q_UNUSED(e); }
161 		/**
162 		 * Mouse was moved. pos is given relative to CNItem position.
163 		 */
mouseMoveEvent(QMouseEvent * e)164 		virtual void mouseMoveEvent( QMouseEvent *e ) { Q_UNUSED(e); }
165 		/**
166 		 * Mouse was scrolled. pos is given relative to CNItem position.
167 		 */
wheelEvent(QWheelEvent * e)168 		virtual void wheelEvent( QWheelEvent *e ) { Q_UNUSED(e); }
169 
170 		void drawShape( QPainter &p ) override;
171 
172 	protected:
173 		void posChanged() override;
174 		QString m_id;
175 };
176 
177 
178 class ToolButton : public QToolButton
179 {
180 	public:
181 		ToolButton( QWidget* parent );
182 
mousePressEvent(QMouseEvent * e)183 		void mousePressEvent( QMouseEvent *e ) override { QToolButton::mousePressEvent(e); }
mouseReleaseEvent(QMouseEvent * e)184 		void mouseReleaseEvent( QMouseEvent *e ) override { QToolButton::mouseReleaseEvent(e); }
mouseDoubleClickEvent(QMouseEvent * e)185 		void mouseDoubleClickEvent ( QMouseEvent *e ) override { QToolButton::mouseDoubleClickEvent(e); }
mouseMoveEvent(QMouseEvent * e)186 		void mouseMoveEvent( QMouseEvent *e ) override { QToolButton::mouseMoveEvent(e); }
wheelEvent(QWheelEvent * e)187 		void wheelEvent( QWheelEvent *e ) override { QToolButton::wheelEvent(e); }
enterEvent(QEvent *)188 		void enterEvent(QEvent *) override { QToolButton::enterEvent(nullptr); }
leaveEvent(QEvent *)189 		void leaveEvent(QEvent *) override { QToolButton::leaveEvent(nullptr); }
190 
setAngleDegrees(int angleDegrees)191 		void setAngleDegrees( int angleDegrees ) { m_angleDegrees = angleDegrees; }
192 
193 	protected:
194 		virtual void drawButtonLabel( QPainter * p );
195 
196 		int m_angleDegrees;
197 		QFont m_font;
198 };
199 
200 
201 /**
202 @short Stores internal information about button associated with CNItem
203 @author David Saxton
204 */
205 class Button : public Widget
206 {
207 	Q_OBJECT
208 	public:
209 		Button( const QString & id, CNItem *parent, bool isToggle, const QRect &r, KtlQCanvas *canvas );
210 		~Button() override;
211 
212 		void mousePressEvent( QMouseEvent *e ) override;
213 		void mouseReleaseEvent( QMouseEvent *e ) override;
214 		void enterEvent(QEvent *) override;
215 		void leaveEvent(QEvent *) override;
216 
217 		/**
218 		 * Set the text displayed inside the button
219 		 */
220 		void setText( const QString &text );
221 		void setToggle( bool toggle );
isToggle()222 		bool isToggle() const { return b_isToggle; }
223 		QWidget *widget() const override;
224 		bool state() const;
225 		void setIcon( const QIcon & );
226 		void setState( bool state );
227 		QRect recommendedRect() const override;
228 
229 	protected:
230 		void posChanged() override;
231 
232 	private slots:
233 		void slotStateChanged();
234 
235 	private:
236 		bool b_isToggle; // i.e. whether it should be depressed when the mouse is released
237 		ToolButton *m_button;
238 };
239 
240 
241 class SliderWidget : public QSlider
242 {
243 	public:
244 		SliderWidget( QWidget* parent );
245 
mousePressEvent(QMouseEvent * e)246 		void mousePressEvent( QMouseEvent *e ) override { QSlider::mousePressEvent(e); }
mouseReleaseEvent(QMouseEvent * e)247 		void mouseReleaseEvent( QMouseEvent *e ) override { QSlider::mouseReleaseEvent(e); }
mouseDoubleClickEvent(QMouseEvent * e)248 		void mouseDoubleClickEvent ( QMouseEvent *e ) override { QSlider::mouseDoubleClickEvent(e); }
mouseMoveEvent(QMouseEvent * e)249 		void mouseMoveEvent( QMouseEvent *e ) override { QSlider::mouseMoveEvent(e); }
wheelEvent(QWheelEvent * e)250 		void wheelEvent( QWheelEvent *e ) override { QSlider::wheelEvent(e); }
enterEvent(QEvent *)251 		void enterEvent(QEvent *) override { QSlider::enterEvent(nullptr); }
leaveEvent(QEvent *)252 		void leaveEvent(QEvent *) override { QSlider::leaveEvent(nullptr); }
253 };
254 
255 
256 /**
257 @short Stores internal information about a QSlider associated with CNItem
258 @author David Saxton
259 */
260 class Slider : public Widget
261 {
262 	Q_OBJECT
263 	public:
264 		Slider( const QString & id, CNItem *parent, const QRect & r, KtlQCanvas * canvas );
265 		~Slider() override;
266 
267 		void mousePressEvent( QMouseEvent *e ) override;
268 		void mouseReleaseEvent( QMouseEvent *e ) override;
269 		void mouseDoubleClickEvent ( QMouseEvent *e ) override;
270 		void mouseMoveEvent( QMouseEvent *e ) override;
271 		void wheelEvent( QWheelEvent *e ) override;
272 		void enterEvent(QEvent *) override;
273 		void leaveEvent(QEvent *) override;
274 
275 		QWidget *widget() const override;
276 		int value() const;
277 		void setValue( int value );
278 		void setOrientation( Qt::Orientation o );
279 
280 	protected:
281 		void posChanged() override;
282 
283 	private slots:
284 		void slotValueChanged( int value );
285 
286 	private:
287 		bool m_bSliderInverted; ///< In some orientations, the slider is reflected
288 		SliderWidget *m_slider;
289 		Qt::Orientation m_orientation;
290 };
291 
292 #endif
293 
294