VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsRotatorButton.cpp@ 103988

Last change on this file since 103988 was 98103, checked in by vboxsync, 21 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1/* $Id: UIGraphicsRotatorButton.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGraphicsRotatorButton class definition.
4 */
5
6/*
7 * Copyright (C) 2012-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QStateMachine>
30#include <QPropertyAnimation>
31#include <QSignalTransition>
32#include <QMouseEventTransition>
33
34/* GUI includes: */
35#include "UIGraphicsRotatorButton.h"
36#include "UIIconPool.h"
37
38
39UIGraphicsRotatorButton::UIGraphicsRotatorButton(QIGraphicsWidget *pParent,
40 const QString &strPropertyName,
41 bool fToggled,
42 bool fReflected /* = false */,
43 int iAnimationDuration /* = 300 */)
44 : UIGraphicsButton(pParent, UIIconPool::iconSet(":/expanding_collapsing_16px.png"))
45 , m_fReflected(fReflected)
46 , m_state(fToggled ? UIGraphicsRotatorButtonState_Rotated : UIGraphicsRotatorButtonState_Default)
47 , m_pAnimationMachine(0)
48 , m_iAnimationDuration(iAnimationDuration)
49 , m_pForwardButtonAnimation(0)
50 , m_pBackwardButtonAnimation(0)
51 , m_pForwardSubordinateAnimation(0)
52 , m_pBackwardSubordinateAnimation(0)
53{
54 /* Configure: */
55 setAutoHandleButtonClick(true);
56
57 /* Create state machine: */
58 m_pAnimationMachine = new QStateMachine(this);
59 /* Create 'default' state: */
60 QState *pStateDefault = new QState(m_pAnimationMachine);
61 pStateDefault->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Default));
62 pStateDefault->assignProperty(this, "rotation", m_fReflected ? 180 : 0);
63 /* Create 'animating' state: */
64 QState *pStateAnimating = new QState(m_pAnimationMachine);
65 pStateAnimating->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Animating));
66 /* Create 'rotated' state: */
67 QState *pStateRotated = new QState(m_pAnimationMachine);
68 pStateRotated->assignProperty(this, "state", QVariant::fromValue(UIGraphicsRotatorButtonState_Rotated));
69 pStateRotated->assignProperty(this, "rotation", 90);
70
71 /* Forward button animation: */
72 m_pForwardButtonAnimation = new QPropertyAnimation(this, "rotation", this);
73 m_pForwardButtonAnimation->setDuration(m_iAnimationDuration);
74 m_pForwardButtonAnimation->setStartValue(m_fReflected ? 180 : 0);
75 m_pForwardButtonAnimation->setEndValue(90);
76 /* Backward button animation: */
77 m_pBackwardButtonAnimation = new QPropertyAnimation(this, "rotation", this);
78 m_pBackwardButtonAnimation->setDuration(m_iAnimationDuration);
79 m_pBackwardButtonAnimation->setStartValue(90);
80 m_pBackwardButtonAnimation->setEndValue(m_fReflected ? 180 : 0);
81
82 /* Forward subordinate animation: */
83 m_pForwardSubordinateAnimation = new QPropertyAnimation(pParent, strPropertyName.toLatin1(), this);
84 m_pForwardSubordinateAnimation->setDuration(m_iAnimationDuration);
85 m_pForwardSubordinateAnimation->setEasingCurve(QEasingCurve::InCubic);
86 /* Backward subordinate animation: */
87 m_pBackwardSubordinateAnimation = new QPropertyAnimation(pParent, strPropertyName.toLatin1(), this);
88 m_pBackwardSubordinateAnimation->setDuration(m_iAnimationDuration);
89 m_pBackwardSubordinateAnimation->setEasingCurve(QEasingCurve::InCubic);
90
91 /* Default => Animating: */
92 QSignalTransition *pDefaultToAnimating = pStateDefault->addTransition(this, SIGNAL(sigToAnimating()), pStateAnimating);
93 pDefaultToAnimating->addAnimation(m_pForwardButtonAnimation);
94 pDefaultToAnimating->addAnimation(m_pForwardSubordinateAnimation);
95 /* Animating => Rotated: */
96 connect(m_pForwardButtonAnimation, SIGNAL(finished()), this, SIGNAL(sigToRotated()), Qt::QueuedConnection);
97 pStateAnimating->addTransition(this, SIGNAL(sigToRotated()), pStateRotated);
98
99 /* Rotated => Animating: */
100 QSignalTransition *pRotatedToAnimating = pStateRotated->addTransition(this, SIGNAL(sigToAnimating()), pStateAnimating);
101 pRotatedToAnimating->addAnimation(m_pBackwardButtonAnimation);
102 pRotatedToAnimating->addAnimation(m_pBackwardSubordinateAnimation);
103 /* Animating => Default: */
104 connect(m_pBackwardButtonAnimation, SIGNAL(finished()), this, SIGNAL(sigToDefault()), Qt::QueuedConnection);
105 pStateAnimating->addTransition(this, SIGNAL(sigToDefault()), pStateDefault);
106
107 /* Default => Rotated: */
108 pStateDefault->addTransition(this, SIGNAL(sigToRotated()), pStateRotated);
109
110 /* Rotated => Default: */
111 pStateRotated->addTransition(this, SIGNAL(sigToDefault()), pStateDefault);
112
113 /* Initial state is 'default': */
114 m_pAnimationMachine->setInitialState(!fToggled ? pStateDefault : pStateRotated);
115 /* Start state-machine: */
116 m_pAnimationMachine->start();
117
118 /* Refresh: */
119 refresh();
120}
121
122void UIGraphicsRotatorButton::setAutoHandleButtonClick(bool fEnabled)
123{
124 /* Disconnect button-click signal: */
125 disconnect(this, &UIGraphicsRotatorButton::sigButtonClicked, this, &UIGraphicsRotatorButton::sltButtonClicked);
126 if (fEnabled)
127 {
128 /* Connect button-click signal: */
129 connect(this, &UIGraphicsRotatorButton::sigButtonClicked, this, &UIGraphicsRotatorButton::sltButtonClicked);
130 }
131}
132
133void UIGraphicsRotatorButton::setToggled(bool fToggled, bool fAnimated /* = true */)
134{
135 /* Not during animation: */
136 if (isAnimationRunning())
137 return;
138
139 /* Make sure something has changed: */
140 switch (state())
141 {
142 case UIGraphicsRotatorButtonState_Default:
143 {
144 if (!fToggled)
145 return;
146 break;
147 }
148 case UIGraphicsRotatorButtonState_Rotated:
149 {
150 if (fToggled)
151 return;
152 break;
153 }
154 default: break;
155 }
156
157 /* Should be animated? */
158 if (fAnimated)
159 {
160 /* Rotation start: */
161 emit sigRotationStart();
162 emit sigToAnimating();
163 }
164 else
165 {
166 if (fToggled)
167 emit sigToRotated();
168 else
169 emit sigToDefault();
170 }
171}
172
173void UIGraphicsRotatorButton::setAnimationRange(int iStart, int iEnd)
174{
175 m_pForwardSubordinateAnimation->setStartValue(iStart);
176 m_pForwardSubordinateAnimation->setEndValue(iEnd);
177 m_pBackwardSubordinateAnimation->setStartValue(iEnd);
178 m_pBackwardSubordinateAnimation->setEndValue(iStart);
179}
180
181bool UIGraphicsRotatorButton::isAnimationRunning() const
182{
183 return m_pForwardSubordinateAnimation->state() == QAbstractAnimation::Running ||
184 m_pBackwardSubordinateAnimation->state() == QAbstractAnimation::Running;
185}
186
187void UIGraphicsRotatorButton::sltButtonClicked()
188{
189 /* Toggle state: */
190 switch (state())
191 {
192 case UIGraphicsRotatorButtonState_Default: setToggled(true); break;
193 case UIGraphicsRotatorButtonState_Rotated: setToggled(false); break;
194 default: break;
195 }
196}
197
198void UIGraphicsRotatorButton::refresh()
199{
200 /* Update rotation center: */
201 QSizeF sh = minimumSizeHint();
202 setTransformOriginPoint(sh.width() / 2, sh.height() / 2);
203 /* Update rotation state: */
204 updateRotationState();
205 /* Call to base-class: */
206 UIGraphicsButton::refresh();
207}
208
209void UIGraphicsRotatorButton::updateRotationState()
210{
211 switch (state())
212 {
213 case UIGraphicsRotatorButtonState_Default: setRotation(m_fReflected ? 180 : 0); break;
214 case UIGraphicsRotatorButtonState_Rotated: setRotation(90); break;
215 default: break;
216 }
217}
218
219UIGraphicsRotatorButtonState UIGraphicsRotatorButton::state() const
220{
221 return m_state;
222}
223
224void UIGraphicsRotatorButton::setState(UIGraphicsRotatorButtonState state)
225{
226 m_state = state;
227 switch (m_state)
228 {
229 case UIGraphicsRotatorButtonState_Default:
230 {
231 emit sigRotationFinish(false);
232 break;
233 }
234 case UIGraphicsRotatorButtonState_Rotated:
235 {
236 emit sigRotationFinish(true);
237 break;
238 }
239 default: break;
240 }
241}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette