VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIToolBar.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: 8.6 KB
Line 
1/* $Id: QIToolBar.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - QIToolBar class implementation.
4 */
5
6/*
7 * Copyright (C) 2006-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 <QLayout>
30#include <QMainWindow>
31#include <QResizeEvent>
32#ifdef VBOX_WS_MAC
33# include <QApplication>
34# include <QPainter>
35# include <QPainterPath>
36#endif
37
38/* GUI includes: */
39#include "QIToolBar.h"
40#ifdef VBOX_WS_MAC
41# include "VBoxUtils.h"
42#endif
43
44
45QIToolBar::QIToolBar(QWidget *pParent /* = 0 */)
46 : QToolBar(pParent)
47 , m_pMainWindow(qobject_cast<QMainWindow*>(pParent))
48#ifdef VBOX_WS_MAC
49 , m_fEmulateUnifiedToolbar(false)
50 , m_iOverallContentsWidth(0)
51 , m_iBrandingWidth(0)
52#endif
53{
54 prepare();
55}
56
57void QIToolBar::setUseTextLabels(bool fEnable)
58{
59 /* Determine tool-button style on the basis of passed flag: */
60 Qt::ToolButtonStyle tbs = fEnable ? Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly;
61
62 /* Depending on parent, assign this style: */
63 if (m_pMainWindow)
64 m_pMainWindow->setToolButtonStyle(tbs);
65 else
66 setToolButtonStyle(tbs);
67}
68
69bool QIToolBar::useTextLabels() const
70{
71 /* Depending on parent, return the style: */
72 if (m_pMainWindow)
73 return m_pMainWindow->toolButtonStyle() == Qt::ToolButtonTextUnderIcon;
74 else
75 return toolButtonStyle() == Qt::ToolButtonTextUnderIcon;
76}
77
78#ifdef VBOX_WS_MAC
79void QIToolBar::enableMacToolbar()
80{
81 /* Depending on parent, enable unified title/tool-bar: */
82 if (m_pMainWindow)
83 m_pMainWindow->setUnifiedTitleAndToolBarOnMac(true);
84}
85
86void QIToolBar::emulateMacToolbar()
87{
88 /* Remember request, to be used in paintEvent: */
89 m_fEmulateUnifiedToolbar = true;
90}
91
92void QIToolBar::setShowToolBarButton(bool fShow)
93{
94 ::darwinSetShowsToolbarButton(this, fShow);
95}
96
97void QIToolBar::updateLayout()
98{
99 // WORKAROUND:
100 // There is a bug in Qt Cocoa which result in showing a "more arrow" when
101 // the necessary size of the tool-bar is increased. Also for some languages
102 // the with doesn't match if the text increase. So manually adjust the size
103 // after changing the text.
104 QSizePolicy sp = sizePolicy();
105 setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
106 adjustSize();
107 setSizePolicy(sp);
108 layout()->invalidate();
109 layout()->activate();
110}
111
112void QIToolBar::enableBranding(const QIcon &icnBranding,
113 const QString &strBranding,
114 const QColor &clrBranding,
115 int iBrandingWidth)
116{
117 m_icnBranding = icnBranding;
118 m_strBranding = strBranding;
119 m_clrBranding = clrBranding;
120 m_iBrandingWidth = iBrandingWidth;
121 update();
122}
123#endif /* VBOX_WS_MAC */
124
125bool QIToolBar::event(QEvent *pEvent)
126{
127 /* Sanity check: */
128 if (!pEvent)
129 return QToolBar::event(pEvent);
130
131 /* Handle required event types: */
132 switch (pEvent->type())
133 {
134#ifdef VBOX_WS_MAC
135 case QEvent::LayoutRequest:
136 {
137 /* Recalculate overall contents width on layout
138 * request if we have branding stuff: */
139 if (!m_icnBranding.isNull())
140 recalculateOverallContentsWidth();
141 break;
142 }
143#endif /* VBOX_WS_MAC */
144 default:
145 break;
146 }
147
148 /* Call to base-class: */
149 return QToolBar::event(pEvent);
150}
151
152void QIToolBar::resizeEvent(QResizeEvent *pEvent)
153{
154 /* Call to base-class: */
155 QToolBar::resizeEvent(pEvent);
156
157 /* Notify listeners about new size: */
158 emit sigResized(pEvent->size());
159}
160
161#ifdef VBOX_WS_MAC
162void QIToolBar::paintEvent(QPaintEvent *pEvent)
163{
164 /* Call to base-class: */
165 QToolBar::paintEvent(pEvent);
166
167 /* If we have request to emulate unified tool-bar: */
168 if (m_fEmulateUnifiedToolbar)
169 {
170 /* Limit painting with incoming rectangle: */
171 QPainter painter(this);
172 painter.setClipRect(pEvent->rect());
173
174 /* Acquire full rectangle: */
175 const QRect rectangle = rect();
176
177 /* Prepare gradient: */
178 const QColor backgroundColor = QApplication::palette().color(QPalette::Active, QPalette::Window);
179 QLinearGradient gradient(rectangle.topLeft(), rectangle.bottomLeft());
180 gradient.setColorAt(0, backgroundColor.darker(105));
181 gradient.setColorAt(1, backgroundColor.darker(115));
182
183 /* Fill background: */
184 painter.fillRect(rectangle, gradient);
185
186 /* Do we have branding stuff and a place for it? */
187 if ( !m_icnBranding.isNull()
188 && width() >= m_iOverallContentsWidth + m_iBrandingWidth)
189 {
190 /* A bit of common stuff: */
191 QFont fnt = font();
192 int iTextWidth = 0;
193 int iTextHeight = 0;
194
195 /* Configure font to fit width (m_iBrandingWidth - 2 * 4): */
196 if (useTextLabels())
197 {
198 for (int i = 0; i <= 10; ++i) // no more than 10 tries ..
199 {
200 if (fnt.pixelSize() == -1)
201 fnt.setPointSize(fnt.pointSize() - i);
202 else
203 fnt.setPixelSize(fnt.pixelSize() - i);
204 iTextWidth = QFontMetrics(fnt).size(0, m_strBranding).width();
205 if (iTextWidth <= m_iBrandingWidth - 2 * 4)
206 break;
207 }
208 iTextHeight = QFontMetrics(fnt).height();
209 }
210
211 /* Draw pixmap: */
212 const int iIconSize = qMin(rectangle.height(), 32 /* default */);
213 const int iIconMarginH = (m_iBrandingWidth - iIconSize) / 2;
214 const int iIconMarginV = (rectangle.height() - iIconSize - iTextHeight) / 2;
215 const int iIconX = rectangle.width() - iIconSize - iIconMarginH;
216 const int iIconY = iIconMarginV;
217 painter.drawPixmap(iIconX, iIconY, m_icnBranding.pixmap(QSize(iIconSize, iIconSize)));
218
219 /* Draw text path: */
220 if (useTextLabels())
221 {
222 const int iTextMargingH = (m_iBrandingWidth - iTextWidth) / 2;
223 const int iTextX = rectangle.width() - iTextWidth - iTextMargingH;
224 const int iTextY = iIconY + iIconSize + iTextHeight;
225 QPainterPath textPath;
226 textPath.addText(0, 0, fnt, m_strBranding);
227 textPath.translate(iTextX, iTextY);
228 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
229 painter.setPen(QPen(m_clrBranding.darker(80), 2, Qt::SolidLine, Qt::RoundCap));
230 painter.drawPath(QPainterPathStroker().createStroke(textPath));
231 painter.setBrush(Qt::black);
232 painter.setPen(Qt::NoPen);
233 painter.drawPath(textPath);
234 }
235 }
236 }
237}
238#endif /* VBOX_WS_MAC */
239
240void QIToolBar::prepare()
241{
242 /* Configure tool-bar: */
243 setFloatable(false);
244 setMovable(false);
245
246#ifdef VBOX_WS_MAC
247 setStyleSheet("QToolBar { border: 0px none black; }");
248#endif
249
250 /* Configure tool-bar' layout: */
251 if (layout())
252 layout()->setContentsMargins(0, 0, 0, 0);
253
254 /* Configure tool-bar' context-menu policy: */
255 setContextMenuPolicy(Qt::NoContextMenu);
256}
257
258#ifdef VBOX_WS_MAC
259void QIToolBar::recalculateOverallContentsWidth()
260{
261 /* Reset contents width: */
262 m_iOverallContentsWidth = 0;
263
264 /* Caclulate new value: */
265 if (!layout())
266 return;
267 int iResult = 0;
268 const int iSpacing = layout()->spacing();
269 foreach (QAction *pAction, actions())
270 {
271 if (!pAction || !pAction->isVisible())
272 continue;
273 QWidget *pWidget = widgetForAction(pAction);
274 if (!pWidget)
275 continue;
276 /* Add each widget width and spacing: */
277 const int iWidth = pWidget->width() + iSpacing;
278 iResult += iWidth;
279 }
280 /* Subtract last spacing: */
281 iResult -= iSpacing;
282
283 /* Update result: */
284 m_iOverallContentsWidth = qMax(m_iOverallContentsWidth, iResult);
285}
286#endif /* VBOX_WS_MAC */
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