VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/manager/chooser/UIChooserItemGlobal.cpp

Last change on this file was 104313, checked in by vboxsync, 6 weeks ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in the settings related GUI classes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.6 KB
Line 
1/* $Id: UIChooserItemGlobal.cpp 104313 2024-04-12 13:10:30Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIChooserItemGlobal class implementation.
4 */
5
6/*
7 * Copyright (C) 2012-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 <QGraphicsSceneMouseEvent>
31#include <QGraphicsView>
32#include <QPainter>
33#include <QStyleOptionGraphicsItem>
34#include <QWindow>
35
36/* GUI includes: */
37#include "UIChooserItemGlobal.h"
38#include "UIChooserModel.h"
39#include "UIChooserNodeGlobal.h"
40#include "UIIconPool.h"
41#include "UIImageTools.h"
42#include "UITranslationEventListener.h"
43#include "UIVirtualBoxManager.h"
44
45
46UIChooserItemGlobal::UIChooserItemGlobal(UIChooserItem *pParent, UIChooserNodeGlobal *pNode)
47 : UIChooserItem(pParent, pNode)
48#ifdef VBOX_WS_MAC
49 , m_iDefaultColorDeviation(0)
50#endif
51 , m_iHoverLightnessStart(0)
52 , m_iHoverLightnessFinal(0)
53 , m_iHighlightLightnessStart(0)
54 , m_iHighlightLightnessFinal(0)
55 , m_iMinimumNameWidth(0)
56 , m_iMaximumNameWidth(0)
57 , m_iHeightHint(0)
58{
59 prepare();
60}
61
62UIChooserItemGlobal::~UIChooserItemGlobal()
63{
64 cleanup();
65}
66
67UIChooserNodeGlobal *UIChooserItemGlobal::nodeToGlobalType() const
68{
69 return node() ? node()->toGlobalNode() : 0;
70}
71
72bool UIChooserItemGlobal::isToolButtonArea(const QPoint &position, int iMarginMultiplier /* = 1 */) const
73{
74 const int iFullWidth = geometry().width();
75 const int iFullHeight = geometry().height();
76 const int iMarginHR = data(GlobalItemData_MarginHR).toInt();
77 const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
78 const int iToolPixmapX = iFullWidth - iMarginHR - 1
79 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
80 const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
81 QRect rect = QRect(iToolPixmapX,
82 iToolPixmapY,
83 m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
84 m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
85 rect.adjust(-iMarginMultiplier * iButtonMargin, -iMarginMultiplier * iButtonMargin,
86 iMarginMultiplier * iButtonMargin, iMarginMultiplier * iButtonMargin);
87 return rect.contains(position);
88}
89
90bool UIChooserItemGlobal::isPinButtonArea(const QPoint &position, int iMarginMultiplier /* = 1 */) const
91{
92 const int iFullWidth = geometry().width();
93 const int iFullHeight = geometry().height();
94 const int iMarginHR = data(GlobalItemData_MarginHR).toInt();
95 const int iSpacing = data(GlobalItemData_Spacing).toInt();
96 const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
97 const int iPinPixmapX = iFullWidth - iMarginHR - 1
98 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio()
99 - iSpacing
100 - m_pinPixmap.width() / m_pinPixmap.devicePixelRatio();
101 const int iPinPixmapY = (iFullHeight - m_pinPixmap.height() / m_pinPixmap.devicePixelRatio()) / 2;
102 QRect rect = QRect(iPinPixmapX,
103 iPinPixmapY,
104 m_pinPixmap.width() / m_pinPixmap.devicePixelRatio(),
105 m_pinPixmap.height() / m_pinPixmap.devicePixelRatio());
106 rect.adjust(-iMarginMultiplier * iButtonMargin, -iMarginMultiplier * iButtonMargin,
107 iMarginMultiplier * iButtonMargin, iMarginMultiplier * iButtonMargin);
108 return rect.contains(position);
109}
110
111int UIChooserItemGlobal::heightHint() const
112{
113 return m_iHeightHint;
114}
115
116void UIChooserItemGlobal::setHeightHint(int iHint)
117{
118 /* Remember a new hint: */
119 m_iHeightHint = iHint;
120
121 /* Update geometry and the model layout: */
122 updateGeometry();
123 model()->updateLayout();
124}
125
126void UIChooserItemGlobal::sltRetranslateUI()
127{
128}
129
130void UIChooserItemGlobal::showEvent(QShowEvent *pEvent)
131{
132 /* Call to base-class: */
133 UIChooserItem::showEvent(pEvent);
134
135 /* Update pixmaps: */
136 updatePixmaps();
137}
138
139void UIChooserItemGlobal::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
140{
141 /* Call to base-class: */
142 UIChooserItem::resizeEvent(pEvent);
143
144 /* What is the new geometry? */
145 const QRectF newGeometry = geometry();
146
147 /* Should we update visible name? */
148 if (previousGeometry().width() != newGeometry.width())
149 updateMaximumNameWidth();
150
151 /* Remember the new geometry: */
152 setPreviousGeometry(newGeometry);
153}
154
155void UIChooserItemGlobal::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
156{
157 /* Call to base-class: */
158 UIChooserItem::mousePressEvent(pEvent);
159 /* No drag at all: */
160 pEvent->ignore();
161}
162
163void UIChooserItemGlobal::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget * /* pWidget = 0 */)
164{
165 /* Acquire rectangle: */
166 const QRect rectangle = pOptions->rect;
167
168 /* Paint background: */
169 paintBackground(pPainter, rectangle);
170 /* Paint frame: */
171 paintFrame(pPainter, rectangle);
172 /* Paint global info: */
173 paintGlobalInfo(pPainter, rectangle);
174}
175
176void UIChooserItemGlobal::setFavorite(bool fFavorite)
177{
178 /* Call to base-class: */
179 UIChooserItem::setFavorite(fFavorite);
180
181 /* Update pin-pixmap: */
182 updatePinPixmap();
183}
184
185void UIChooserItemGlobal::startEditing()
186{
187 AssertMsgFailed(("Global graphics item do NOT support editing yet!"));
188}
189
190void UIChooserItemGlobal::updateItem()
191{
192 /* Update this global-item: */
193 updatePixmaps();
194 updateMinimumNameWidth();
195 updateVisibleName();
196 updateToolTip();
197 update();
198
199 /* Update parent group-item: */
200 parentItem()->updateToolTip();
201 parentItem()->update();
202}
203
204void UIChooserItemGlobal::updateToolTip()
205{
206 // Nothing for now..
207}
208
209QList<UIChooserItem*> UIChooserItemGlobal::items(UIChooserNodeType) const
210{
211 AssertMsgFailedReturn(("Global graphics item do NOT support children!"), QList<UIChooserItem*>());
212}
213
214void UIChooserItemGlobal::addItem(UIChooserItem *, bool, int)
215{
216 AssertMsgFailed(("Global graphics item do NOT support children!"));
217}
218
219void UIChooserItemGlobal::removeItem(UIChooserItem *)
220{
221 AssertMsgFailed(("Global graphics item do NOT support children!"));
222}
223
224UIChooserItem *UIChooserItemGlobal::searchForItem(const QString &, int iSearchFlags)
225{
226 /* Ignore if we are not searching for the global-item: */
227 if (!(iSearchFlags & UIChooserItemSearchFlag_Global))
228 return 0;
229
230 /* Returning this: */
231 return this;
232}
233
234UIChooserItem *UIChooserItemGlobal::firstMachineItem()
235{
236 return 0;
237}
238
239void UIChooserItemGlobal::updateLayout()
240{
241 // Just do nothing ..
242}
243
244int UIChooserItemGlobal::minimumWidthHint() const
245{
246 /* Prepare variables: */
247 const int iMarginHL = data(GlobalItemData_MarginHL).toInt();
248 const int iMarginHR = data(GlobalItemData_MarginHR).toInt();
249 const int iSpacing = data(GlobalItemData_Spacing).toInt();
250
251 /* Calculating proposed width: */
252 int iProposedWidth = 0;
253
254 /* Two margins: */
255 iProposedWidth += iMarginHL + iMarginHR;
256 /* And global-item content width: */
257 iProposedWidth += (m_pixmapSize.width() +
258 iSpacing +
259 m_iMinimumNameWidth +
260 iSpacing +
261 m_toolPixmapSize.width() +
262 iSpacing +
263 m_pinPixmapSize.width());
264
265 /* Return result: */
266 return iProposedWidth;
267}
268
269int UIChooserItemGlobal::minimumHeightHint() const
270{
271 /* Prepare variables: */
272 const int iMarginV = data(GlobalItemData_MarginV).toInt();
273
274 /* Calculating proposed height: */
275 int iProposedHeight = 0;
276
277 /* Global-item content height: */
278 int iContentHeight = qMax(m_pixmapSize.height(), m_visibleNameSize.height());
279 iContentHeight = qMax(iContentHeight, m_toolPixmapSize.height());
280 iContentHeight = qMax(iContentHeight, m_pinPixmapSize.height());
281
282 /* If we have height hint: */
283 if (m_iHeightHint)
284 {
285 /* Take the largest value between height hint and content height: */
286 iProposedHeight += qMax(m_iHeightHint, iContentHeight);
287 }
288 /* Otherwise: */
289 else
290 {
291 /* Two margins: */
292 iProposedHeight += 2 * iMarginV;
293 /* And content height: */
294 iProposedHeight += iContentHeight;
295 }
296
297 /* Return result: */
298 return iProposedHeight;
299}
300
301QSizeF UIChooserItemGlobal::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
302{
303 /* If Qt::MinimumSize requested: */
304 if (which == Qt::MinimumSize)
305 return QSizeF(minimumWidthHint(), minimumHeightHint());
306 /* Else call to base-class: */
307 return UIChooserItem::sizeHint(which, constraint);
308}
309
310QPixmap UIChooserItemGlobal::toPixmap()
311{
312 AssertFailedReturn(QPixmap());
313}
314
315bool UIChooserItemGlobal::isDropAllowed(QGraphicsSceneDragDropEvent *, UIChooserItemDragToken) const
316{
317 /* No drops at all: */
318 return false;
319}
320
321void UIChooserItemGlobal::processDrop(QGraphicsSceneDragDropEvent *, UIChooserItem *, UIChooserItemDragToken)
322{
323 /* Nothing to process: */
324}
325
326void UIChooserItemGlobal::resetDragToken()
327{
328 /* Nothing to process: */
329}
330
331QMimeData *UIChooserItemGlobal::createMimeData()
332{
333 /* Nothing to return: */
334 return 0;
335}
336
337void UIChooserItemGlobal::sltHandleWindowRemapped()
338{
339 updatePixmaps();
340}
341
342void UIChooserItemGlobal::prepare()
343{
344 /* Color tones: */
345#if defined(VBOX_WS_MAC)
346 m_iDefaultColorDeviation = 105;
347 m_iHoverLightnessStart = 125;
348 m_iHoverLightnessFinal = 115;
349 m_iHighlightLightnessStart = 115;
350 m_iHighlightLightnessFinal = 105;
351#elif defined(VBOX_WS_WIN)
352 m_iHoverLightnessStart = 220;
353 m_iHoverLightnessFinal = 210;
354 m_iHighlightLightnessStart = 190;
355 m_iHighlightLightnessFinal = 180;
356#else /* !VBOX_WS_MAC && !VBOX_WS_WIN */
357 m_iHoverLightnessStart = 125;
358 m_iHoverLightnessFinal = 115;
359 m_iHighlightLightnessStart = 110;
360 m_iHighlightLightnessFinal = 100;
361#endif /* !VBOX_WS_MAC && !VBOX_WS_WIN */
362
363 /* Fonts: */
364 m_nameFont = font();
365 m_nameFont.setWeight(QFont::Bold);
366
367 /* Sizes: */
368 m_iMinimumNameWidth = 0;
369 m_iMaximumNameWidth = 0;
370
371 /* Add item to the parent: */
372 AssertPtrReturnVoid(parentItem());
373 parentItem()->addItem(this, isFavorite(), position());
374
375 /* Configure connections: */
376 connect(gpManager, &UIVirtualBoxManager::sigWindowRemapped,
377 this, &UIChooserItemGlobal::sltHandleWindowRemapped);
378
379 /* Init: */
380 updatePixmaps();
381
382 /* Apply language settings: */
383 sltRetranslateUI();
384 connect(&translationEventListener(), &UITranslationEventListener::sigRetranslateUI,
385 this, &UIChooserItemGlobal::sltRetranslateUI);
386}
387
388void UIChooserItemGlobal::cleanup()
389{
390 /* If that item is current: */
391 if (model()->currentItem() == this)
392 {
393 /* Unset current-item: */
394 model()->setCurrentItem(0);
395 }
396 /* If that item is in selection list: */
397 if (model()->selectedItems().contains(this))
398 {
399 /* Remove item from the selection list: */
400 model()->removeFromSelectedItems(this);
401 }
402 /* If that item is in navigation list: */
403 if (model()->navigationItems().contains(this))
404 {
405 /* Remove item from the navigation list: */
406 model()->removeFromNavigationItems(this);
407 }
408
409 /* Remove item from the parent: */
410 AssertPtrReturnVoid(parentItem());
411 parentItem()->removeItem(this);
412}
413
414QVariant UIChooserItemGlobal::data(int iKey) const
415{
416 /* Provide other members with required data: */
417 switch (iKey)
418 {
419 /* Layout hints: */
420 case GlobalItemData_MarginHL: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize);
421 case GlobalItemData_MarginHR: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4 * 5;
422 case GlobalItemData_MarginV: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4 * 3;
423 case GlobalItemData_Spacing: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 2;
424 case GlobalItemData_ButtonMargin: return QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 4;
425
426 /* Default: */
427 default: break;
428 }
429 return QVariant();
430}
431
432void UIChooserItemGlobal::updatePixmaps()
433{
434 /* Update pixmap: */
435 updatePixmap();
436 /* Update tool-pixmap: */
437 updateToolPixmap();
438 /* Update pin-pixmap: */
439 updatePinPixmap();
440}
441
442void UIChooserItemGlobal::updatePixmap()
443{
444 /* Acquire new metric, then compose pixmap-size: */
445 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize);
446 const QSize pixmapSize = QSize(iMetric, iMetric);
447
448 /* Create new icon, then acquire pixmap: */
449 const QIcon icon = UIIconPool::iconSet(":/tools_global_32px.png");
450 const qreal fDevicePixelRatio = gpManager->windowHandle() ? gpManager->windowHandle()->devicePixelRatio() : 1;
451 const QPixmap pixmap = icon.pixmap(pixmapSize, fDevicePixelRatio);
452
453 /* Update linked values: */
454 if (m_pixmapSize != pixmapSize)
455 {
456 m_pixmapSize = pixmapSize;
457 updateMaximumNameWidth();
458 updateGeometry();
459 }
460 if (m_pixmap.toImage() != pixmap.toImage())
461 {
462 m_pixmap = pixmap;
463 update();
464 }
465}
466
467void UIChooserItemGlobal::updateToolPixmap()
468{
469 /* Determine icon metric: */
470 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) * .75;
471 /* Create new tool-pixmap and tool-pixmap size: */
472 const QIcon toolIcon = UIIconPool::iconSet(":/tools_menu_24px.png");
473 AssertReturnVoid(!toolIcon.isNull());
474 const QSize toolPixmapSize = QSize(iIconMetric, iIconMetric);
475 const qreal fDevicePixelRatio = gpManager->windowHandle() ? gpManager->windowHandle()->devicePixelRatio() : 1;
476 const QPixmap toolPixmap = toolIcon.pixmap(toolPixmapSize, fDevicePixelRatio);
477 /* Update linked values: */
478 if (m_toolPixmapSize != toolPixmapSize)
479 {
480 m_toolPixmapSize = toolPixmapSize;
481 updateGeometry();
482 }
483 if (m_toolPixmap.toImage() != toolPixmap.toImage())
484 {
485 m_toolPixmap = toolPixmap;
486 update();
487 }
488}
489
490void UIChooserItemGlobal::updatePinPixmap()
491{
492 /* Determine icon metric: */
493 const int iIconMetric = QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize) * .75;
494 /* Create new tool-pixmap and tool-pixmap size: */
495 const QIcon pinIcon = UIIconPool::iconSet(isFavorite() ? ":/favorite_pressed_24px.png" : ":/favorite_24px.png");
496 AssertReturnVoid(!pinIcon.isNull());
497 const QSize pinPixmapSize = QSize(iIconMetric, iIconMetric);
498 const qreal fDevicePixelRatio = gpManager->windowHandle() ? gpManager->windowHandle()->devicePixelRatio() : 1;
499 const QPixmap pinPixmap = pinIcon.pixmap(pinPixmapSize, fDevicePixelRatio);
500 /* Update linked values: */
501 if (m_pinPixmapSize != pinPixmapSize)
502 {
503 m_pinPixmapSize = pinPixmapSize;
504 updateGeometry();
505 }
506 if (m_pinPixmap.toImage() != pinPixmap.toImage())
507 {
508 m_pinPixmap = pinPixmap;
509 update();
510 }
511}
512
513void UIChooserItemGlobal::updateMinimumNameWidth()
514{
515 /* Calculate new minimum name width: */
516 QPaintDevice *pPaintDevice = model()->paintDevice();
517 const QFontMetrics fm(m_nameFont, pPaintDevice);
518#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
519 const int iMinimumNameWidth = fm.horizontalAdvance(compressText(m_nameFont, pPaintDevice, name(),
520 textWidth(m_nameFont, pPaintDevice, 15)));
521#else
522 const int iMinimumNameWidth = fm.width(compressText(m_nameFont, pPaintDevice, name(), textWidth(m_nameFont, pPaintDevice, 15)));
523#endif
524
525 /* Is there something changed? */
526 if (m_iMinimumNameWidth == iMinimumNameWidth)
527 return;
528
529 /* Update linked values: */
530 m_iMinimumNameWidth = iMinimumNameWidth;
531 updateGeometry();
532}
533
534void UIChooserItemGlobal::updateMaximumNameWidth()
535{
536 /* Prepare variables: */
537 const int iMarginHL = data(GlobalItemData_MarginHL).toInt();
538 const int iMarginHR = data(GlobalItemData_MarginHR).toInt();
539 const int iSpacing = data(GlobalItemData_Spacing).toInt();
540
541 /* Calculate new maximum name width: */
542 int iMaximumNameWidth = (int)geometry().width();
543 iMaximumNameWidth -= iMarginHL; /* left margin */
544 iMaximumNameWidth -= m_pixmapSize.width(); /* pixmap width */
545 iMaximumNameWidth -= iSpacing; /* spacing between pixmap and name */
546 iMaximumNameWidth -= iMarginHR; /* right margin */
547
548 /* Is there something changed? */
549 if (m_iMaximumNameWidth == iMaximumNameWidth)
550 return;
551
552 /* Update linked values: */
553 m_iMaximumNameWidth = iMaximumNameWidth;
554 updateVisibleName();
555}
556
557void UIChooserItemGlobal::updateVisibleName()
558{
559 /* Prepare variables: */
560 QPaintDevice *pPaintDevice = model()->paintDevice();
561
562 /* Calculate new visible name and name-size: */
563 const QString strVisibleName = compressText(m_nameFont, pPaintDevice, name(), m_iMaximumNameWidth);
564 const QSize visibleNameSize = textSize(m_nameFont, pPaintDevice, strVisibleName);
565
566 /* Update linked values: */
567 if (m_visibleNameSize != visibleNameSize)
568 {
569 m_visibleNameSize = visibleNameSize;
570 updateGeometry();
571 }
572 if (m_strVisibleName != strVisibleName)
573 {
574 m_strVisibleName = strVisibleName;
575 update();
576 }
577}
578
579void UIChooserItemGlobal::paintBackground(QPainter *pPainter, const QRect &rectangle)
580{
581 /* Save painter: */
582 pPainter->save();
583
584 /* Prepare color: */
585 const QPalette pal = QApplication::palette();
586
587 /* Selected-item background: */
588 if (model()->selectedItems().contains(this))
589 {
590 /* Prepare color: */
591 const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
592 /* Draw gradient: */
593 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
594 bgGrad.setColorAt(0, backgroundColor.lighter(m_iHighlightLightnessStart));
595 bgGrad.setColorAt(1, backgroundColor.lighter(m_iHighlightLightnessFinal));
596 pPainter->fillRect(rectangle, bgGrad);
597
598 if (isHovered())
599 {
600 /* Prepare color: */
601 QColor animationColor1 = QColor(Qt::white);
602 QColor animationColor2 = QColor(Qt::white);
603#ifdef VBOX_WS_MAC
604 animationColor1.setAlpha(90);
605#else
606 animationColor1.setAlpha(30);
607#endif
608 animationColor2.setAlpha(0);
609 /* Draw hovered-item animated gradient: */
610 QRect animatedRect = rectangle;
611 animatedRect.setWidth(animatedRect.height());
612 const int iLength = 2 * animatedRect.width() + rectangle.width();
613 const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
614 animatedRect.moveLeft(iShift);
615 QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
616 bgAnimatedGrad.setColorAt(0, animationColor2);
617 bgAnimatedGrad.setColorAt(0.1, animationColor2);
618 bgAnimatedGrad.setColorAt(0.5, animationColor1);
619 bgAnimatedGrad.setColorAt(0.9, animationColor2);
620 bgAnimatedGrad.setColorAt(1, animationColor2);
621 pPainter->fillRect(rectangle, bgAnimatedGrad);
622 }
623 }
624 /* Hovered-item background: */
625 else if (isHovered())
626 {
627 /* Prepare color: */
628 const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Highlight);
629 /* Draw gradient: */
630 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
631 bgGrad.setColorAt(0, backgroundColor.lighter(m_iHoverLightnessStart));
632 bgGrad.setColorAt(1, backgroundColor.lighter(m_iHoverLightnessFinal));
633 pPainter->fillRect(rectangle, bgGrad);
634
635 /* Prepare color: */
636 QColor animationColor1 = QColor(Qt::white);
637 QColor animationColor2 = QColor(Qt::white);
638#ifdef VBOX_WS_MAC
639 animationColor1.setAlpha(120);
640#else
641 animationColor1.setAlpha(50);
642#endif
643 animationColor2.setAlpha(0);
644 /* Draw hovered-item animated gradient: */
645 QRect animatedRect = rectangle;
646 animatedRect.setWidth(animatedRect.height());
647 const int iLength = 2 * animatedRect.width() + rectangle.width();
648 const int iShift = - animatedRect.width() + iLength * animatedValue() / 100;
649 animatedRect.moveLeft(iShift);
650 QLinearGradient bgAnimatedGrad(animatedRect.topLeft(), animatedRect.bottomRight());
651 bgAnimatedGrad.setColorAt(0, animationColor2);
652 bgAnimatedGrad.setColorAt(0.1, animationColor2);
653 bgAnimatedGrad.setColorAt(0.5, animationColor1);
654 bgAnimatedGrad.setColorAt(0.9, animationColor2);
655 bgAnimatedGrad.setColorAt(1, animationColor2);
656 pPainter->fillRect(rectangle, bgAnimatedGrad);
657 }
658 /* Default background: */
659 else
660 {
661#ifdef VBOX_WS_MAC
662 /* Prepare color: */
663 const QColor backgroundColor = pal.color(QPalette::Active, QPalette::Window);
664 /* Draw gradient: */
665 QLinearGradient bgGrad(rectangle.topLeft(), rectangle.bottomLeft());
666 bgGrad.setColorAt(0, backgroundColor.lighter(m_iDefaultColorDeviation));
667 bgGrad.setColorAt(1, backgroundColor.darker(m_iDefaultColorDeviation));
668 pPainter->fillRect(rectangle, bgGrad);
669#else
670 /* Draw simple background: */
671 pPainter->fillRect(rectangle, pal.color(QPalette::Active, QPalette::Window));
672#endif
673 }
674
675 /* Restore painter: */
676 pPainter->restore();
677}
678
679void UIChooserItemGlobal::paintFrame(QPainter *pPainter, const QRect &rectangle)
680{
681 /* Only selected and/or hovered item should have a frame: */
682 if (!model()->selectedItems().contains(this) && !isHovered())
683 return;
684
685 /* Save painter: */
686 pPainter->save();
687
688 /* Prepare color: */
689 const QPalette pal = QApplication::palette();
690 QColor strokeColor;
691
692 /* Selected-item frame: */
693 if (model()->selectedItems().contains(this))
694 strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHighlightLightnessStart - 40);
695 /* Hovered-item frame: */
696 else if (isHovered())
697 strokeColor = pal.color(QPalette::Active, QPalette::Highlight).lighter(m_iHoverLightnessStart - 40);
698
699 /* Create/assign pen: */
700 QPen pen(strokeColor);
701 pen.setWidth(0);
702 pPainter->setPen(pen);
703
704 /* Draw borders: */
705 pPainter->drawLine(rectangle.topLeft(), rectangle.topRight() + QPoint(1, 0));
706 pPainter->drawLine(rectangle.bottomLeft(), rectangle.bottomRight() + QPoint(1, 0));
707 pPainter->drawLine(rectangle.topLeft(), rectangle.bottomLeft());
708
709 /* Restore painter: */
710 pPainter->restore();
711}
712
713void UIChooserItemGlobal::paintGlobalInfo(QPainter *pPainter, const QRect &rectangle)
714{
715 /* Prepare variables: */
716 const int iFullWidth = rectangle.width();
717 const int iFullHeight = rectangle.height();
718 const int iMarginHL = data(GlobalItemData_MarginHL).toInt();
719 const int iMarginHR = data(GlobalItemData_MarginHR).toInt();
720 const int iSpacing = data(GlobalItemData_Spacing).toInt();
721 const int iButtonMargin = data(GlobalItemData_ButtonMargin).toInt();
722
723 /* Selected or hovered item foreground: */
724 if (model()->selectedItems().contains(this) || isHovered())
725 {
726 /* Prepare palette: */
727 const QPalette pal = QApplication::palette();
728
729 /* Get background color: */
730 const QColor highlight = pal.color(QPalette::Active, QPalette::Highlight);
731 const QColor background = model()->selectedItems().contains(this)
732 ? highlight.lighter(m_iHighlightLightnessStart)
733 : highlight.lighter(m_iHoverLightnessStart);
734
735 /* Gather foreground color for background one: */
736 const QColor foreground = suitableForegroundColor(pal, background);
737 pPainter->setPen(foreground);
738 }
739
740 /* Calculate indents: */
741 int iLeftColumnIndent = iMarginHL;
742
743 /* Paint left column: */
744 {
745 /* Prepare variables: */
746 const int iGlobalPixmapX = iLeftColumnIndent;
747 const int iGlobalPixmapY = (iFullHeight - m_pixmap.height() / m_pixmap.devicePixelRatio()) / 2;
748
749 /* Paint pixmap: */
750 paintPixmap(/* Painter: */
751 pPainter,
752 /* Point to paint in: */
753 QPoint(iGlobalPixmapX, iGlobalPixmapY),
754 /* Pixmap to paint: */
755 m_pixmap);
756 }
757
758 /* Calculate indents: */
759 const int iMiddleColumnIndent = iLeftColumnIndent +
760 m_pixmapSize.width() +
761 iSpacing;
762
763 /* Paint middle column: */
764 {
765 /* Prepare variables: */
766 const int iNameX = iMiddleColumnIndent;
767 const int iNameY = (iFullHeight - m_visibleNameSize.height()) / 2;
768
769 /* Paint name: */
770 paintText(/* Painter: */
771 pPainter,
772 /* Point to paint in: */
773 QPoint(iNameX, iNameY),
774 /* Font to paint text: */
775 m_nameFont,
776 /* Paint device: */
777 model()->paintDevice(),
778 /* Text to paint: */
779 m_strVisibleName);
780 }
781
782 /* Calculate indents: */
783 QGraphicsView *pView = model()->scene()->views().first();
784 const QPointF sceneCursorPosition = pView->mapToScene(pView->mapFromGlobal(QCursor::pos()));
785 const QPoint itemCursorPosition = mapFromScene(sceneCursorPosition).toPoint();
786 int iRightColumnIndent = iFullWidth - iMarginHR - 1 - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio();
787
788 /* Paint right column: */
789 if ( model()->firstSelectedItem() == this
790 || isHovered())
791 {
792 /* Prepare variables: */
793 const int iToolPixmapX = iRightColumnIndent;
794 const int iToolPixmapY = (iFullHeight - m_toolPixmap.height() / m_toolPixmap.devicePixelRatio()) / 2;
795 QRect toolButtonRectangle = QRect(iToolPixmapX,
796 iToolPixmapY,
797 m_toolPixmap.width() / m_toolPixmap.devicePixelRatio(),
798 m_toolPixmap.height() / m_toolPixmap.devicePixelRatio());
799 toolButtonRectangle.adjust(- iButtonMargin, -iButtonMargin, iButtonMargin, iButtonMargin);
800
801 /* Paint tool button: */
802 if ( isHovered()
803 && isToolButtonArea(itemCursorPosition, 4))
804 paintFlatButton(/* Painter: */
805 pPainter,
806 /* Button rectangle: */
807 toolButtonRectangle,
808 /* Cursor position: */
809 itemCursorPosition);
810
811 /* Paint pixmap: */
812 paintPixmap(/* Painter: */
813 pPainter,
814 /* Point to paint in: */
815 QPoint(iToolPixmapX, iToolPixmapY),
816 /* Pixmap to paint: */
817 m_toolPixmap);
818 }
819
820 /* Calculate indents: */
821 iRightColumnIndent = iRightColumnIndent - m_toolPixmap.width() / m_toolPixmap.devicePixelRatio() - iSpacing;
822
823 /* Paint right column: */
824 if ( model()->firstSelectedItem() == this
825 || isHovered())
826 {
827 /* Prepare variables: */
828 const int iPinPixmapX = iRightColumnIndent;
829 const int iPinPixmapY = (iFullHeight - m_pinPixmap.height() / m_pinPixmap.devicePixelRatio()) / 2;
830 QRect pinButtonRectangle = QRect(iPinPixmapX,
831 iPinPixmapY,
832 m_pinPixmap.width() / m_pinPixmap.devicePixelRatio(),
833 m_pinPixmap.height() / m_pinPixmap.devicePixelRatio());
834 pinButtonRectangle.adjust(- iButtonMargin, -iButtonMargin, iButtonMargin, iButtonMargin);
835
836 /* Paint pin button: */
837 if ( isHovered()
838 && isPinButtonArea(itemCursorPosition, 4))
839 paintFlatButton(/* Painter: */
840 pPainter,
841 /* Button rectangle: */
842 pinButtonRectangle,
843 /* Cursor position: */
844 itemCursorPosition);
845
846 /* Paint pixmap: */
847 paintPixmap(/* Painter: */
848 pPainter,
849 /* Point to paint in: */
850 QPoint(iPinPixmapX, iPinPixmapY),
851 /* Pixmap to paint: */
852 m_pinPixmap);
853 }
854}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use