VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 4 weeks 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.2 KB
RevLine 
[46193]1/* $Id: QIToolBar.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
[25178]2/** @file
[86233]3 * VBox Qt GUI - QIToolBar class implementation.
[25178]4 */
5
6/*
[106061]7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
[25178]8 *
[96407]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
[25178]26 */
27
[51937]28/* Qt includes: */
[76606]29#include <QLayout>
30#include <QMainWindow>
31#include <QResizeEvent>
32#ifdef VBOX_WS_MAC
[88863]33# include <QApplication>
[76606]34# include <QPainter>
[94995]35# include <QPainterPath>
[76606]36#endif
[51937]37
38/* GUI includes: */
[86233]39#include "QIToolBar.h"
[76606]40#ifdef VBOX_WS_MAC
41# include "VBoxUtils.h"
42#endif
[52730]43
[25178]44
[86233]45QIToolBar::QIToolBar(QWidget *pParent /* = 0 */)
[32760]46 : QToolBar(pParent)
[46193]47 , m_pMainWindow(qobject_cast<QMainWindow*>(pParent))
[74593]48#ifdef VBOX_WS_MAC
49 , m_fEmulateUnifiedToolbar(false)
[95003]50 , m_iOverallContentsWidth(0)
[94995]51 , m_iBrandingWidth(0)
[74593]52#endif
[25178]53{
[51937]54 prepare();
[32760]55}
[25178]56
[86233]57void QIToolBar::setUseTextLabels(bool fEnable)
[46193]58{
[51937]59 /* Determine tool-button style on the basis of passed flag: */
60 Qt::ToolButtonStyle tbs = fEnable ? Qt::ToolButtonTextUnderIcon : Qt::ToolButtonIconOnly;
[46193]61
[51937]62 /* Depending on parent, assign this style: */
[46193]63 if (m_pMainWindow)
64 m_pMainWindow->setToolButtonStyle(tbs);
65 else
66 setToolButtonStyle(tbs);
67}
68
[95002]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
[60362]78#ifdef VBOX_WS_MAC
[86233]79void QIToolBar::enableMacToolbar()
[32760]80{
[51937]81 /* Depending on parent, enable unified title/tool-bar: */
[32760]82 if (m_pMainWindow)
83 m_pMainWindow->setUnifiedTitleAndToolBarOnMac(true);
84}
[25178]85
[86233]86void QIToolBar::emulateMacToolbar()
[74593]87{
88 /* Remember request, to be used in paintEvent: */
89 m_fEmulateUnifiedToolbar = true;
90}
91
[86233]92void QIToolBar::setShowToolBarButton(bool fShow)
[32760]93{
94 ::darwinSetShowsToolbarButton(this, fShow);
95}
[29975]96
[94995]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}
[60362]108#endif /* VBOX_WS_MAC */
[25178]109
[95003]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
[86233]137void QIToolBar::resizeEvent(QResizeEvent *pEvent)
[74137]138{
139 /* Call to base-class: */
140 QToolBar::resizeEvent(pEvent);
141
142 /* Notify listeners about new size: */
143 emit sigResized(pEvent->size());
144}
145
[74593]146#ifdef VBOX_WS_MAC
[86233]147void QIToolBar::paintEvent(QPaintEvent *pEvent)
[74593]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 {
[94985]155 /* Limit painting with incoming rectangle: */
156 QPainter painter(this);
157 painter.setClipRect(pEvent->rect());
[74593]158
[94985]159 /* Acquire full rectangle: */
160 const QRect rectangle = rect();
161
[74593]162 /* Prepare gradient: */
[89248]163 const QColor backgroundColor = QApplication::palette().color(QPalette::Active, QPalette::Window);
[74593]164 QLinearGradient gradient(rectangle.topLeft(), rectangle.bottomLeft());
[102423]165#if defined (VBOX_WS_MAC)
166 gradient.setColorAt(0, backgroundColor.lighter(105));
167 gradient.setColorAt(1, backgroundColor.darker(105));
168#else
[89248]169 gradient.setColorAt(0, backgroundColor.darker(105));
170 gradient.setColorAt(1, backgroundColor.darker(115));
[102423]171#endif
[74593]172
173 /* Fill background: */
174 painter.fillRect(rectangle, gradient);
[94995]175
[95003]176 /* Do we have branding stuff and a place for it? */
177 if ( !m_icnBranding.isNull()
178 && width() >= m_iOverallContentsWidth + m_iBrandingWidth)
[94995]179 {
[95002]180 /* A bit of common stuff: */
[94995]181 QFont fnt = font();
182 int iTextWidth = 0;
[95002]183 int iTextHeight = 0;
184
185 /* Configure font to fit width (m_iBrandingWidth - 2 * 4): */
186 if (useTextLabels())
[94995]187 {
[95002]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();
[94995]199 }
200
201 /* Draw pixmap: */
202 const int iIconSize = qMin(rectangle.height(), 32 /* default */);
203 const int iIconMarginH = (m_iBrandingWidth - iIconSize) / 2;
[95002]204 const int iIconMarginV = (rectangle.height() - iIconSize - iTextHeight) / 2;
[94995]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: */
[95002]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 }
[94995]225 }
[74593]226 }
227}
228#endif /* VBOX_WS_MAC */
229
[86233]230void QIToolBar::prepare()
[51937]231{
232 /* Configure tool-bar: */
233 setFloatable(false);
234 setMovable(false);
235
[68315]236#ifdef VBOX_WS_MAC
[71527]237 setStyleSheet("QToolBar { border: 0px none black; }");
238#endif
[51937]239
240 /* Configure tool-bar' layout: */
241 if (layout())
242 layout()->setContentsMargins(0, 0, 0, 0);
243
244 /* Configure tool-bar' context-menu policy: */
[100885]245 setContextMenuPolicy(Qt::PreventContextMenu);
[51937]246}
[95003]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.

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