VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/extensions/QIToolBar.cpp

Last change on this file was 102423, checked in by vboxsync, 6 months ago

FE/Qt: macOS: Adjust cocoa native colors for QIToolBar and Chooser pane global item.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: QIToolBar.cpp 102423 2023-12-01 14:23:43Z 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::enableBranding(const QIcon &icnBranding,
98 const QString &strBranding,
99 const QColor &clrBranding,
100 int iBrandingWidth)
101{
102 m_icnBranding = icnBranding;
103 m_strBranding = strBranding;
104 m_clrBranding = clrBranding;
105 m_iBrandingWidth = iBrandingWidth;
106 update();
107}
108#endif /* VBOX_WS_MAC */
109
110bool QIToolBar::event(QEvent *pEvent)
111{
112 /* Sanity check: */
113 if (!pEvent)
114 return QToolBar::event(pEvent);
115
116 /* Handle required event types: */
117 switch (pEvent->type())
118 {
119#ifdef VBOX_WS_MAC
120 case QEvent::LayoutRequest:
121 {
122 /* Recalculate overall contents width on layout
123 * request if we have branding stuff: */
124 if (!m_icnBranding.isNull())
125 recalculateOverallContentsWidth();
126 break;
127 }
128#endif /* VBOX_WS_MAC */
129 default:
130 break;
131 }
132
133 /* Call to base-class: */
134 return QToolBar::event(pEvent);
135}
136
137void QIToolBar::resizeEvent(QResizeEvent *pEvent)
138{
139 /* Call to base-class: */
140 QToolBar::resizeEvent(pEvent);
141
142 /* Notify listeners about new size: */
143 emit sigResized(pEvent->size());
144}
145
146#ifdef VBOX_WS_MAC
147void QIToolBar::paintEvent(QPaintEvent *pEvent)
148{
149 /* Call to base-class: */
150 QToolBar::paintEvent(pEvent);
151
152 /* If we have request to emulate unified tool-bar: */
153 if (m_fEmulateUnifiedToolbar)
154 {
155 /* Limit painting with incoming rectangle: */
156 QPainter painter(this);
157 painter.setClipRect(pEvent->rect());
158
159 /* Acquire full rectangle: */
160 const QRect rectangle = rect();
161
162 /* Prepare gradient: */
163 const QColor backgroundColor = QApplication::palette().color(QPalette::Active, QPalette::Window);
164 QLinearGradient gradient(rectangle.topLeft(), rectangle.bottomLeft());
165#if defined (VBOX_WS_MAC)
166 gradient.setColorAt(0, backgroundColor.lighter(105));
167 gradient.setColorAt(1, backgroundColor.darker(105));
168#else
169 gradient.setColorAt(0, backgroundColor.darker(105));
170 gradient.setColorAt(1, backgroundColor.darker(115));
171#endif
172
173 /* Fill background: */
174 painter.fillRect(rectangle, gradient);
175
176 /* Do we have branding stuff and a place for it? */
177 if ( !m_icnBranding.isNull()
178 && width() >= m_iOverallContentsWidth + m_iBrandingWidth)
179 {
180 /* A bit of common stuff: */
181 QFont fnt = font();
182 int iTextWidth = 0;
183 int iTextHeight = 0;
184
185 /* Configure font to fit width (m_iBrandingWidth - 2 * 4): */
186 if (useTextLabels())
187 {
188 for (int i = 0; i <= 10; ++i) // no more than 10 tries ..
189 {
190 if (fnt.pixelSize() == -1)
191 fnt.setPointSize(fnt.pointSize() - i);
192 else
193 fnt.setPixelSize(fnt.pixelSize() - i);
194 iTextWidth = QFontMetrics(fnt).size(0, m_strBranding).width();
195 if (iTextWidth <= m_iBrandingWidth - 2 * 4)
196 break;
197 }
198 iTextHeight = QFontMetrics(fnt).height();
199 }
200
201 /* Draw pixmap: */
202 const int iIconSize = qMin(rectangle.height(), 32 /* default */);
203 const int iIconMarginH = (m_iBrandingWidth - iIconSize) / 2;
204 const int iIconMarginV = (rectangle.height() - iIconSize - iTextHeight) / 2;
205 const int iIconX = rectangle.width() - iIconSize - iIconMarginH;
206 const int iIconY = iIconMarginV;
207 painter.drawPixmap(iIconX, iIconY, m_icnBranding.pixmap(QSize(iIconSize, iIconSize)));
208
209 /* Draw text path: */
210 if (useTextLabels())
211 {
212 const int iTextMargingH = (m_iBrandingWidth - iTextWidth) / 2;
213 const int iTextX = rectangle.width() - iTextWidth - iTextMargingH;
214 const int iTextY = iIconY + iIconSize + iTextHeight;
215 QPainterPath textPath;
216 textPath.addText(0, 0, fnt, m_strBranding);
217 textPath.translate(iTextX, iTextY);
218 painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
219 painter.setPen(QPen(m_clrBranding.darker(80), 2, Qt::SolidLine, Qt::RoundCap));
220 painter.drawPath(QPainterPathStroker().createStroke(textPath));
221 painter.setBrush(Qt::black);
222 painter.setPen(Qt::NoPen);
223 painter.drawPath(textPath);
224 }
225 }
226 }
227}
228#endif /* VBOX_WS_MAC */
229
230void QIToolBar::prepare()
231{
232 /* Configure tool-bar: */
233 setFloatable(false);
234 setMovable(false);
235
236#ifdef VBOX_WS_MAC
237 setStyleSheet("QToolBar { border: 0px none black; }");
238#endif
239
240 /* Configure tool-bar' layout: */
241 if (layout())
242 layout()->setContentsMargins(0, 0, 0, 0);
243
244 /* Configure tool-bar' context-menu policy: */
245 setContextMenuPolicy(Qt::PreventContextMenu);
246}
247
248#ifdef VBOX_WS_MAC
249void QIToolBar::recalculateOverallContentsWidth()
250{
251 /* Reset contents width: */
252 m_iOverallContentsWidth = 0;
253
254 /* Caclulate new value: */
255 if (!layout())
256 return;
257 int iResult = 0;
258 const int iSpacing = layout()->spacing();
259 foreach (QAction *pAction, actions())
260 {
261 if (!pAction || !pAction->isVisible())
262 continue;
263 QWidget *pWidget = widgetForAction(pAction);
264 if (!pWidget)
265 continue;
266 /* Add each widget width and spacing: */
267 const int iWidth = pWidget->width() + iSpacing;
268 iResult += iWidth;
269 }
270 /* Subtract last spacing: */
271 iResult -= iSpacing;
272
273 /* Update result: */
274 m_iOverallContentsWidth = qMax(m_iOverallContentsWidth, iResult);
275}
276#endif /* VBOX_WS_MAC */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use