VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/widgets/VBoxMiniToolBar.cpp@ 35740

Last change on this file since 35740 was 35078, checked in by vboxsync, 14 years ago

FE/Qt: Fix replacement for r68895 (mini-toolbar kde bug).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.5 KB
Line 
1/* $Id: VBoxMiniToolBar.cpp 35078 2010-12-14 13:42:28Z vboxsync $ */
2/** @file
3 *
4 * VBox frontends: Qt GUI ("VirtualBox"):
5 * VBoxMiniToolBar class declaration & implementation. This is the toolbar shown on fullscreen mode.
6 */
7
8/*
9 * Copyright (C) 2009-2010 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20/* Local includes */
21#include "UIIconPool.h"
22#include "VBoxGlobal.h"
23#include "VBoxMiniToolBar.h"
24
25/* Global includes */
26#include <QCursor>
27#include <QDesktopWidget>
28#include <QLabel>
29#include <QMenu>
30#include <QPaintEvent>
31#include <QPainter>
32#include <QPolygon>
33#include <QRect>
34#include <QRegion>
35#include <QTimer>
36#include <QToolButton>
37
38/* Mini-toolbar constructor */
39VBoxMiniToolBar::VBoxMiniToolBar(QWidget *pParent, Alignment alignment, bool fActive, bool fAutoHide)
40 : UIToolBar(pParent)
41 , m_pAutoHideAction(0)
42 , m_pDisplayLabel(0)
43 , m_pMinimizeAction(0)
44 , m_pRestoreAction(0)
45 , m_pCloseAction(0)
46 , m_fActive(fActive)
47 , m_fPolished(false)
48 , m_fSeamless(false)
49 , m_fAutoHide(fAutoHide)
50 , m_fSlideToScreen(true)
51 , m_fHideAfterSlide(false)
52 , m_iAutoHideCounter(0)
53 , m_iPositionX(0)
54 , m_iPositionY(0)
55 , m_pInsertPosition(0)
56 , m_alignment(alignment)
57 , m_fAnimated(true)
58 , m_iScrollDelay(10)
59 , m_iAutoScrollDelay(100)
60 , m_iAutoHideTotalCounter(10)
61{
62 /* Check parent widget presence: */
63 AssertMsg(parentWidget(), ("Parent widget must be set!\n"));
64
65 /* Toolbar options: */
66 setIconSize(QSize(16, 16));
67 setVisible(false);
68
69 /* Left margin of tool-bar: */
70 m_Margins << widgetForAction(addWidget(new QWidget(this)));
71
72 /* Add pushpin: */
73 m_pAutoHideAction = new QAction(this);
74 m_pAutoHideAction->setIcon(UIIconPool::iconSet(":/pin_16px.png"));
75 m_pAutoHideAction->setToolTip(tr("Always show the toolbar"));
76 m_pAutoHideAction->setCheckable(true);
77 m_pAutoHideAction->setChecked(!m_fAutoHide);
78 connect(m_pAutoHideAction, SIGNAL(toggled(bool)), this, SLOT(togglePushpin(bool)));
79 addAction(m_pAutoHideAction);
80
81 /* Left menu margin: */
82 m_Spacings << widgetForAction(addWidget(new QWidget(this)));
83
84 /* Right menu margin: */
85 m_pInsertPosition = addWidget(new QWidget(this));
86 m_Spacings << widgetForAction(m_pInsertPosition);
87
88 /* Left label margin: */
89 m_LabelMargins << widgetForAction(addWidget(new QWidget(this)));
90
91 /* Insert a label for VM Name: */
92 m_pDisplayLabel = new QLabel(this);
93 m_pDisplayLabel->setAlignment(Qt::AlignCenter);
94 addWidget(m_pDisplayLabel);
95
96 /* Right label margin: */
97 m_LabelMargins << widgetForAction(addWidget(new QWidget(this)));
98
99 /* Minimize action: */
100 m_pMinimizeAction = new QAction(this);
101 m_pMinimizeAction->setIcon(UIIconPool::iconSet(":/minimize_16px.png"));
102 m_pMinimizeAction->setToolTip(tr("Minimize Window"));
103 connect(m_pMinimizeAction, SIGNAL(triggered()), this, SIGNAL(minimizeAction()));
104 addAction(m_pMinimizeAction);
105
106 /* Exit action: */
107 m_pRestoreAction = new QAction(this);
108 m_pRestoreAction->setIcon(UIIconPool::iconSet(":/restore_16px.png"));
109 m_pRestoreAction->setToolTip(tr("Exit Full Screen or Seamless Mode"));
110 connect(m_pRestoreAction, SIGNAL(triggered()), this, SIGNAL(exitAction()));
111 addAction(m_pRestoreAction);
112
113 /* Close action: */
114 m_pCloseAction = new QAction(this);
115 m_pCloseAction->setIcon(UIIconPool::iconSet(":/close_16px.png"));
116 m_pCloseAction->setToolTip(tr("Close VM"));
117 connect(m_pCloseAction, SIGNAL(triggered()), this, SIGNAL(closeAction()));
118 addAction(m_pCloseAction);
119
120 /* Right margin of tool-bar: */
121 m_Margins << widgetForAction(addWidget(new QWidget(this)));
122
123 /* Event-filter for parent widget to control resize: */
124 pParent->installEventFilter(this);
125
126 /* Enable mouse-tracking for this & children allowing to get mouse-move events: */
127 setMouseTrackingEnabled(m_fAutoHide);
128}
129
130/* Appends passed menus into internal menu-list */
131VBoxMiniToolBar& VBoxMiniToolBar::operator<<(QList<QMenu*> menus)
132{
133 for (int i = 0; i < menus.size(); ++i)
134 {
135 QAction *pAction = menus[i]->menuAction();
136 insertAction(m_pInsertPosition, pAction);
137 if (QToolButton *pButton = qobject_cast<QToolButton*>(widgetForAction(pAction)))
138 {
139 pButton->setPopupMode(QToolButton::InstantPopup);
140 pButton->setAutoRaise(true);
141 }
142 if (i != menus.size() - 1)
143 m_Spacings << widgetForAction(insertWidget(m_pInsertPosition, new QWidget(this)));
144 }
145 return *this;
146}
147
148/* Seamless mode setter */
149void VBoxMiniToolBar::setSeamlessMode(bool fSeamless)
150{
151 m_fSeamless = fSeamless;
152}
153
154/* Update the display text, usually the VM Name */
155void VBoxMiniToolBar::setDisplayText(const QString &strText)
156{
157 /* If text was really changed: */
158 if (m_pDisplayLabel->text() != strText)
159 {
160 /* Update toolbar label: */
161 m_pDisplayLabel->setText(strText);
162
163 /* Reinitialize: */
164 initialize();
165
166 /* Update toolbar if its not hidden: */
167 if (!isHidden())
168 updateDisplay(!m_fAutoHide, false);
169 }
170}
171
172/* Is auto-hide feature enabled? */
173bool VBoxMiniToolBar::isAutoHide() const
174{
175 return m_fAutoHide;
176}
177
178void VBoxMiniToolBar::updateDisplay(bool fShow, bool fSetHideFlag)
179{
180 m_iAutoHideCounter = 0;
181
182 setMouseTrackingEnabled(m_fAutoHide);
183
184 if (fShow)
185 {
186 if (isHidden())
187 moveToBase();
188
189 if (m_fAnimated)
190 {
191 if (fSetHideFlag)
192 {
193 m_fHideAfterSlide = false;
194 m_fSlideToScreen = true;
195 }
196 if (m_fActive)
197 show();
198 m_scrollTimer.start(m_iScrollDelay, this);
199 }
200 else if (m_fActive)
201 show();
202
203 if (m_fAutoHide)
204 m_autoScrollTimer.start(m_iAutoScrollDelay, this);
205 else
206 m_autoScrollTimer.stop();
207 }
208 else
209 {
210 if (m_fAnimated)
211 {
212 if (fSetHideFlag)
213 {
214 m_fHideAfterSlide = true;
215 m_fSlideToScreen = false;
216 }
217 m_scrollTimer.start(m_iScrollDelay, this);
218 }
219 else
220 hide();
221
222 if (m_fAutoHide)
223 m_autoScrollTimer.start(m_iAutoScrollDelay, this);
224 else
225 m_autoScrollTimer.stop();
226 }
227}
228
229/* Parent widget event-filter */
230bool VBoxMiniToolBar::eventFilter(QObject *pObject, QEvent *pEvent)
231{
232 /* If parent widget was resized: */
233 if (pObject == parent() && pEvent->type() == QEvent::Resize)
234 {
235 /* Update toolbar position: */
236 moveToBase();
237 return true;
238 }
239 /* Base-class event-filter: */
240 return UIToolBar::eventFilter(pObject, pEvent);
241}
242
243/* Mouse-move event processor */
244void VBoxMiniToolBar::mouseMoveEvent(QMouseEvent *pEvent)
245{
246 /* Activate sliding animation on mouse move: */
247 if (!m_fHideAfterSlide)
248 {
249 m_fSlideToScreen = true;
250 m_scrollTimer.start(m_iScrollDelay, this);
251 }
252 /* Base-class mouse-move event processing: */
253 UIToolBar::mouseMoveEvent(pEvent);
254}
255
256/* Timer event processor
257 * Handles auto hide feature of the toolbar */
258void VBoxMiniToolBar::timerEvent(QTimerEvent *pEvent)
259{
260 if (pEvent->timerId() == m_scrollTimer.timerId())
261 {
262 QRect screen = m_fSeamless ? vboxGlobal().availableGeometry(QApplication::desktop()->screenNumber(window())) :
263 QApplication::desktop()->screenGeometry(window());
264 switch (m_alignment)
265 {
266 case AlignTop:
267 {
268 if (((m_iPositionY == screen.y()) && m_fSlideToScreen) ||
269 ((m_iPositionY == screen.y() - height() + 1) && !m_fSlideToScreen))
270 {
271 m_scrollTimer.stop();
272 if (m_fHideAfterSlide)
273 {
274 m_fHideAfterSlide = false;
275 hide();
276 }
277 return;
278 }
279 m_fSlideToScreen ? ++m_iPositionY : --m_iPositionY;
280 break;
281 }
282 case AlignBottom:
283 {
284 if (((m_iPositionY == screen.y() + screen.height() - height()) && m_fSlideToScreen) ||
285 ((m_iPositionY == screen.y() + screen.height() - 1) && !m_fSlideToScreen))
286 {
287 m_scrollTimer.stop();
288 if (m_fHideAfterSlide)
289 {
290 m_fHideAfterSlide = false;
291 hide();
292 }
293 return;
294 }
295 m_fSlideToScreen ? --m_iPositionY : ++m_iPositionY;
296 break;
297 }
298 default:
299 break;
300 }
301 move(parentWidget()->mapFromGlobal(QPoint(m_iPositionX, m_iPositionY)));
302 emit geometryUpdated();
303 }
304 else if (pEvent->timerId() == m_autoScrollTimer.timerId())
305 {
306 QRect rect = this->rect();
307 QPoint p = mapFromGlobal(QCursor::pos());
308 if (!rect.contains(p))
309 {
310 ++m_iAutoHideCounter;
311
312 if (m_iAutoHideCounter == m_iAutoHideTotalCounter)
313 {
314 m_fSlideToScreen = false;
315 m_scrollTimer.start(m_iScrollDelay, this);
316 }
317 }
318 else
319 m_iAutoHideCounter = 0;
320 }
321 else
322 QWidget::timerEvent(pEvent);
323}
324
325/* Show event processor */
326void VBoxMiniToolBar::showEvent(QShowEvent *pEvent)
327{
328 if (!m_fPolished)
329 {
330 /* Tool-bar margins: */
331 foreach(QWidget *pMargin, m_Margins)
332 pMargin->setMinimumWidth(height());
333
334 /* Tool-bar spacings: */
335 foreach(QWidget *pSpacing, m_Spacings)
336 pSpacing->setMinimumWidth(5);
337
338 /* Title spacings: */
339 foreach(QWidget *pLableMargin, m_LabelMargins)
340 pLableMargin->setMinimumWidth(15);
341
342 /* Initialize: */
343 initialize();
344
345 m_fPolished = true;
346 }
347 /* Base-class show event processing: */
348 UIToolBar::showEvent(pEvent);
349}
350
351/* Show event processor */
352void VBoxMiniToolBar::paintEvent(QPaintEvent *pEvent)
353{
354 /* Paint background */
355 QPainter painter;
356 painter.begin(this);
357 painter.fillRect(pEvent->rect(), QApplication::palette().color(QPalette::Active, QPalette::Window));
358 painter.end();
359 /* Base-class paint event processing: */
360 UIToolBar::paintEvent(pEvent);
361}
362
363/* Toggle push-pin */
364void VBoxMiniToolBar::togglePushpin(bool fOn)
365{
366 m_fAutoHide = !fOn;
367 updateDisplay(!m_fAutoHide, false);
368}
369
370/* Initialize mini-toolbar */
371void VBoxMiniToolBar::initialize()
372{
373 /* Resize to sizehint: */
374 resize(sizeHint());
375
376 /* Update geometry: */
377 recreateMask();
378 moveToBase();
379}
380
381/* Recreate mini-toolbar mask */
382void VBoxMiniToolBar::recreateMask()
383{
384 int iEdgeShift = height();
385 int iPoints[8];
386 switch (m_alignment)
387 {
388 case AlignTop:
389 {
390 iPoints[0] = 0;
391 iPoints[1] = 0;
392
393 iPoints[2] = iEdgeShift;
394 iPoints[3] = height();
395
396 iPoints[4] = width() - iEdgeShift;
397 iPoints[5] = height();
398
399 iPoints[6] = width();
400 iPoints[7] = 0;
401
402 break;
403 }
404 case AlignBottom:
405 {
406 iPoints[0] = iEdgeShift;
407 iPoints[1] = 0;
408
409 iPoints[2] = 0;
410 iPoints[3] = height();
411
412 iPoints[4] = width();
413 iPoints[5] = height();
414
415 iPoints[6] = width() - iEdgeShift;
416 iPoints[7] = 0;
417
418 break;
419 }
420 default:
421 break;
422 }
423 /* Make sure any old mask is removed first: */
424 clearMask();
425 /* Set the new mask */
426 QPolygon polygon;
427 polygon.setPoints(4, iPoints);
428 setMask(polygon);
429}
430
431/* Move mini-toolbar to the base location */
432void VBoxMiniToolBar::moveToBase()
433{
434 QRect screen = m_fSeamless ? vboxGlobal().availableGeometry(QApplication::desktop()->screenNumber(window())) :
435 QApplication::desktop()->screenGeometry(window());
436 m_iPositionX = screen.x() + (screen.width() / 2) - (width() / 2);
437 switch (m_alignment)
438 {
439 case AlignTop:
440 {
441 m_iPositionY = screen.y() - height() + 1;
442 break;
443 }
444 case AlignBottom:
445 {
446 m_iPositionY = screen.y() + screen.height() - 1;
447 break;
448 }
449 default:
450 {
451 m_iPositionY = 0;
452 break;
453 }
454 }
455 move(parentWidget()->mapFromGlobal(QPoint(m_iPositionX, m_iPositionY)));
456}
457
458/* Enable/disable mouse-tracking for required widgets */
459void VBoxMiniToolBar::setMouseTrackingEnabled(bool fEnabled)
460{
461 setMouseTracking(fEnabled);
462 if (m_pDisplayLabel)
463 m_pDisplayLabel->setMouseTracking(fEnabled);
464 if (m_pAutoHideAction && widgetForAction(m_pAutoHideAction))
465 widgetForAction(m_pAutoHideAction)->setMouseTracking(fEnabled);
466 if (m_pMinimizeAction && widgetForAction(m_pMinimizeAction))
467 widgetForAction(m_pMinimizeAction)->setMouseTracking(fEnabled);
468 if (m_pRestoreAction && widgetForAction(m_pRestoreAction))
469 widgetForAction(m_pRestoreAction)->setMouseTracking(fEnabled);
470 if (m_pCloseAction && widgetForAction(m_pCloseAction))
471 widgetForAction(m_pCloseAction)->setMouseTracking(fEnabled);
472}
473
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use