VirtualBox

Changeset 46195 in vbox for trunk/src


Ignore:
Timestamp:
May 21, 2013 2:59:54 PM (12 years ago)
Author:
vboxsync
Message:

FE/Qt: Move animation frame-work name-space into separate corresponding files.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r46058 r46195  
    509509        src/globals/COMDefs.cpp \
    510510        src/globals/UIActionPool.cpp \
     511        src/globals/UIAnimationFramework.cpp \
    511512        src/globals/UIExtraDataEventHandler.cpp \
    512513        src/globals/UIIconPool.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIAnimationFramework.cpp

    r46193 r46195  
    33 *
    44 * VBox frontends: Qt GUI ("VirtualBox"):
    5  * UIPopupPane class implementation
     5 * UIAnimationFramework class implementation
    66 */
    77
     
    1919
    2020/* Qt includes: */
    21 #include <QHBoxLayout>
    22 #include <QVBoxLayout>
    23 #include <QLabel>
    24 #include <QCheckBox>
    25 #include <QKeyEvent>
    26 #include <QPainter>
     21#include <QWidget>
    2722#include <QStateMachine>
    2823#include <QPropertyAnimation>
     
    3025
    3126/* GUI includes: */
    32 #include "QIWithRetranslateUI.h"
    33 #include "UIPopupPane.h"
    34 #include "UIIconPool.h"
    35 #include "QIToolButton.h"
    36 
    37 /* Other VBox includes: */
    38 #include <VBox/sup.h>
    39 
     27#include "UIAnimationFramework.h"
    4028
    4129QStateMachine* UIAnimationFramework::installPropertyAnimation(QWidget *pTarget, const char *pszPropertyName,
     
    7866}
    7967
    80 
    81 /* Popup-pane text-pane prototype class: */
    82 class UIPopupPaneTextPane : public QIWithRetranslateUI<QWidget>
    83 {
    84     Q_OBJECT;
    85     Q_PROPERTY(QSize collapsedSizeHint READ collapsedSizeHint);
    86     Q_PROPERTY(QSize expandedSizeHint READ expandedSizeHint);
    87     Q_PROPERTY(QSize minimumSizeHint READ minimumSizeHint WRITE setMinimumSizeHint);
    88 
    89 signals:
    90 
    91     /* Notifiers: Parent propagation stuff: */
    92     void sigFocusEnter();
    93     void sigFocusLeave();
    94 
    95     /* Notifier: Layout stuff: */
    96     void sigSizeHintChanged();
    97 
    98 public:
    99 
    100     /* Constructor: */
    101     UIPopupPaneTextPane(QWidget *pParent = 0);
    102 
    103     /* API: Text stuff: */
    104     void setText(const QString &strText);
    105 
    106     /* API: Desired-width stuff: */
    107     void setDesiredWidth(int iDesiredWidth);
    108 
    109     /* API: Auto-confirmation stuff: */
    110     void setProposeAutoConfirmation(bool fPropose);
    111     bool autoConfirmationProposed() const;
    112     bool isAutoConfirmed() const;
    113 
    114     /* API: Layout stuff: */
    115     QSize minimumSizeHint() const;
    116     void setMinimumSizeHint(const QSize &minimumSizeHint);
    117     void layoutContent();
    118 
    119 private slots:
    120 
    121     /* Handlers: Focus stuff: */
    122     void sltFocusEnter();
    123     void sltFocusLeave();
    124 
    125 private:
    126 
    127     /* Helpers: Prepare stuff: */
    128     void prepare();
    129     void prepareContent();
    130 
    131     /* Helper: Translate stuff: */
    132     void retranslateUi();
    133 
    134     /* Helper: Layout stuff: */
    135     void updateSizeHint();
    136 
    137     /* Property: Focus stuff: */
    138     QSize collapsedSizeHint() const { return m_collapsedSizeHint; }
    139     QSize expandedSizeHint() const { return m_expandedSizeHint; }
    140 
    141     /* Variables: Layout stuff: */
    142     const int m_iLayoutMargin;
    143     const int m_iLayoutSpacing;
    144     QSize m_labelSizeHint;
    145     QSize m_checkBoxSizeHint;
    146     QSize m_collapsedSizeHint;
    147     QSize m_expandedSizeHint;
    148     QSize m_minimumSizeHint;
    149 
    150     /* Variables: Widget stuff: */
    151     QLabel *m_pLabel;
    152     int m_iDesiredLabelWidth;
    153     QCheckBox *m_pAutoConfirmCheckBox;
    154     bool m_fProposeAutoConfirmation;
    155 
    156     /* Variables: Focus stuff: */
    157     bool m_fFocused;
    158     QObject *m_pAnimation;
    159 };
    160 
    161 
    162 /* Popup-pane button-pane prototype class: */
    163 class UIPopupPaneButtonPane : public QWidget
    164 {
    165     Q_OBJECT;
    166 
    167 signals:
    168 
    169     /* Notifier: Button stuff: */
    170     void sigButtonClicked(int iButtonID);
    171 
    172 public:
    173 
    174     /* Constructor: */
    175     UIPopupPaneButtonPane(QWidget *pParent = 0);
    176 
    177     /* API: Button stuff: */
    178     void setButtons(const QMap<int, QString> &buttonDescriptions);
    179 
    180 private slots:
    181 
    182     /* Handler: Button stuff: */
    183     void sltButtonClicked();
    184 
    185 private:
    186 
    187     /* Helpers: Prepare/cleanup stuff: */
    188     void prepare();
    189     void prepareLayouts();
    190     void prepareButtons();
    191     void cleanupButtons();
    192 
    193     /* Handler: Event stuff: */
    194     void keyPressEvent(QKeyEvent *pEvent);
    195 
    196     /* Static helpers: Button stuff: */
    197     static QIToolButton* addButton(int iButtonID, const QString &strToolTip);
    198     static QString defaultToolTip(int iButtonID);
    199     static QIcon defaultIcon(int iButtonID);
    200 
    201     /* Variables: Widget stuff: */
    202     QHBoxLayout *m_pButtonLayout;
    203     QMap<int, QString> m_buttonDescriptions;
    204     QMap<int, QIToolButton*> m_buttons;
    205     int m_iDefaultButton;
    206     int m_iEscapeButton;
    207 };
    208 
    209 
    210 UIPopupPane::UIPopupPane(QWidget *pParent,
    211                          const QString &strMessage, const QString &strDetails,
    212                          const QMap<int, QString> &buttonDescriptions,
    213                          bool fProposeAutoConfirmation)
    214     : QWidget(pParent)
    215     , m_iLayoutMargin(10), m_iLayoutSpacing(5)
    216     , m_strMessage(strMessage), m_strDetails(strDetails)
    217     , m_fProposeAutoConfirmation(fProposeAutoConfirmation)
    218     , m_buttonDescriptions(buttonDescriptions)
    219     , m_fHovered(false)
    220     , m_iDefaultOpacity(128)
    221     , m_iHoveredOpacity(230)
    222     , m_iOpacity(m_iDefaultOpacity)
    223     , m_fFocused(false)
    224     , m_pTextPane(0), m_pButtonPane(0)
    225 {
    226     /* Prepare: */
    227     prepare();
    228 }
    229 
    230 void UIPopupPane::setMessage(const QString &strMessage)
    231 {
    232     /* Make sure somthing changed: */
    233     if (m_strMessage == strMessage)
    234         return;
    235 
    236     /* Fetch new message: */
    237     m_strMessage = strMessage;
    238     m_pTextPane->setText(m_strMessage);
    239 }
    240 
    241 void UIPopupPane::setDetails(const QString &strDetails)
    242 {
    243     /* Make sure somthing changed: */
    244     if (m_strDetails == strDetails)
    245         return;
    246 
    247     /* Fetch new details: */
    248     m_strDetails = strDetails;
    249 }
    250 
    251 void UIPopupPane::setProposeAutoConfirmation(bool fPropose)
    252 {
    253     /* Make sure something changed: */
    254     if (m_fProposeAutoConfirmation == fPropose)
    255         return;
    256 
    257     /* Fetch new auto-confirmation proposal: */
    258     m_fProposeAutoConfirmation = fPropose;
    259     m_pTextPane->setProposeAutoConfirmation(m_fProposeAutoConfirmation);
    260 }
    261 
    262 void UIPopupPane::setDesiredWidth(int iWidth)
    263 {
    264     /* Make sure text-pane exists: */
    265     if (!m_pTextPane)
    266         return;
    267 
    268     /* Propagate desired width to the text-pane we have: */
    269     m_pTextPane->setDesiredWidth(iWidth - 2 * m_iLayoutMargin
    270                                         - m_pButtonPane->minimumSizeHint().width());
    271 }
    272 
    273 int UIPopupPane::minimumWidthHint() const
    274 {
    275     /* Prepare width hint: */
    276     int iWidthHint = 0;
    277 
    278     /* Take into account layout: */
    279     iWidthHint += 2 * m_iLayoutMargin;
    280     {
    281         /* Take into account widgets: */
    282         iWidthHint += m_pTextPane->minimumSizeHint().width();
    283         iWidthHint += m_iLayoutSpacing;
    284         iWidthHint += m_pButtonPane->minimumSizeHint().width();
    285     }
    286 
    287     /* Return width hint: */
    288     return iWidthHint;
    289 }
    290 
    291 int UIPopupPane::minimumHeightHint() const
    292 {
    293     /* Prepare height hint: */
    294     int iHeightHint = 0;
    295 
    296     /* Take into account layout: */
    297     iHeightHint += 2 * m_iLayoutMargin;
    298     {
    299         /* Take into account widgets: */
    300         const int iTextPaneHeight = m_pTextPane->minimumSizeHint().height();
    301         const int iButtonBoxHeight = m_pButtonPane->minimumSizeHint().height();
    302         iHeightHint += qMax(iTextPaneHeight, iButtonBoxHeight);
    303     }
    304 
    305     /* Return height hint: */
    306     return iHeightHint;
    307 }
    308 
    309 QSize UIPopupPane::minimumSizeHint() const
    310 {
    311     /* Wrap reimplemented getters: */
    312     return QSize(minimumWidthHint(), minimumHeightHint());
    313 }
    314 
    315 void UIPopupPane::layoutContent()
    316 {
    317     /* Variables: */
    318     const int iWidth = width();
    319     const int iHeight = height();
    320     const QSize buttonPaneMinimumSizeHint = m_pButtonPane->minimumSizeHint();
    321     const int iButtonPaneMinimumWidth = buttonPaneMinimumSizeHint.width();
    322     const int iButtonPaneMinimumHeight = buttonPaneMinimumSizeHint.height();
    323     const int iTextPaneWidth = iWidth - 2 * m_iLayoutMargin - m_iLayoutSpacing - iButtonPaneMinimumWidth;
    324     const int iTextPaneHeight = m_pTextPane->minimumSizeHint().height();
    325     const int iMaximumHeight = qMax(iTextPaneHeight, iButtonPaneMinimumHeight);
    326     const int iMinimumHeight = qMin(iTextPaneHeight, iButtonPaneMinimumHeight);
    327     const int iHeightShift = (iMaximumHeight - iMinimumHeight) / 2;
    328     const bool fTextPaneShifted = iTextPaneHeight < iButtonPaneMinimumHeight;
    329 
    330     /* Text-pane: */
    331     m_pTextPane->move(m_iLayoutMargin,
    332                       fTextPaneShifted ? m_iLayoutMargin + iHeightShift : m_iLayoutMargin);
    333     m_pTextPane->resize(iTextPaneWidth,
    334                         iTextPaneHeight);
    335     m_pTextPane->layoutContent();
    336     /* Button-box: */
    337     m_pButtonPane->move(m_iLayoutMargin + iTextPaneWidth + m_iLayoutSpacing,
    338                         m_iLayoutMargin);
    339     m_pButtonPane->resize(iButtonPaneMinimumWidth,
    340                           iHeight - 2 * m_iLayoutMargin);
    341 }
    342 
    343 void UIPopupPane::sltButtonClicked(int iButtonID)
    344 {
    345     done(iButtonID & AlertButtonMask);
    346 }
    347 
    348 void UIPopupPane::prepare()
    349 {
    350     /* Install 'hover' animation for 'opacity' property: */
    351     UIAnimationFramework::installPropertyAnimation(this, "opacity", "defaultOpacity", "hoveredOpacity",
    352                                                    SIGNAL(sigHoverEnter()), SIGNAL(sigHoverLeave()));
    353     /* Prepare content: */
    354     prepareContent();
    355 }
    356 
    357 void UIPopupPane::prepareContent()
    358 {
    359     /* Prepare this: */
    360     installEventFilter(this);
    361     /* Create message-label: */
    362     m_pTextPane = new UIPopupPaneTextPane(this);
    363     {
    364         /* Prepare label: */
    365         connect(m_pTextPane, SIGNAL(sigSizeHintChanged()),
    366                 this, SIGNAL(sigSizeHintChanged()));
    367         m_pTextPane->installEventFilter(this);
    368         m_pTextPane->setText(m_strMessage);
    369         m_pTextPane->setProposeAutoConfirmation(m_fProposeAutoConfirmation);
    370     }
    371     /* Create button-box: */
    372     m_pButtonPane = new UIPopupPaneButtonPane(this);
    373     {
    374         /* Prepare button-box: */
    375         connect(m_pButtonPane, SIGNAL(sigButtonClicked(int)),
    376                 this, SLOT(sltButtonClicked(int)));
    377         m_pButtonPane->installEventFilter(this);
    378         m_pButtonPane->setButtons(m_buttonDescriptions);
    379     }
    380 
    381     /* Prepare focus rules: */
    382     setFocusPolicy(Qt::StrongFocus);
    383     m_pTextPane->setFocusPolicy(Qt::StrongFocus);
    384     m_pButtonPane->setFocusPolicy(Qt::StrongFocus);
    385     setFocusProxy(m_pButtonPane);
    386     m_pTextPane->setFocusProxy(m_pButtonPane);
    387 }
    388 
    389 bool UIPopupPane::eventFilter(QObject *pWatched, QEvent *pEvent)
    390 {
    391     /* Depending on event-type: */
    392     switch (pEvent->type())
    393     {
    394         /* Something is hovered: */
    395         case QEvent::HoverEnter:
    396         case QEvent::Enter:
    397         {
    398             if (!m_fHovered)
    399             {
    400                 m_fHovered = true;
    401                 emit sigHoverEnter();
    402             }
    403             break;
    404         }
    405         /* Nothing is hovered: */
    406         case QEvent::Leave:
    407         {
    408             if (pWatched == this && m_fHovered)
    409             {
    410                 m_fHovered = false;
    411                 emit sigHoverLeave();
    412             }
    413             break;
    414         }
    415         case QEvent::FocusIn:
    416         {
    417             if (!m_fFocused)
    418             {
    419                 m_fFocused = true;
    420                 emit sigFocusEnter();
    421             }
    422             break;
    423         }
    424         case QEvent::FocusOut:
    425         {
    426             if (m_fFocused)
    427             {
    428                 m_fFocused = false;
    429                 emit sigFocusLeave();
    430             }
    431             break;
    432         }
    433         /* Default case: */
    434         default: break;
    435     }
    436     /* Do not filter anything: */
    437     return false;
    438 }
    439 
    440 void UIPopupPane::paintEvent(QPaintEvent*)
    441 {
    442     /* Compose painting rectangle: */
    443     const QRect rect(0, 0, width(), height());
    444 
    445     /* Create painter: */
    446     QPainter painter(this);
    447     painter.setRenderHint(QPainter::Antialiasing);
    448 
    449     /* Configure painter clipping: */
    450     QPainterPath path;
    451     int iDiameter = 6;
    452     QSizeF arcSize(2 * iDiameter, 2 * iDiameter);
    453     path.moveTo(iDiameter, 0);
    454     path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-iDiameter, 0), 90, 90);
    455     path.lineTo(path.currentPosition().x(), rect.height() - iDiameter);
    456     path.arcTo(QRectF(path.currentPosition(), arcSize).translated(0, -iDiameter), 180, 90);
    457     path.lineTo(rect.width() - iDiameter, path.currentPosition().y());
    458     path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-iDiameter, -2 * iDiameter), 270, 90);
    459     path.lineTo(path.currentPosition().x(), iDiameter);
    460     path.arcTo(QRectF(path.currentPosition(), arcSize).translated(-2 * iDiameter, -iDiameter), 0, 90);
    461     path.closeSubpath();
    462     painter.setClipPath(path);
    463 
    464     /* Fill with background: */
    465     QColor currentColor(palette().color(QPalette::Window));
    466     QColor newColor1(currentColor.red(), currentColor.green(), currentColor.blue(), opacity());
    467     QColor newColor2 = newColor1.darker(115);
    468     QLinearGradient headerGradient(rect.topLeft(), rect.topRight());
    469     headerGradient.setColorAt(0, newColor1);
    470     headerGradient.setColorAt(1, newColor2);
    471     painter.fillRect(rect, headerGradient);
    472 }
    473 
    474 void UIPopupPane::done(int iResultCode)
    475 {
    476     /* Close the window: */
    477     close();
    478 
    479     /* Was the popup auto-confirmed? */
    480     if (m_pTextPane->isAutoConfirmed())
    481         iResultCode |= AlertOption_AutoConfirmed;
    482 
    483     /* Notify listeners: */
    484     emit sigDone(iResultCode);
    485 }
    486 
    487 
    488 UIPopupPaneTextPane::UIPopupPaneTextPane(QWidget *pParent /*= 0*/)
    489     : QIWithRetranslateUI<QWidget>(pParent)
    490     , m_iLayoutMargin(0)
    491     , m_iLayoutSpacing(10)
    492     , m_pLabel(0)
    493     , m_iDesiredLabelWidth(-1)
    494     , m_pAutoConfirmCheckBox(0)
    495     , m_fProposeAutoConfirmation(false)
    496     , m_fFocused(false)
    497     , m_pAnimation(0)
    498 {
    499     /* Prepare: */
    500     prepare();
    501 }
    502 
    503 void UIPopupPaneTextPane::setText(const QString &strText)
    504 {
    505     /* Make sure the text is changed: */
    506     if (m_pLabel->text() == strText)
    507         return;
    508     /* Update the pane for the new text: */
    509     m_pLabel->setText(strText);
    510     updateSizeHint();
    511 }
    512 
    513 void UIPopupPaneTextPane::setDesiredWidth(int iDesiredWidth)
    514 {
    515     /* Make sure the desired-width is changed: */
    516     if (m_iDesiredLabelWidth == iDesiredWidth)
    517         return;
    518     /* Update the pane for the new desired-width: */
    519     m_iDesiredLabelWidth = iDesiredWidth;
    520     updateSizeHint();
    521 }
    522 
    523 void UIPopupPaneTextPane::setProposeAutoConfirmation(bool fPropose)
    524 {
    525     /* Make sure the auto-confirmation-proposal is changed: */
    526     if (m_fProposeAutoConfirmation == fPropose)
    527         return;
    528     /* Update the pane for the new auto-confirmation-proposal: */
    529     m_fProposeAutoConfirmation = fPropose;
    530     updateSizeHint();
    531 }
    532 
    533 bool UIPopupPaneTextPane::autoConfirmationProposed() const
    534 {
    535     return m_fProposeAutoConfirmation;
    536 }
    537 
    538 bool UIPopupPaneTextPane::isAutoConfirmed() const
    539 {
    540     return autoConfirmationProposed() &&
    541            m_pAutoConfirmCheckBox &&
    542            m_pAutoConfirmCheckBox->isChecked();
    543 }
    544 
    545 QSize UIPopupPaneTextPane::minimumSizeHint() const
    546 {
    547     /* Check if desired-width set: */
    548     if (m_iDesiredLabelWidth >= 0)
    549         /* Dependent size-hint: */
    550         return m_minimumSizeHint;
    551     /* Golden-rule size-hint by default: */
    552     return QWidget::minimumSizeHint();
    553 }
    554 
    555 void UIPopupPaneTextPane::setMinimumSizeHint(const QSize &minimumSizeHint)
    556 {
    557     /* Make sure the size-hint is changed: */
    558     if (m_minimumSizeHint == minimumSizeHint)
    559         return;
    560     /* Assign new size-hint: */
    561     m_minimumSizeHint = minimumSizeHint;
    562     /* Notify parent popup-pane: */
    563     emit sigSizeHintChanged();
    564 }
    565 
    566 void UIPopupPaneTextPane::layoutContent()
    567 {
    568     /* Variables: */
    569     const int iWidth = width();
    570     const int iHeight = height();
    571     const int iLabelWidth = m_labelSizeHint.width();
    572     const int iLabelHeight = m_labelSizeHint.height();
    573     /* Label: */
    574     m_pLabel->move(m_iLayoutMargin, m_iLayoutMargin);
    575     m_pLabel->resize(qMin(iWidth, iLabelWidth), qMin(iHeight, iLabelHeight));
    576 
    577     /* Check-box: */
    578     if (m_fProposeAutoConfirmation)
    579     {
    580         /* Variables: */
    581         const int iCheckBoxWidth = m_checkBoxSizeHint.width();
    582         const int iCheckBoxHeight = m_checkBoxSizeHint.height();
    583         const int iCheckBoxY = m_iLayoutMargin + iLabelHeight + m_iLayoutSpacing;
    584         /* Layout check-box: */
    585         if (iHeight - m_iLayoutMargin - iCheckBoxHeight - iCheckBoxY >= 0)
    586         {
    587             m_pAutoConfirmCheckBox->move(m_iLayoutMargin, iCheckBoxY);
    588             m_pAutoConfirmCheckBox->resize(iCheckBoxWidth, iCheckBoxHeight);
    589             if (m_pAutoConfirmCheckBox->isHidden())
    590                 m_pAutoConfirmCheckBox->show();
    591         }
    592         else if (!m_pAutoConfirmCheckBox->isHidden())
    593             m_pAutoConfirmCheckBox->hide();
    594     }
    595     else if (!m_pAutoConfirmCheckBox->isHidden())
    596         m_pAutoConfirmCheckBox->hide();
    597 }
    598 
    599 void UIPopupPaneTextPane::sltFocusEnter()
    600 {
    601     /* Ignore if already focused: */
    602     if (m_fFocused)
    603         return;
    604 
    605     /* Update focus state: */
    606     m_fFocused = true;
    607 
    608     /* Notify listeners: */
    609     emit sigFocusEnter();
    610 }
    611 
    612 void UIPopupPaneTextPane::sltFocusLeave()
    613 {
    614     /* Ignore if already unfocused: */
    615     if (!m_fFocused)
    616         return;
    617 
    618     /* Update focus state: */
    619     m_fFocused = false;
    620 
    621     /* Notify listeners: */
    622     emit sigFocusLeave();
    623 }
    624 
    625 void UIPopupPaneTextPane::prepare()
    626 {
    627     /* Propagate parent signals: */
    628     connect(parent(), SIGNAL(sigFocusEnter()), this, SLOT(sltFocusEnter()));
    629     connect(parent(), SIGNAL(sigFocusLeave()), this, SLOT(sltFocusLeave()));
    630     /* Prepare content: */
    631     prepareContent();
    632 }
    633 
    634 void UIPopupPaneTextPane::prepareContent()
    635 {
    636     /* Create label: */
    637     m_pLabel = new QLabel(this);
    638     {
    639         /* Prepare label: */
    640         QFont currentFont = m_pLabel->font();
    641 #ifdef Q_WS_MAC
    642         currentFont.setPointSize(currentFont.pointSize() - 2);
    643 #else /* Q_WS_MAC */
    644         currentFont.setPointSize(currentFont.pointSize() - 1);
    645 #endif /* !Q_WS_MAC */
    646         m_pLabel->setFont(currentFont);
    647         m_pLabel->setWordWrap(true);
    648         m_pLabel->setFocusPolicy(Qt::NoFocus);
    649     }
    650     /* Create check-box: */
    651     m_pAutoConfirmCheckBox = new QCheckBox(this);
    652     {
    653         /* Prepare check-box: */
    654         QFont currentFont = m_pAutoConfirmCheckBox->font();
    655 #ifdef Q_WS_MAC
    656         currentFont.setPointSize(currentFont.pointSize() - 2);
    657 #else /* Q_WS_MAC */
    658         currentFont.setPointSize(currentFont.pointSize() - 1);
    659 #endif /* !Q_WS_MAC */
    660         m_pAutoConfirmCheckBox->setFont(currentFont);
    661         m_pAutoConfirmCheckBox->setFocusPolicy(Qt::NoFocus);
    662     }
    663     /* Translate UI finally: */
    664     retranslateUi();
    665 }
    666 
    667 void UIPopupPaneTextPane::retranslateUi()
    668 {
    669     /* Translate auto-confirm check-box: */
    670     m_pAutoConfirmCheckBox->setText(QApplication::translate("UIMessageCenter", "Do not show this message again"));
    671 }
    672 
    673 void UIPopupPaneTextPane::updateSizeHint()
    674 {
    675     /* Recalculate collapsed size-hint: */
    676     {
    677         /* Collapsed size-hint contains only one-text-line label: */
    678         QFontMetrics fm(m_pLabel->font(), m_pLabel);
    679         m_collapsedSizeHint = QSize(m_iDesiredLabelWidth, fm.height());
    680     }
    681 
    682     /* Recalculate expanded size-hint: */
    683     {
    684         /* Recalculate label size-hint: */
    685         m_labelSizeHint = QSize(m_iDesiredLabelWidth, m_pLabel->heightForWidth(m_iDesiredLabelWidth));
    686         /* Recalculate check-box size-hint: */
    687         m_checkBoxSizeHint = m_fProposeAutoConfirmation ? m_pAutoConfirmCheckBox->sizeHint() : QSize();
    688         /* Expanded size-hint contains full-size label: */
    689         m_expandedSizeHint = m_labelSizeHint;
    690         /* Expanded size-hint can contain check-box: */
    691         if (m_checkBoxSizeHint.isValid())
    692         {
    693             m_expandedSizeHint.setWidth(qMax(m_expandedSizeHint.width(), m_checkBoxSizeHint.width()));
    694             m_expandedSizeHint.setHeight(m_expandedSizeHint.height() + m_iLayoutSpacing + m_checkBoxSizeHint.height());
    695         }
    696     }
    697 
    698     /* Update current size-hint: */
    699     m_minimumSizeHint = m_fFocused ? m_expandedSizeHint : m_collapsedSizeHint;
    700 
    701     /* And reinstall size-hint animation: */
    702     delete m_pAnimation;
    703     m_pAnimation = UIAnimationFramework::installPropertyAnimation(this, "minimumSizeHint", "collapsedSizeHint", "expandedSizeHint",
    704                                                                   SIGNAL(sigFocusEnter()), SIGNAL(sigFocusLeave()),
    705                                                                   m_fFocused);
    706 }
    707 
    708 
    709 UIPopupPaneButtonPane::UIPopupPaneButtonPane(QWidget *pParent /*= 0*/)
    710     : QWidget(pParent)
    711     , m_iDefaultButton(0)
    712     , m_iEscapeButton(0)
    713 {
    714     /* Prepare: */
    715     prepare();
    716 }
    717 
    718 void UIPopupPaneButtonPane::setButtons(const QMap<int, QString> &buttonDescriptions)
    719 {
    720     /* Make sure something changed: */
    721     if (m_buttonDescriptions == buttonDescriptions)
    722         return;
    723 
    724     /* Assign new button-descriptions: */
    725     m_buttonDescriptions = buttonDescriptions;
    726     /* Recreate buttons: */
    727     cleanupButtons();
    728     prepareButtons();
    729 }
    730 
    731 void UIPopupPaneButtonPane::sltButtonClicked()
    732 {
    733     /* Make sure the slot is called by the button: */
    734     QIToolButton *pButton = qobject_cast<QIToolButton*>(sender());
    735     if (!pButton)
    736         return;
    737 
    738     /* Make sure we still have that button: */
    739     int iButtonID = m_buttons.key(pButton, 0);
    740     if (!iButtonID)
    741         return;
    742 
    743     /* Notify listeners button was clicked: */
    744     emit sigButtonClicked(iButtonID);
    745 }
    746 
    747 void UIPopupPaneButtonPane::prepare()
    748 {
    749     /* Prepare layouts: */
    750     prepareLayouts();
    751 }
    752 
    753 void UIPopupPaneButtonPane::prepareLayouts()
    754 {
    755     /* Create layouts: */
    756     m_pButtonLayout = new QHBoxLayout;
    757     m_pButtonLayout->setContentsMargins(0, 0, 0, 0);
    758     m_pButtonLayout->setSpacing(0);
    759     QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    760     pMainLayout->setContentsMargins(0, 0, 0, 0);
    761     pMainLayout->setSpacing(0);
    762     pMainLayout->addLayout(m_pButtonLayout);
    763     pMainLayout->addStretch();
    764 }
    765 
    766 void UIPopupPaneButtonPane::prepareButtons()
    767 {
    768     /* Add all the buttons: */
    769     const QList<int> &buttonsIDs = m_buttonDescriptions.keys();
    770     foreach (int iButtonID, buttonsIDs)
    771         if (QIToolButton *pButton = addButton(iButtonID, m_buttonDescriptions[iButtonID]))
    772         {
    773             m_pButtonLayout->addWidget(pButton);
    774             m_buttons[iButtonID] = pButton;
    775             connect(pButton, SIGNAL(clicked(bool)), this, SLOT(sltButtonClicked()));
    776             if (pButton->property("default").toBool())
    777                 m_iDefaultButton = iButtonID;
    778             if (pButton->property("escape").toBool())
    779                 m_iEscapeButton = iButtonID;
    780         }
    781 }
    782 
    783 void UIPopupPaneButtonPane::cleanupButtons()
    784 {
    785     /* Remove all the buttons: */
    786     const QList<int> &buttonsIDs = m_buttons.keys();
    787     foreach (int iButtonID, buttonsIDs)
    788     {
    789         delete m_buttons[iButtonID];
    790         m_buttons.remove(iButtonID);
    791     }
    792 }
    793 
    794 void UIPopupPaneButtonPane::keyPressEvent(QKeyEvent *pEvent)
    795 {
    796     /* Depending on pressed key: */
    797     switch (pEvent->key())
    798     {
    799         case Qt::Key_Enter:
    800         case Qt::Key_Return:
    801         {
    802             if (m_iDefaultButton)
    803             {
    804                 pEvent->accept();
    805                 emit sigButtonClicked(m_iDefaultButton);
    806                 return;
    807             }
    808             break;
    809         }
    810         case Qt::Key_Escape:
    811         {
    812             if (m_iEscapeButton)
    813             {
    814                 pEvent->accept();
    815                 emit sigButtonClicked(m_iEscapeButton);
    816                 return;
    817             }
    818             break;
    819         }
    820         default:
    821             break;
    822     }
    823     /* Call to base-class: */
    824     QWidget::keyPressEvent(pEvent);
    825 }
    826 
    827 /* static */
    828 QIToolButton* UIPopupPaneButtonPane::addButton(int iButtonID, const QString &strToolTip)
    829 {
    830     /* Create button: */
    831     QIToolButton *pButton = new QIToolButton;
    832     pButton->removeBorder();
    833     pButton->setToolTip(strToolTip.isEmpty() ? defaultToolTip(iButtonID) : strToolTip);
    834     pButton->setIcon(defaultIcon(iButtonID));
    835 
    836     /* Sign the 'default' button: */
    837     if (iButtonID & AlertButtonOption_Default)
    838         pButton->setProperty("default", true);
    839     /* Sign the 'escape' button: */
    840     if (iButtonID & AlertButtonOption_Escape)
    841         pButton->setProperty("escape", true);
    842 
    843     /* Return button: */
    844     return pButton;
    845 }
    846 
    847 /* static */
    848 QString UIPopupPaneButtonPane::defaultToolTip(int iButtonID)
    849 {
    850     QString strToolTip;
    851     switch (iButtonID & AlertButtonMask)
    852     {
    853         case AlertButton_Ok:      strToolTip = QIMessageBox::tr("OK");     break;
    854         case AlertButton_Cancel:  strToolTip = QIMessageBox::tr("Cancel"); break;
    855         case AlertButton_Choice1: strToolTip = QIMessageBox::tr("Yes");    break;
    856         case AlertButton_Choice2: strToolTip = QIMessageBox::tr("No");     break;
    857         default:                  strToolTip = QString();                  break;
    858     }
    859     return strToolTip;
    860 }
    861 
    862 /* static */
    863 QIcon UIPopupPaneButtonPane::defaultIcon(int iButtonID)
    864 {
    865     QIcon icon;
    866     switch (iButtonID & AlertButtonMask)
    867     {
    868         case AlertButton_Ok:      icon = UIIconPool::iconSet(":/ok_16px.png");     break;
    869         case AlertButton_Cancel:  icon = UIIconPool::iconSet(":/cancel_16px.png"); break;
    870         case AlertButton_Choice1: break;
    871         case AlertButton_Choice2: break;
    872         default:                  break;
    873     }
    874     return icon;
    875 }
    876 
    877 #include "UIPopupPane.moc"
    878 
  • trunk/src/VBox/Frontends/VirtualBox/src/globals/UIAnimationFramework.h

    r46193 r46195  
    22 *
    33 * VBox frontends: Qt GUI ("VirtualBox"):
    4  * UIPopupPane class declaration
     4 * UIAnimationFramework class declaration
    55 */
    66
     
    1717 */
    1818
    19 #ifndef __UIPopupPane_h__
    20 #define __UIPopupPane_h__
    21 
    22 /* Qt includes: */
    23 #include <QWidget>
    24 #include <QMap>
    25 
    26 /* GUI includes: */
    27 #include "QIMessageBox.h"
     19#ifndef __UIAnimationFramework_h__
     20#define __UIAnimationFramework_h__
    2821
    2922/* Forward declaration: */
    3023class QStateMachine;
    31 class UIPopupPaneTextPane;
    32 class UIPopupPaneButtonPane;
    3324
    3425/* UIAnimationFramework namespace: */
     
    4233}
    4334
    44 /* Popup-pane prototype class: */
    45 class UIPopupPane : public QWidget
    46 {
    47     Q_OBJECT;
    48     Q_PROPERTY(int defaultOpacity READ defaultOpacity);
    49     Q_PROPERTY(int hoveredOpacity READ hoveredOpacity);
    50     Q_PROPERTY(int opacity READ opacity WRITE setOpacity);
    51 
    52 signals:
    53 
    54     /* Notifiers: Hover stuff: */
    55     void sigHoverEnter();
    56     void sigHoverLeave();
    57 
    58     /* Notifiers: Focus stuff: */
    59     void sigFocusEnter();
    60     void sigFocusLeave();
    61 
    62     /* Notifier: Layout stuff: */
    63     void sigSizeHintChanged();
    64 
    65     /* Notifier: Complete stuff: */
    66     void sigDone(int iResultCode) const;
    67 
    68 public:
    69 
    70     /* Constructor: */
    71     UIPopupPane(QWidget *pParent,
    72                 const QString &strMessage, const QString &strDetails,
    73                 const QMap<int, QString> &buttonDescriptions,
    74                 bool fProposeAutoConfirmation);
    75 
    76     /* API: Text stuff: */
    77     void setMessage(const QString &strMessage);
    78     void setDetails(const QString &strDetails);
    79 
    80     /* API: Auto-confirmation stuff: */
    81     void setProposeAutoConfirmation(bool fPropose);
    82 
    83     /* API: Layout stuff: */
    84     void setDesiredWidth(int iWidth);
    85     int minimumWidthHint() const;
    86     int minimumHeightHint() const;
    87     QSize minimumSizeHint() const;
    88     void layoutContent();
    89 
    90 private slots:
    91 
    92     /* Handler: Button stuff: */
    93     void sltButtonClicked(int iButtonID);
    94 
    95 private:
    96 
    97     /* Helpers: Prepare stuff: */
    98     void prepare();
    99     void prepareContent();
    100 
    101     /* Handler: Event-filter stuff: */
    102     bool eventFilter(QObject *pWatched, QEvent *pEvent);
    103 
    104     /* Handler: Event stuff: */
    105     void paintEvent(QPaintEvent *pEvent);
    106 
    107     /* Helper: Complete stuff: */
    108     void done(int iResultCode);
    109 
    110     /* Property: Hover stuff: */
    111     int defaultOpacity() const { return m_iDefaultOpacity; }
    112     int hoveredOpacity() const { return m_iHoveredOpacity; }
    113     int opacity() const { return m_iOpacity; }
    114     void setOpacity(int iOpacity) { m_iOpacity = iOpacity; update(); }
    115 
    116     /* Variables: General stuff: */
    117     const QString m_strId;
    118     const int m_iLayoutMargin;
    119     const int m_iLayoutSpacing;
    120 
    121     /* Variables: Text stuff: */
    122     QString m_strMessage, m_strDetails;
    123 
    124     /* Variables: Auto-confirmation stuff: */
    125     bool m_fProposeAutoConfirmation;
    126 
    127     /* Variables: Button stuff: */
    128     QMap<int, QString> m_buttonDescriptions;
    129 
    130     /* Variables: Hover stuff: */
    131     bool m_fHovered;
    132     const int m_iDefaultOpacity;
    133     const int m_iHoveredOpacity;
    134     int m_iOpacity;
    135 
    136     /* Variables: Focus stuff: */
    137     bool m_fFocused;
    138 
    139     /* Widgets: */
    140     UIPopupPaneTextPane *m_pTextPane;
    141     UIPopupPaneButtonPane *m_pButtonPane;
    142 };
    143 
    144 #endif /* __UIPopupPane_h__ */
     35#endif /* __UIAnimationFramework_h__ */
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupPane.cpp

    r45696 r46195  
    2626#include <QPainter>
    2727#include <QStateMachine>
    28 #include <QPropertyAnimation>
    29 #include <QSignalTransition>
    3028
    3129/* GUI includes: */
     
    3432#include "UIIconPool.h"
    3533#include "QIToolButton.h"
     34#include "UIAnimationFramework.h"
    3635
    3736/* Other VBox includes: */
    3837#include <VBox/sup.h>
    39 
    40 
    41 QStateMachine* UIAnimationFramework::installPropertyAnimation(QWidget *pTarget, const char *pszPropertyName,
    42                                                               const char *pszValuePropertyNameStart, const char *pszValuePropertyNameFinal,
    43                                                               const char *pSignalForward, const char *pSignalBackward,
    44                                                               bool fReversive /*= false*/, int iAnimationDuration /*= 300*/)
    45 {
    46     /* State-machine: */
    47     QStateMachine *pStateMachine = new QStateMachine(pTarget);
    48     /* State-machine 'start' state: */
    49     QState *pStateStart = new QState(pStateMachine);
    50     /* State-machine 'final' state: */
    51     QState *pStateFinal = new QState(pStateMachine);
    52 
    53     /* State-machine 'forward' animation: */
    54     QPropertyAnimation *pForwardAnimation = new QPropertyAnimation(pTarget, pszPropertyName, pStateMachine);
    55     pForwardAnimation->setEasingCurve(QEasingCurve(QEasingCurve::InOutCubic));
    56     pForwardAnimation->setDuration(iAnimationDuration);
    57     pForwardAnimation->setStartValue(pTarget->property(pszValuePropertyNameStart));
    58     pForwardAnimation->setEndValue(pTarget->property(pszValuePropertyNameFinal));
    59     /* State-machine 'backward' animation: */
    60     QPropertyAnimation *pBackwardAnimation = new QPropertyAnimation(pTarget, pszPropertyName, pStateMachine);
    61     pBackwardAnimation->setEasingCurve(QEasingCurve(QEasingCurve::InOutCubic));
    62     pBackwardAnimation->setDuration(iAnimationDuration);
    63     pBackwardAnimation->setStartValue(pTarget->property(pszValuePropertyNameFinal));
    64     pBackwardAnimation->setEndValue(pTarget->property(pszValuePropertyNameStart));
    65 
    66     /* State-machine state transitions: */
    67     QSignalTransition *pDefaultToHovered = pStateStart->addTransition(pTarget, pSignalForward, pStateFinal);
    68     pDefaultToHovered->addAnimation(pForwardAnimation);
    69     QSignalTransition *pHoveredToDefault = pStateFinal->addTransition(pTarget, pSignalBackward, pStateStart);
    70     pHoveredToDefault->addAnimation(pBackwardAnimation);
    71 
    72     /* Initial state is 'start': */
    73     pStateMachine->setInitialState(!fReversive ? pStateStart : pStateFinal);
    74     /* Start hover-machine: */
    75     pStateMachine->start();
    76     /* Return machine: */
    77     return pStateMachine;
    78 }
    7938
    8039
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIPopupPane.h

    r45696 r46195  
    2828
    2929/* Forward declaration: */
    30 class QStateMachine;
    3130class UIPopupPaneTextPane;
    3231class UIPopupPaneButtonPane;
    33 
    34 /* UIAnimationFramework namespace: */
    35 namespace UIAnimationFramework
    36 {
    37     /* API: Animation stuff: */
    38     QStateMachine* installPropertyAnimation(QWidget *pTarget, const char *pszPropertyName,
    39                                             const char *pszValuePropertyNameStart, const char *pszValuePropertyNameFinal,
    40                                             const char *pSignalForward, const char *pSignalBackward,
    41                                             bool fReversive = false, int iAnimationDuration = 300);
    42 }
    4332
    4433/* Popup-pane prototype class: */
Note: See TracChangeset for help on using the changeset viewer.

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