1
/* $Id: UIPopupBox.cpp 30904 2010-07-19 09:43:24Z vboxsync $ */
4
* VBox frontends: Qt GUI ("VirtualBox"):
5
* UIPopupBox class implementation
9
* Copyright (C) 2010 Oracle Corporation
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.
21
#include "UIPopupBox.h"
23
# include "UIImageTools.h"
27
#include <QApplication>
29
#include <QPaintEvent>
31
#include <QVBoxLayout>
33
UIPopupBox::UIPopupBox(QWidget *pParent)
35
, m_fLinkEnabled(false)
40
, m_fHeaderHover(false)
42
QVBoxLayout *pMainLayout = new QVBoxLayout(this);
43
pMainLayout->setContentsMargins(10, 5, 5, 5);
44
QHBoxLayout *pTitleLayout = new QHBoxLayout();
45
m_pTitleIcon = new QLabel(this);
46
m_pTitleLabel = new QLabel(this);
47
connect(m_pTitleLabel, SIGNAL(linkActivated(const QString)),
48
this, SIGNAL(titleClicked(const QString)));
49
pTitleLayout->addWidget(m_pTitleIcon);
50
pTitleLayout->addWidget(m_pTitleLabel, Qt::AlignLeft);
51
pMainLayout->addLayout(pTitleLayout);
53
m_arrowPath.lineTo(m_aw / 2.0, m_aw / 2.0);
54
m_arrowPath.lineTo(m_aw, 0);
56
// setMouseTracking(true);
57
qApp->installEventFilter(this);
60
UIPopupBox::~UIPopupBox()
66
void UIPopupBox::setTitle(const QString& strTitle)
68
m_strTitle = strTitle;
73
QString UIPopupBox::title() const
78
void UIPopupBox::setTitleIcon(const QIcon& icon)
85
QIcon UIPopupBox::titleIcon() const
90
void UIPopupBox::setTitleLink(const QString& strLink)
95
QString UIPopupBox::titleLink() const
100
void UIPopupBox::setTitleLinkEnabled(bool fEnabled)
102
m_fLinkEnabled = fEnabled;
105
bool UIPopupBox::isTitleLinkEnabled() const
107
return m_fLinkEnabled;
110
void UIPopupBox::setContentWidget(QWidget *pWidget)
112
if (m_pContentWidget)
114
layout()->removeWidget(m_pContentWidget);
115
// m_pContentWidget->removeEventFilter(this);
117
m_pContentWidget = pWidget;
118
// m_pContentWidget->installEventFilter(this);
119
// m_pContentWidget->setMouseTracking(true);
120
layout()->addWidget(pWidget);
124
QWidget* UIPopupBox::contentWidget() const
126
return m_pContentWidget;
129
void UIPopupBox::setOpen(bool fOpen)
132
if (m_pContentWidget)
133
m_pContentWidget->setVisible(m_fOpen);
138
void UIPopupBox::toggleOpen()
143
bool UIPopupBox::isOpen() const
148
bool UIPopupBox::eventFilter(QObject * /* pWatched */, QEvent *pEvent)
150
QEvent::Type type = pEvent->type();
151
if ( type == QEvent::MouseMove
152
|| type == QEvent::Wheel
153
|| type == QEvent::Resize
154
|| type == QEvent::Enter
155
|| type == QEvent::Leave)
160
void UIPopupBox::resizeEvent(QResizeEvent *pEvent)
164
QWidget::resizeEvent(pEvent);
167
void UIPopupBox::mouseDoubleClickEvent(QMouseEvent * /* pEvent */)
172
void UIPopupBox::mouseMoveEvent(QMouseEvent *pEvent)
175
QWidget::mouseMoveEvent(pEvent);
178
void UIPopupBox::wheelEvent(QWheelEvent *pEvent)
181
QWidget::wheelEvent(pEvent);
184
void UIPopupBox::enterEvent(QEvent *pEvent)
187
QWidget::enterEvent(pEvent);
190
void UIPopupBox::leaveEvent(QEvent *pEvent)
193
QWidget::leaveEvent(pEvent);
196
void UIPopupBox::paintEvent(QPaintEvent *pEvent)
198
QPainter painter(this);
199
painter.setClipRect(pEvent->rect());
201
QPalette pal = palette();
202
painter.setClipPath(*m_pLabelPath);
203
QColor base = pal.color(QPalette::Active, QPalette::Window);
204
QRect rect = QRect(QPoint(0, 0), size()).adjusted(0, 0, -1, -1);
205
/* Base background */
206
painter.fillRect(QRect(QPoint(0, 0), size()), pal.brush(QPalette::Active, QPalette::Base));
207
/* Top header background */
208
QLinearGradient lg(rect.x(), rect.y(), rect.x(), rect.y() + 2 * 5 + m_pTitleLabel->sizeHint().height());
209
lg.setColorAt(0, base.darker(95));
210
lg.setColorAt(1, base.darker(110));
211
int theight = rect.height();
213
theight = 2 * 5 + m_pTitleLabel->sizeHint().height();
214
painter.fillRect(QRect(rect.x(), rect.y(), rect.width(), theight), lg);
215
/* Outer round rectangle line */
216
painter.setClipping(false);
217
painter.strokePath(*m_pLabelPath, base.darker(110));
221
painter.setBrush(base.darker(106));
222
painter.setPen(QPen(base.darker(128), 3, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
223
QSizeF s = m_arrowPath.boundingRect().size();
226
painter.translate(rect.x() + rect.width() - s.width() - 10, rect.y() + theight / 2 + s.height() / 2);
228
painter.scale(1, -1);
231
painter.translate(rect.x() + rect.width() - s.width() - 10, rect.y() + theight / 2 - s.height() / 2 + 1);
233
painter.setRenderHint(QPainter::Antialiasing);
234
painter.drawPath(m_arrowPath);
238
void UIPopupBox::updateHover(bool fForce /* = false */)
240
bool fOld = m_fHeaderHover;
241
QPoint bl = mapFromGlobal(QCursor::pos());
242
// printf("%d %d\n", bl.x(), bl.y());
244
&& m_pLabelPath->contains(mapFromGlobal(QCursor::pos())))
246
m_fHeaderHover = true;
248
m_fHeaderHover = false;
251
|| m_strLink.isEmpty())
253
m_pTitleLabel->setText(QString("<b>%1</b>").arg(m_strTitle));
256
|| fOld != m_fHeaderHover)
258
QPalette pal = m_pTitleLabel->palette();
259
m_pTitleLabel->setText(QString("<b><a style=\"text-decoration: none; color: %1\" href=\"%2\">%3</a></b>")
260
.arg(m_fHeaderHover ? pal.color(QPalette::Link).name() : pal.color(QPalette::WindowText).name())
264
QPixmap i = m_icon.pixmap(16, 16);
267
// if (!m_fHeaderHover)
268
// i = QPixmap::fromImage(toGray(i.toImage()));
269
#endif /* Q_WS_MAC */
270
m_pTitleIcon->setPixmap(i);
275
void UIPopupBox::recalc()
279
QRect rect = QRect(QPoint(0, 0), size()).adjusted(0, 0, -1, -1);
281
m_pLabelPath = new QPainterPath(QPointF(rect.x() + rect.width() - d, rect.y()));
282
m_pLabelPath->arcTo(QRectF(rect.x(), rect.y(), d, d), 90, 90);
283
m_pLabelPath->arcTo(QRectF(rect.x(), rect.y() + rect.height() - d, d, d), 180, 90);
284
m_pLabelPath->arcTo(QRectF(rect.x() + rect.width() - d, rect.y() + rect.height() - d, d, d), 270, 90);
285
m_pLabelPath->arcTo(QRectF(rect.x() + rect.width() - d, rect.y(), d, d), 0, 90);
286
m_pLabelPath->closeSubpath();