VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.cpp@ 100347

Last change on this file since 100347 was 98103, checked in by vboxsync, 2 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1/* $Id: UIGraphicsButton.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIGraphicsButton class implementation.
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 <QApplication>
30#include <QGraphicsScene>
31#include <QGraphicsSceneMouseEvent>
32#include <QGraphicsView>
33#include <QPainter>
34#include <QStyle>
35#include <QTimerEvent>
36
37/* GUI includes: */
38#include "UIGraphicsButton.h"
39
40
41UIGraphicsButton::UIGraphicsButton(QIGraphicsWidget *pParent, const QIcon &icon)
42 : QIGraphicsWidget(pParent)
43 , m_icon(icon)
44 , m_enmClickPolicy(ClickPolicy_OnRelease)
45 , m_iDelayId(0)
46 , m_iRepeatId(0)
47 , m_dIconScaleIndex(0)
48{
49 refresh();
50}
51
52void UIGraphicsButton::setIconScaleIndex(double dIndex)
53{
54 if (dIndex >= 0)
55 m_dIconScaleIndex = dIndex;
56}
57
58double UIGraphicsButton::iconScaleIndex() const
59{
60 return m_dIconScaleIndex;
61}
62
63void UIGraphicsButton::setClickPolicy(ClickPolicy enmPolicy)
64{
65 m_enmClickPolicy = enmPolicy;
66}
67
68UIGraphicsButton::ClickPolicy UIGraphicsButton::clickPolicy() const
69{
70 return m_enmClickPolicy;
71}
72
73QVariant UIGraphicsButton::data(int iKey) const
74{
75 switch (iKey)
76 {
77 case GraphicsButton_Margin:
78 return 0;
79 case GraphicsButton_IconSize:
80 {
81 int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
82 if (m_dIconScaleIndex > 0)
83 iMetric *= m_dIconScaleIndex;
84 return QSize(iMetric, iMetric);
85 }
86 case GraphicsButton_Icon:
87 return m_icon;
88 default:
89 break;
90 }
91 return QVariant();
92}
93
94QSizeF UIGraphicsButton::sizeHint(Qt::SizeHint enmType, const QSizeF &constraint /* = QSizeF() */) const
95{
96 /* For minimum size-hint: */
97 if (enmType == Qt::MinimumSize)
98 {
99 /* Prepare variables: */
100 const int iMargin = data(GraphicsButton_Margin).toInt();
101 const QSize iconSize = data(GraphicsButton_IconSize).toSize();
102 /* Perform calculations: */
103 int iWidth = 2 * iMargin + iconSize.width();
104 int iHeight = 2 * iMargin + iconSize.height();
105 return QSize(iWidth, iHeight);
106 }
107
108 /* Call to base-class: */
109 return QIGraphicsWidget::sizeHint(enmType, constraint);
110}
111
112void UIGraphicsButton::paint(QPainter *pPainter, const QStyleOptionGraphicsItem* /* pOption */, QWidget* /* pWidget = 0 */)
113{
114 /* Prepare variables: */
115 const int iMargin = data(GraphicsButton_Margin).toInt();
116 const QIcon icon = data(GraphicsButton_Icon).value<QIcon>();
117 const QSize expectedIconSize = data(GraphicsButton_IconSize).toSize();
118
119 /* Determine which QWindow this QGraphicsWidget belongs to.
120 * This is required for proper HiDPI-aware pixmap calculations. */
121 QWindow *pWindow = 0;
122 if ( scene()
123 && !scene()->views().isEmpty()
124 && scene()->views().first()
125 && scene()->views().first()->window())
126 pWindow = scene()->views().first()->window()->windowHandle();
127
128 /* Acquire pixmap, adjust it to be in center of button if necessary: */
129 const QPixmap pixmap = icon.pixmap(pWindow, expectedIconSize);
130 const QSize actualIconSize = pixmap.size() / pixmap.devicePixelRatio();
131 QPoint position = QPoint(iMargin, iMargin);
132 if (actualIconSize != expectedIconSize)
133 {
134 const int iDx = (expectedIconSize.width() - actualIconSize.width()) / 2;
135 const int iDy = (expectedIconSize.height() - actualIconSize.height()) / 2;
136 position += QPoint(iDx, iDy);
137 }
138
139 /* Draw the pixmap finally: */
140 pPainter->drawPixmap(position, pixmap);
141}
142
143void UIGraphicsButton::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
144{
145 /* Call to base-class: */
146 QIGraphicsWidget::mousePressEvent(pEvent);
147
148 /* Accepting this event allows to get release-event: */
149 pEvent->accept();
150
151 /* For click-on-press policy: */
152 if (m_enmClickPolicy == ClickPolicy_OnPress)
153 {
154 /* Notify listeners about button click: */
155 emit sigButtonClicked();
156 /* Start delay timer: */
157 m_iDelayId = startTimer(500);
158 }
159}
160
161void UIGraphicsButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *pEvent)
162{
163 /* Call to base-class: */
164 QIGraphicsWidget::mouseReleaseEvent(pEvent);
165
166 /* Depending on click policy: */
167 switch (m_enmClickPolicy)
168 {
169 /* For click-on-release policy: */
170 case ClickPolicy_OnRelease:
171 {
172 /* Notify listeners about button click: */
173 emit sigButtonClicked();
174 break;
175 }
176 /* For click-on-press policy: */
177 case ClickPolicy_OnPress:
178 {
179 /* We should stop all timers: */
180 killTimer(m_iDelayId);
181 killTimer(m_iRepeatId);
182 m_iDelayId = 0;
183 m_iRepeatId = 0;
184 break;
185 }
186 }
187}
188
189void UIGraphicsButton::timerEvent(QTimerEvent *pEvent)
190{
191 /* For click-on-press policy: */
192 if (m_enmClickPolicy == ClickPolicy_OnPress)
193 {
194 /* We should auto-repeat button click: */
195 emit sigButtonClicked();
196
197 /* For delay timer: */
198 if (pEvent->timerId() == m_iDelayId)
199 {
200 /* We should stop it and start repeat timer: */
201 killTimer(m_iDelayId);
202 m_iDelayId = 0;
203 m_iRepeatId = startTimer(90);
204 }
205 }
206}
207
208void UIGraphicsButton::refresh()
209{
210 /* Refresh geometry: */
211 updateGeometry();
212 /* Resize to minimum size-hint: */
213 resize(minimumSizeHint());
214}
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