VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIMenuToolBar.cpp

Last change on this file was 98103, checked in by vboxsync, 16 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: 10.1 KB
Line 
1/* $Id: UIMenuToolBar.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIMenuToolBar class implementation.
4 */
5
6/*
7 * Copyright (C) 2017-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 <QHBoxLayout>
31#include <QPainter>
32#include <QPainterPath>
33#include <QPainterPathStroker>
34#include <QStyle>
35#include <QToolButton>
36
37/* GUI includes: */
38#include "UIMenuToolBar.h"
39#include "QIToolBar.h"
40
41/* Other VBox includes: */
42#include "iprt/assert.h"
43
44
45/** QIToolBar extension
46 * holding single drop-down menu of actions. */
47class UIMenuToolBarPrivate : public QIToolBar
48{
49 Q_OBJECT;
50
51public:
52
53 /** Constructs toolbar. */
54 UIMenuToolBarPrivate(QWidget *pParent = 0);
55
56 /** Rebuilds toolbar shape. */
57 void rebuildShape();
58
59 /** Defines toolbar alignment @a enmType. */
60 void setAlignmentType(UIMenuToolBar::AlignmentType enmType);
61
62 /** Defines toolbar menu action. */
63 void setMenuAction(QAction *pAction);
64
65protected:
66
67 /** Handles show @a pEvent. */
68 virtual void showEvent(QShowEvent *pEvent) RT_OVERRIDE;
69
70 /** Handles polish @a pEvent. */
71 virtual void polishEvent(QShowEvent *pEvent);
72
73 /** Handles resize @a pEvent. */
74 virtual void resizeEvent(QResizeEvent *pEvent) RT_OVERRIDE;
75
76 /** Handles paint @a pEvent. */
77 virtual void paintEvent(QPaintEvent *pEvent) RT_OVERRIDE;
78
79private:
80
81 /** Holds whether this widget was polished. */
82 bool m_fPolished;
83
84 /** Holds the left margin instance. */
85 QWidget *m_pMarginLeft;
86 /** Holds the right margin instance. */
87 QWidget *m_pMarginRight;
88
89 /** Holds the menu toolbar alignment type. */
90 UIMenuToolBar::AlignmentType m_enmAlignmentType;
91
92 /** Holds the shape. */
93 QPainterPath m_shape;
94};
95
96
97/*********************************************************************************************************************************
98* Class UIMenuToolBarPrivate implementation. *
99*********************************************************************************************************************************/
100
101UIMenuToolBarPrivate::UIMenuToolBarPrivate(QWidget *pParent /* = 0 */)
102 : QIToolBar(pParent)
103 , m_fPolished(false)
104 , m_pMarginLeft(0)
105 , m_pMarginRight(0)
106 , m_enmAlignmentType(UIMenuToolBar::AlignmentType_TopLeft)
107{
108 /* Rebuild shape: */
109 rebuildShape();
110}
111
112void UIMenuToolBarPrivate::rebuildShape()
113{
114 /* Get the metric: */
115 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
116 const int iRounding = qMax(iIconMetric / 4, 4);
117
118 /* Configure margins: */
119 if (m_pMarginLeft && m_pMarginRight)
120 {
121 const int iStandardMargin = iRounding;
122 int iLeftMargin = iStandardMargin;
123 int iRightMargin = iStandardMargin;
124 if ( m_enmAlignmentType == UIMenuToolBar::AlignmentType_TopLeft
125 || m_enmAlignmentType == UIMenuToolBar::AlignmentType_BottomLeft)
126 iRightMargin += iRounding;
127 if ( m_enmAlignmentType == UIMenuToolBar::AlignmentType_TopRight
128 || m_enmAlignmentType == UIMenuToolBar::AlignmentType_BottomRight)
129 iLeftMargin += iRounding;
130 m_pMarginLeft->setMinimumWidth(iLeftMargin);
131 m_pMarginRight->setMinimumWidth(iRightMargin);
132 }
133
134 /* Rebuild shape: */
135 QPainterPath shape;
136 switch (m_enmAlignmentType)
137 {
138 case UIMenuToolBar::AlignmentType_TopLeft:
139 shape.moveTo(width(), height());
140 shape.lineTo(shape.currentPosition().x(), iRounding * 2);
141 shape.arcTo(QRectF(shape.currentPosition(), QSizeF(iRounding * 4, iRounding * 4))
142 .translated(-iRounding * 4, -iRounding * 2), 0, 90);
143 shape.lineTo(0, shape.currentPosition().y());
144 shape.lineTo(shape.currentPosition().x(), height());
145 shape.closeSubpath();
146 break;
147 case UIMenuToolBar::AlignmentType_TopRight:
148 shape.moveTo(0, height());
149 shape.lineTo(shape.currentPosition().x(), iRounding * 2);
150 shape.arcTo(QRectF(shape.currentPosition(), QSizeF(iRounding * 4, iRounding * 4))
151 .translated(0, -iRounding * 2), 180, -90);
152 shape.lineTo(width(), shape.currentPosition().y());
153 shape.lineTo(shape.currentPosition().x(), height());
154 shape.closeSubpath();
155 break;
156 case UIMenuToolBar::AlignmentType_BottomLeft:
157 shape.moveTo(width(), 0);
158 shape.lineTo(shape.currentPosition().x(), height() - iRounding * 2);
159 shape.arcTo(QRectF(shape.currentPosition(), QSizeF(iRounding * 4, iRounding * 4))
160 .translated(-iRounding * 4, -iRounding * 2), 0, -90);
161 shape.lineTo(0, shape.currentPosition().y());
162 shape.lineTo(shape.currentPosition().x(), 0);
163 shape.closeSubpath();
164 break;
165 case UIMenuToolBar::AlignmentType_BottomRight:
166 shape.moveTo(0, 0);
167 shape.lineTo(shape.currentPosition().x(), height() - iRounding * 2);
168 shape.arcTo(QRectF(shape.currentPosition(), QSizeF(iRounding * 4, iRounding * 4))
169 .translated(0, -iRounding * 2), 180, 90);
170 shape.lineTo(width(), shape.currentPosition().y());
171 shape.lineTo(shape.currentPosition().x(), 0);
172 shape.closeSubpath();
173 break;
174 }
175 m_shape = shape;
176}
177
178void UIMenuToolBarPrivate::setAlignmentType(UIMenuToolBar::AlignmentType enmType)
179{
180 /* Set alignment type: */
181 m_enmAlignmentType = enmType;
182
183 /* Rebuild shape: */
184 rebuildShape();
185}
186
187void UIMenuToolBarPrivate::setMenuAction(QAction *pAction)
188{
189 /* Clear first: */
190 clear();
191 delete m_pMarginLeft;
192 m_pMarginLeft = 0;
193 delete m_pMarginRight;
194 m_pMarginRight = 0;
195
196 /* Create left margin: */
197 m_pMarginLeft = widgetForAction(addWidget(new QWidget));
198
199 /* Add action itself: */
200 addAction(pAction);
201
202 /* Configure the newly added action's button: */
203 QToolButton *pButton = qobject_cast<QToolButton*>(widgetForAction(pAction));
204 AssertPtrReturnVoid(pButton);
205 {
206 /* Configure tool-button: */
207 pButton->setAutoRaise(true);
208 pButton->setPopupMode(QToolButton::InstantPopup);
209 }
210
211 /* Create right margin: */
212 m_pMarginRight = widgetForAction(addWidget(new QWidget));
213
214 /* Rebuild shape: */
215 rebuildShape();
216}
217
218void UIMenuToolBarPrivate::showEvent(QShowEvent *pEvent)
219{
220 /* Call to base-class: */
221 QIToolBar::showEvent(pEvent);
222
223 /* Make sure we should polish dialog: */
224 if (m_fPolished)
225 return;
226
227 /* Call to polish-event: */
228 polishEvent(pEvent);
229
230 /* Mark dialog as polished: */
231 m_fPolished = true;
232}
233
234void UIMenuToolBarPrivate::polishEvent(QShowEvent * /* pEvent */)
235{
236 /* Rebuild shape: */
237 rebuildShape();
238}
239
240void UIMenuToolBarPrivate::resizeEvent(QResizeEvent *pEvent)
241{
242 /* Call to base-class: */
243 QIToolBar::resizeEvent(pEvent);
244
245 /* Rebuild shape: */
246 rebuildShape();
247}
248
249void UIMenuToolBarPrivate::paintEvent(QPaintEvent * /* pEvent */)
250{
251 /* Prepare painter: */
252 QPainter painter(this);
253
254 /* Fill background: */
255 if (!m_shape.isEmpty())
256 {
257 painter.setRenderHint(QPainter::Antialiasing);
258 painter.setClipPath(m_shape);
259 }
260 QRect backgroundRect = rect();
261 QColor backgroundColor = QApplication::palette().color(QPalette::Window);
262 QLinearGradient headerGradient(backgroundRect.bottomLeft(), backgroundRect.topLeft());
263 headerGradient.setColorAt(0, backgroundColor.darker(120));
264 headerGradient.setColorAt(1, backgroundColor.darker(104));
265 painter.fillRect(backgroundRect, headerGradient);
266}
267
268
269/*********************************************************************************************************************************
270* Class UIMenuToolBar implementation. *
271*********************************************************************************************************************************/
272
273UIMenuToolBar::UIMenuToolBar(QWidget *pParent /* = 0 */)
274 : QWidget(pParent)
275{
276 /* Prepare: */
277 prepare();
278}
279
280void UIMenuToolBar::prepare()
281{
282 /* Create layout: */
283 new QHBoxLayout(this);
284 AssertPtrReturnVoid(layout());
285 {
286 /* Configure layout: */
287 layout()->setContentsMargins(0, 0, 0, 0);
288
289 /* Create menu-toolbar: */
290 m_pToolbar = new UIMenuToolBarPrivate;
291 AssertPtrReturnVoid(m_pToolbar);
292 {
293 /* Configure menu-toolbar: */
294 m_pToolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
295
296 /* Add into layout: */
297 layout()->addWidget(m_pToolbar);
298 }
299 }
300}
301
302void UIMenuToolBar::setAlignmentType(AlignmentType enmType)
303{
304 /* Pass to private object: */
305 return m_pToolbar->setAlignmentType(enmType);
306}
307
308void UIMenuToolBar::setIconSize(const QSize &size)
309{
310 /* Pass to private object: */
311 return m_pToolbar->setIconSize(size);
312}
313
314void UIMenuToolBar::setMenuAction(QAction *pAction)
315{
316 /* Pass to private object: */
317 return m_pToolbar->setMenuAction(pAction);
318}
319
320void UIMenuToolBar::setToolButtonStyle(Qt::ToolButtonStyle enmStyle)
321{
322 /* Pass to private object: */
323 return m_pToolbar->setToolButtonStyle(enmStyle);
324}
325
326QWidget *UIMenuToolBar::widgetForAction(QAction *pAction) const
327{
328 /* Pass to private object: */
329 return m_pToolbar->widgetForAction(pAction);
330}
331
332#include "UIMenuToolBar.moc"
333
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use