1 /*
2  * Stellarium
3  * Copyright (C) 2008 Fabien Chereau
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
18  */
19 
20 #ifndef STELGUIITEMS_HPP
21 #define STELGUIITEMS_HPP
22 
23 #include <QGraphicsPixmapItem>
24 #include <QGraphicsWidget>
25 #include <QDebug>
26 #include <QMap>
27 
28 class QGraphicsSceneMouseEvent;
29 class QTimeLine;
30 class QGraphicsTextItem;
31 class QTimer;
32 class StelProgressController;
33 class QProgressBar;
34 
35 // Progess bars in the lower right corner
36 class StelProgressBarMgr : public QGraphicsWidget
37 {
38 	Q_OBJECT
39 public:
40 	StelProgressBarMgr(QGraphicsItem* parent);
41 
42 public slots:
43 	void addProgressBar(const StelProgressController *p);
44 	void removeProgressBar(const StelProgressController *p);
45 	void oneBarChanged();
46 private:
47 	QMap<const StelProgressController*, QProgressBar*> allBars;
48 };
49 
50 // Buttons in the bottom left corner
51 class CornerButtons : public QObject, public QGraphicsItem
52 {
53 	Q_OBJECT
54 	Q_INTERFACES(QGraphicsItem)
55 public:
56 	CornerButtons(QGraphicsItem* parent=Q_NULLPTR);
57 	virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE;
58 	virtual QRectF boundingRect() const Q_DECL_OVERRIDE;
59 	void setOpacity(double opacity);
60 private:
61 	mutable double lastOpacity;
62 };
63 
64 //! A Button Graphicsitem for use in Stellarium's graphic widgets
65 class StelButton : public QObject, public QGraphicsPixmapItem
66 {
67 	friend class BottomStelBar;
68 	friend class LeftStelBar;
69 	Q_OBJECT
70 public:
71 	//! Constructor
72 	//! @param parent the parent item
73 	//! @param pixOn the pixmap to display when the button is toggled
74 	//! @param pixOff the pixmap to display when the button is not toggled
75 	//! @param pixHover a pixmap slowly blended when mouse is over the button
76 	//! @param action the associated action. Connections are automatically done with the signals if relevant.
77 	//! @param noBackground define whether the button background image have to be used
78 	StelButton(QGraphicsItem* parent, const QPixmap& pixOn, const QPixmap& pixOff,
79 		   const QPixmap& pixHover=QPixmap(),
80 		   class StelAction* action=Q_NULLPTR,
81 		   bool noBackground=false,
82 		   StelAction *otherAction=Q_NULLPTR);
83 
84 	//! Constructor
85 	//! @param parent the parent item
86 	//! @param pixOn the pixmap to display when the button is toggled
87 	//! @param pixOff the pixmap to display when the button is not toggled
88 	//! @param pixHover a pixmap slowly blended when mouse is over the button
89 	//! @param actionId the id of the associated action. Connections are automatically done with the signals if relevant.
90 	//! @param noBackground define whether the button background image have to be used
91 	StelButton(QGraphicsItem* parent, const QPixmap& pixOn, const QPixmap& pixOff,
92 		   const QPixmap& pixHover,
93 		   const QString& actionId,
94 		   bool noBackground=false,
95 		   const QString& otherActionId="");
96 	//! Constructor
97 	//! @param parent the parent item
98 	//! @param pixOn the pixmap to display when the button is toggled
99 	//! @param pixOff the pixmap to display when the button is not toggled
100 	//! @param pixNoChange the pixmap to display when the button state of a tristate is not changed
101 	//! @param pixHover a pixmap slowly blended when mouse is over the button
102 	//! @param actionId the associated action. Connections are automatically done with the signals if relevant.
103 	//! @param noBackground define whether the button background image have to be used
104 	//! @param isTristate define whether the button is a tristate or an on/off button
105 	StelButton(QGraphicsItem* parent, const QPixmap& pixOn, const QPixmap& pixOff, const QPixmap& pixNoChange,
106 		   const QPixmap& pixHover,
107 		   const QString& actionId=QString(),
108 		   bool noBackground=false,
109 		   bool isTristate=true);
110 
111 	//! Button states
112 	enum {ButtonStateOff = 0, ButtonStateOn = 1, ButtonStateNoChange = 2};
113 
114 	//! Get whether the button is checked
isChecked() const115 	int isChecked() const {return checked;}
116 
117 	//! Get the width of the button image.
118 	//! The width is based on pixOn.
getButtonPixmapWidth() const119 	int getButtonPixmapWidth() const {return pixOn.width();}
120 
121 	//! Set the button opacity
setOpacity(double v)122 	void setOpacity(double v) {opacity=v; updateIcon();}
123 
124 	//! Set the background pixmap of the button.
125 	void setBackgroundPixmap(const QPixmap& newBackground);
126 
127 	//! While configuring buttons, call this with true when after key release
128 	//! focus should go back to the sky (typical for bottom buttons;
129 	//! left buttons call panels which receive focus after button press, so those should be configured with b=false)
setFocusOnSky(bool b)130 	void setFocusOnSky(bool b) { flagChangeFocus=b; }
131 
132 	//! Configure the button to trigger its action when the mouse click
133 	//! is released (by default buttons trigger on press event).
setTriggerOnRelease(bool b)134 	void setTriggerOnRelease(bool b) { triggerOnRelease = b;}
135 
136 signals:
137 	//! Triggered when the button state changes
138 	void toggled(bool);
139 	//! Triggered when the button state changes
140 	void triggered();
141 	void triggeredRight();
142 	//! Emitted when the hover state change
143 	//! @param b true if the mouse entered the button
144 	void hoverChanged(bool b);
145 
146 public slots:
147 	//! set whether the button is checked
148 	void setChecked(int b);
setChecked(bool b)149 	void setChecked(bool b) { setChecked(static_cast<int>(b)); }
150 
151 protected:
152 	virtual void hoverEnterEvent(QGraphicsSceneHoverEvent* event) Q_DECL_OVERRIDE;
153 	virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) Q_DECL_OVERRIDE;
154 	virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE;
155 	virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) Q_DECL_OVERRIDE;
156 private slots:
157 	void animValueChanged(qreal value);
158 	void updateIcon();
159 private:
160 	void initCtor(const QPixmap& apixOn,
161                   const QPixmap& apixOff,
162                   const QPixmap& apixNoChange,
163                   const QPixmap& apixHover,
164 		  StelAction* anAction,
165 		  StelAction* otherAction,
166 		  bool noBackground,
167 		  bool isTristate);
168 	int toggleChecked(int);
169 
170 	QPixmap pixOn;
171 	QPixmap pixOff;
172 	QPixmap pixNoChange;
173 	QPixmap pixHover;
174 	QPixmap pixBackground;
175 
176 	int checked;
177 	bool flagChangeFocus;
178 
179 	QTimeLine* timeLine;
180 	class StelAction* action;          // linked action for button press
181 	class StelAction* secondAction;    // linked action for rightclick (or Ctrl-Click?)
182 	bool noBckground;
183 	bool isTristate_;
184 	double opacity;
185 	double hoverOpacity;
186 	bool triggerOnRelease = false;
187 };
188 
189 // The button bar on the left containing windows toggle buttons
190 class LeftStelBar : public QObject, public QGraphicsItem
191 {
192 	Q_OBJECT
193 	Q_INTERFACES(QGraphicsItem)
194 public:
195 	LeftStelBar(QGraphicsItem* parent);
196 	~LeftStelBar() Q_DECL_OVERRIDE;
197 	virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE;
198 	virtual QRectF boundingRect() const Q_DECL_OVERRIDE;
199 	void addButton(StelButton* button);
200 	QRectF boundingRectNoHelpLabel() const;
201 	//! Set the color for all the sub elements
202 	void setColor(const QColor& c);
203 private slots:
204 	//! Update the help label when a button is hovered
205 	void buttonHoverChanged(bool b);
206 private:
207 	QTimeLine* hideTimeLine;
208 	QGraphicsSimpleTextItem* helpLabel;
209 	QGraphicsPixmapItem* helpLabelPixmap; // bad-graphics replacement.
210 };
211 
212 // The button bar on the bottom containing actions toggle buttons
213 class BottomStelBar : public QObject, public QGraphicsItem
214 {
215 	Q_OBJECT
216 	Q_INTERFACES(QGraphicsItem)
217 public:
218 	BottomStelBar(QGraphicsItem* parent, const QPixmap& pixLeft=QPixmap(), const QPixmap& pixRight=QPixmap(), const QPixmap& pixMiddle=QPixmap(), const QPixmap& pixSingle=QPixmap());
219 	virtual ~BottomStelBar() Q_DECL_OVERRIDE;
220 	virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE;
221 	virtual QRectF boundingRect() const Q_DECL_OVERRIDE;
222 	QRectF boundingRectNoHelpLabel() const;
223 
224 	//! Add a button in a group in the button bar. Group are displayed in alphabetic order.
225 	//! @param button the button to add
226 	//! @param groupName the name of the button group to which the button belongs to. If the group doesn't exist yet, a new one is created.
227 	//! @param beforeActionName insert the button before the button associated to the given action. If the action doesn't exist, insert it at the end of the group.
228 	void addButton(StelButton* button, const QString& groupName="defaultGroup", const QString& beforeActionName="");
229 	//! Hide the button associated with the action of the passed name
230 	StelButton* hideButton(const QString& actionName);
231 
232 	//! Set the margin at the left and right of a button group in pixels
233 	void setGroupMargin(const QString& groupName, int left, int right);
234 
235 	//! Set the background of a group
236 	void setGroupBackground(const QString& groupName, const QPixmap& pixLeft=QPixmap(),
237 							const QPixmap& pixRight=QPixmap(), const QPixmap& pixMiddle=QPixmap(),
238 							const QPixmap& pixSingle=QPixmap());
239 
240 	//! Set the color for all the sub elements
241 	void setColor(const QColor& c);
242 
243 	//! Set whether time must be displayed in the bottom bar
setFlagShowTime(bool b)244 	void setFlagShowTime(bool b) {flagShowTime=b;}
getFlagShowTime() const245 	bool getFlagShowTime() const { return flagShowTime; }
246 	//! Set whether location info must be displayed in the bottom bar
setFlagShowLocation(bool b)247 	void setFlagShowLocation(bool b) {flagShowLocation=b;}
getFlagShowLocation() const248 	bool getFlagShowLocation() const { return flagShowLocation; }
249 	//! Set whether FPS info must be displayed in the bottom bar
setFlagShowFps(bool b)250 	void setFlagShowFps(bool b) {flagShowFps=b;}
getFlagShowFps() const251 	bool getFlagShowFps() const { return flagShowFps; }
252 	//! Set whether FOV info must be displayed in the bottom bar
setFlagShowFov(bool b)253 	void setFlagShowFov(bool b) {flagShowFov=b;}
getFlagShowFov() const254 	bool getFlagShowFov() const { return flagShowFov; }
255 	//! Set whether DMS format for FOV info must be displayed in the bottom bar
setFlagFovDms(bool b)256 	void setFlagFovDms(bool b) {flagFovDms=b;}
getFlagFovDms() const257 	bool getFlagFovDms() const { return flagFovDms; }
258 	//! Set whether JD for time info must be displayed in the bottom bar
setFlagTimeJd(bool b)259 	void setFlagTimeJd(bool b) {flagTimeJd=b;}
getFlagTimeJd() const260 	bool getFlagTimeJd() const { return flagTimeJd; }
261 
setFlagShowTz(bool b)262 	void setFlagShowTz(bool b) { flagShowTZ=b; }
getFlagShowTz() const263 	bool getFlagShowTz() const { return flagShowTZ; }
264 
265 signals:
266 	void sizeChanged();
267 
268 private slots:
269 	//! Update the help label when a button is hovered
270 	void buttonHoverChanged(bool b);
271 
272 	//! connect from StelApp to resize fonts on the fly.
273 	void setFontSizeFromApp(int size);
274 	//! connect from StelApp to set font on the fly.
275 	void setFont(QFont font);
276 
277 private:
278 	void updateText(bool forceUpdatePos=false);
279 	void updateButtonsGroups();
280 	QRectF getButtonsBoundingRect() const;
281 	// Elements which get displayed above the buttons:
282 	QGraphicsSimpleTextItem* location;
283 	QGraphicsSimpleTextItem* datetime;
284 	QGraphicsSimpleTextItem* fov;
285 	QGraphicsSimpleTextItem* fps;
286 	// For bad graphics, show these instead. We can use location etc for font info.
287 	// We use ad-hoc pixmaps instead if command-line arg. -t (--text-fix) is given.
288 	QGraphicsPixmapItem* locationPixmap;
289 	QGraphicsPixmapItem* datetimePixmap;
290 	QGraphicsPixmapItem* fovPixmap;
291 	QGraphicsPixmapItem* fpsPixmap;
292 
293 
294 
295 	struct ButtonGroup
296 	{
ButtonGroupBottomStelBar::ButtonGroup297 		ButtonGroup() : leftMargin(0), rightMargin(0),
298 						pixBackgroundLeft(Q_NULLPTR), pixBackgroundRight(Q_NULLPTR),
299 						pixBackgroundMiddle(Q_NULLPTR), pixBackgroundSingle(Q_NULLPTR) {;}
300 		//! Elements of the group
301 		QList<StelButton*> elems;
302 		//! Left margin size in pixel
303 		int leftMargin;
304 		//! Right margin size in pixel
305 		int rightMargin;
306 		//! Background Images;
307 		QPixmap* pixBackgroundLeft;
308 		QPixmap* pixBackgroundRight;
309 		QPixmap* pixBackgroundMiddle;
310 		QPixmap* pixBackgroundSingle;
311 	};
312 
313 	QMap<QString, ButtonGroup> buttonGroups;
314 	QPixmap pixBackgroundLeft;
315 	QPixmap pixBackgroundRight;
316 	QPixmap pixBackgroundMiddle;
317 	QPixmap pixBackgroundSingle;
318 
319 	bool flagShowTime;
320 	bool flagShowLocation;
321 	bool flagShowFps;
322 	bool flagShowFov;
323 	bool flagFovDms;
324 	bool flagTimeJd;
325 	bool flagShowTZ;
326 
327 	QGraphicsSimpleTextItem* helpLabel;
328 	QGraphicsPixmapItem* helpLabelPixmap; // bad-graphics replacement.
329 };
330 
331 // The path around the bottom left button bars
332 class StelBarsPath : public QGraphicsPathItem
333 {
334 	public:
335 		StelBarsPath(QGraphicsItem* parent);
336 		void updatePath(BottomStelBar* bot, LeftStelBar* lef);
337 		//! return radius of corner arc
getRoundSize() const338 		double getRoundSize() const {return roundSize;}
339 		void setBackgroundOpacity(double opacity);
340 	private:
341 		double roundSize; // radius of corner arc
342 };
343 
344 #endif // STELGUIITEMS_HPP
345