VirtualBox

Ignore:
Timestamp:
Oct 9, 2018 7:24:37 AM (6 years ago)
Author:
vboxsync
Message:

bugref:9255. Implementing a new guest screen scale factor editor

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

Legend:

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

    r74557 r74701  
    945945        src/widgets/UIPortForwardingTable.h \
    946946        src/widgets/UIProgressDialog.h \
     947        src/widgets/UIScaleFactorEditor.h \
    947948        src/widgets/UISlidingToolBar.h \
    948949        src/widgets/UISpecialControls.h \
     
    11731174        src/widgets/UIPortForwardingTable.h \
    11741175        src/widgets/UIProgressDialog.h \
     1176        src/widgets/UIScaleFactorEditor.h \
    11751177        src/widgets/UISlidingToolBar.h \
    11761178        src/widgets/UISpecialControls.h \
     
    16721674        src/widgets/UIPortForwardingTable.cpp \
    16731675        src/widgets/UIProgressDialog.cpp \
     1676        src/widgets/UIScaleFactorEditor.cpp \
    16741677        src/widgets/UISlidingToolBar.cpp \
    16751678        src/widgets/UISpecialControls.cpp \
     
    19581961        src/widgets/UIPortForwardingTable.cpp \
    19591962        src/widgets/UIProgressDialog.cpp \
     1963        src/widgets/UIScaleFactorEditor.cpp \
    19601964        src/widgets/UISlidingToolBar.cpp \
    19611965        src/widgets/UISpecialControls.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.cpp

    r74265 r74701  
    39703970}
    39713971
    3972 double UIExtraDataManager::scaleFactor(const QString &strID)
     3972double UIExtraDataManager::scaleFactor(const QString &strID, const int uScreenIndex /* = 0 */)
    39733973{
    39743974    /* Get corresponding extra-data value: */
    3975     const QString strValue = extraDataString(GUI_ScaleFactor, strID);
     3975    const QString strValue = extraDataString(extraDataKeyPerScreen(GUI_ScaleFactor, uScreenIndex), strID);
    39763976
    39773977    /* Try to convert loaded data to double: */
     
    39873987}
    39883988
    3989 void UIExtraDataManager::setScaleFactor(double dScaleFactor, const QString &strID)
     3989void UIExtraDataManager::setScaleFactor(double dScaleFactor, const QString &strID, const int uScreenIndex /* = 0 */)
    39903990{
    39913991    /* Set corresponding extra-data value: */
    3992     setExtraDataString(GUI_ScaleFactor, QString::number(dScaleFactor), strID);
     3992    setExtraDataString(extraDataKeyPerScreen(GUI_ScaleFactor, uScreenIndex), QString::number(dScaleFactor), strID);
    39933993}
    39943994
  • trunk/src/VBox/Frontends/VirtualBox/src/extradata/UIExtraDataManager.h

    r74265 r74701  
    597597
    598598        /** Returns the scale-factor. */
    599         double scaleFactor(const QString &strID);
     599        double scaleFactor(const QString &strID, const int uScreenIndex = 0);
    600600        /** Defines the @a dScaleFactor. */
    601         void setScaleFactor(double dScaleFactor, const QString &strID);
     601        void setScaleFactor(double dScaleFactor, const QString &strID, const int uScreenIndex = 0);
    602602
    603603        /** Returns the scaling optimization type. */
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.cpp

    r73560 r74701  
    409409    /* Load old 'Screen' data from the cache: */
    410410    m_pEditorVideoScreenCount->setValue(oldDisplayData.m_cGuestScreenCount);
     411    m_pScaleFactorEditor->setMonitorCount(oldDisplayData.m_cGuestScreenCount);
     412    m_pScaleFactorEditor->hide();
     413    m_pLabelGuestScreenScaleFactorEditor->hide();
    411414    m_pEditorGuestScreenScale->setValue((int)(oldDisplayData.m_dScaleFactor * 100));
    412415    m_pCheckbox3D->setChecked(oldDisplayData.m_f3dAccelerationEnabled);
  • trunk/src/VBox/Frontends/VirtualBox/src/settings/machine/UIMachineSettingsDisplay.ui

    r73134 r74701  
    203203          </item>
    204204          <item row="6" column="0">
     205           <widget class="QLabel" name="m_pLabelGuestScreenScaleFactorEditor">
     206            <property name="text">
     207             <string>Scale Factor:</string>
     208            </property>
     209            <property name="alignment">
     210             <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
     211            </property>
     212           </widget>
     213          </item>
     214          <item row="6" column="1" rowspan="2" colspan="2">
     215           <layout class="QGridLayout" name="m_pLayoutGuestScreenScaleFactorEditor">
     216            <property name="spacing">
     217             <number>0</number>
     218            </property>
     219            <item row="0" column="0" rowspan="2" colspan="3">
     220             <widget class="UIScaleFactorEditor" name="m_pScaleFactorEditor">
     221              <property name="whatsThis">
     222               <string>Controls the guest screen scale factor.</string>
     223              </property>
     224             </widget>
     225            </item>
     226           </layout>
     227          </item>
     228          <item row="8" column="0">
    205229           <widget class="QLabel" name="m_pLabelVideoOptions">
    206230            <property name="text">
     
    212236           </widget>
    213237          </item>
    214           <item row="6" column="1">
     238          <item row="8" column="1">
    215239           <widget class="QCheckBox" name="m_pCheckbox3D">
    216240            <property name="sizePolicy">
     
    228252           </widget>
    229253          </item>
    230           <item row="7" column="1">
     254          <item row="9" column="1">
    231255           <widget class="QCheckBox" name="m_pCheckbox2DVideo">
    232256            <property name="sizePolicy">
     
    801825   <header>UIFilmContainer.h</header>
    802826  </customwidget>
     827  <customwidget>
     828   <class>UIScaleFactorEditor</class>
     829   <extends>QWidget</extends>
     830   <header>UIScaleFactorEditor.h</header>
     831  </customwidget>
    803832 </customwidgets>
    804833 <resources/>
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIScaleFactorEditor.cpp

    r74627 r74701  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMiniToolBar class implementation.
     3 * VBox Qt GUI - UIScaleFactorEditor class implementation.
    44 */
    55
     
    2121
    2222/* Qt includes: */
    23 # include <QApplication>
    24 # include <QLabel>
    25 # include <QMenu>
    26 # include <QMoveEvent>
    27 # include <QPainter>
    28 # include <QStateMachine>
    29 # include <QStyle>
    30 # include <QTimer>
    31 # include <QToolButton>
    32 # include <QVBoxLayout>
    33 # include <QWindow>
    34 # ifdef VBOX_WS_X11
    35 #  include <QWindowStateChangeEvent>
    36 # endif
     23#include <QComboBox>
     24#include <QGridLayout>
     25#include <QSpinBox>
     26# include <QWidget>
    3727
    3828/* GUI includes: */
    39 # include "UIMiniToolBar.h"
    40 # include "UIAnimationFramework.h"
    41 # include "UIIconPool.h"
    42 # include "UIDesktopWidgetWatchdog.h"
    43 # include "VBoxGlobal.h"
    44 # ifdef VBOX_WS_X11
    45 #  include "UIExtraDataManager.h"
    46 # endif /* VBOX_WS_X11 */
     29#include "QIAdvancedSlider.h"
     30#include "UIScaleFactorEditor.h"
    4731
    4832#endif /* !VBOX_WITH_PRECOMPILED_HEADERS */
    4933
    5034
    51 /** UIToolBar reimplementation
    52   * providing UIMiniToolBar with mini-toolbar. */
    53 class UIMiniToolBarPrivate : public UIToolBar
    54 {
    55     Q_OBJECT;
    56 
    57 signals:
    58 
    59     /** Notifies listeners about we are resized. */
    60     void sigResized();
    61 
    62     /** Notifies listeners about action triggered to toggle auto-hide. */
    63     void sigAutoHideToggled();
    64     /** Notifies listeners about action triggered to minimize. */
    65     void sigMinimizeAction();
    66     /** Notifies listeners about action triggered to exit. */
    67     void sigExitAction();
    68     /** Notifies listeners about action triggered to close. */
    69     void sigCloseAction();
    70 
    71 public:
    72 
    73     /** Constructor. */
    74     UIMiniToolBarPrivate();
    75 
    76     /** Defines @a alignment. */
    77     void setAlignment(Qt::Alignment alignment);
    78 
    79     /** Returns whether we do auto-hide. */
    80     bool autoHide() const;
    81     /** Defines whether we do @a fAutoHide. */
    82     void setAutoHide(bool fAutoHide);
    83 
    84     /** Defines our @a strText. */
    85     void setText(const QString &strText);
    86 
    87     /** Adds our @a menus. */
    88     void addMenus(const QList<QMenu*> &menus);
    89 
    90 protected:
    91 
    92     /** Show @a pEvent handler. */
    93     virtual void showEvent(QShowEvent *pEvent);
    94     /** Polish @a pEvent handler. */
    95     virtual void polishEvent(QShowEvent *pEvent);
    96     /** Resize @a pEvent handler. */
    97     virtual void resizeEvent(QResizeEvent *pEvent);
    98     /** Paint @a pEvent handler. */
    99     virtual void paintEvent(QPaintEvent *pEvent);
    100 
    101 private:
    102 
    103     /** Prepare routine. */
    104     void prepare();
    105 
    106     /** Rebuilds our shape. */
    107     void rebuildShape();
    108 
    109     /** Holds whether this widget was polished. */
    110     bool m_fPolished;
    111     /** Holds the alignment type. */
    112     Qt::Alignment m_alignment;
    113     /** Holds the shape. */
    114     QPainterPath m_shape;
    115 
    116     /** Holds the action to toggle auto-hide. */
    117     QAction *m_pAutoHideAction;
    118     /** Holds the name label. */
    119     QLabel *m_pLabel;
    120     /** Holds the action to trigger minimize. */
    121     QAction *m_pMinimizeAction;
    122     /** Holds the action to trigger exit. */
    123     QAction *m_pRestoreAction;
    124     /** Holds the action to trigger close. */
    125     QAction *m_pCloseAction;
    126 
    127     /** Holds the pointer to the place to insert menu. */
    128     QAction *m_pMenuInsertPosition;
    129 
    130     /** Holds the spacings. */
    131     QList<QWidget*> m_spacings;
    132     /** Holds the margins. */
    133     QList<QWidget*> m_margins;
    134 };
    135 
    136 
    137 /*********************************************************************************************************************************
    138 *   Class UIMiniToolBarPrivate implementation.                                                                                   *
    139 *********************************************************************************************************************************/
    140 
    141 UIMiniToolBarPrivate::UIMiniToolBarPrivate()
    142     /* Variables: General stuff: */
    143     : m_fPolished(false)
    144     , m_alignment(Qt::AlignBottom)
    145     /* Variables: Contents stuff: */
    146     , m_pAutoHideAction(0)
    147     , m_pLabel(0)
    148     , m_pMinimizeAction(0)
    149     , m_pRestoreAction(0)
    150     , m_pCloseAction(0)
    151     /* Variables: Menu stuff: */
    152     , m_pMenuInsertPosition(0)
     35UIScaleFactorEditor::UIScaleFactorEditor(QWidget *pParent)
     36    : QIWithRetranslateUI<QWidget>(pParent)
     37    , m_pScaleSpinBox(0)
     38    , m_pMainLayout(0)
     39    , m_pMonitorComboBox(0)
    15340{
    15441    /* Prepare: */
     
    15643}
    15744
    158 void UIMiniToolBarPrivate::setAlignment(Qt::Alignment alignment)
     45void UIScaleFactorEditor::prepare()
    15946{
    160     /* Make sure alignment really changed: */
    161     if (m_alignment == alignment)
     47    setStyleSheet("background-color:yellow;");
     48
     49    m_pMainLayout = new QGridLayout;
     50    if (!m_pMainLayout)
     51        return;
     52    m_pMonitorComboBox = new QComboBox;
     53    if (m_pMonitorComboBox)
     54    {
     55        m_pMainLayout->addWidget(m_pMonitorComboBox, 0, 0);
     56    }
     57    m_pScaleSpinBox = new QSpinBox;
     58    if (m_pScaleSpinBox)
     59    {
     60        m_pMainLayout->addWidget(m_pScaleSpinBox, 0, 2);
     61        m_pScaleSpinBox->setMinimum(100);
     62        m_pScaleSpinBox->setMaximum(200);
     63        connect(m_pScaleSpinBox ,static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
     64                this, &UIScaleFactorEditor::sltScaleSpinBoxValueChanged);
     65    }
     66
     67    m_pScaleSlider = new QIAdvancedSlider;
     68    {
     69        m_pMainLayout->addWidget(m_pScaleSlider, 0, 1);
     70        m_pScaleSlider->setMinimum(100);
     71        m_pScaleSlider->setMaximum(200);
     72        m_pScaleSlider->setPageStep(10);
     73        m_pScaleSlider->setSingleStep(1);
     74        m_pScaleSlider->setTickInterval(10);
     75        m_pScaleSlider->setSnappingEnabled(true);
     76        connect(m_pScaleSlider, static_cast<void(QIAdvancedSlider::*)(int)>(&QIAdvancedSlider::valueChanged),
     77                this, &UIScaleFactorEditor::sltScaleSliderValueChanged);
     78    }
     79    setLayout(m_pMainLayout);
     80}
     81
     82void UIScaleFactorEditor::setMonitorCount(int iMonitorCount)
     83{
     84    if (!m_pMonitorComboBox)
     85        return;
     86    if (iMonitorCount == m_pMonitorComboBox->count())
    16287        return;
    16388
    164     /* Update alignment: */
    165     m_alignment = alignment;
     89    m_pMonitorComboBox->blockSignals(true);
     90    m_pMonitorComboBox->clear();
     91    for (int i = 0; i < iMonitorCount; ++i)
     92    {
     93        m_pMonitorComboBox->addItem(QString("Monitor %1").arg(i));
    16694
    167     /* Rebuild shape: */
    168     rebuildShape();
     95    }
     96    m_pMonitorComboBox->blockSignals(false);
    16997}
    17098
    171 bool UIMiniToolBarPrivate::autoHide() const
     99void UIScaleFactorEditor::sltScaleSpinBoxValueChanged(int value)
    172100{
    173     /* Return auto-hide: */
    174     return !m_pAutoHideAction->isChecked();
    175 }
    176 
    177 void UIMiniToolBarPrivate::setAutoHide(bool fAutoHide)
    178 {
    179     /* Make sure auto-hide really changed: */
    180     if (m_pAutoHideAction->isChecked() == !fAutoHide)
    181         return;
    182 
    183     /* Update auto-hide: */
    184     m_pAutoHideAction->setChecked(!fAutoHide);
    185 }
    186 
    187 void UIMiniToolBarPrivate::setText(const QString &strText)
    188 {
    189     /* Make sure text really changed: */
    190     if (m_pLabel->text() == strText)
    191         return;
    192 
    193     /* Update text: */
    194     m_pLabel->setText(strText);
    195 
    196     /* Resize to sizehint: */
    197     resize(sizeHint());
    198 }
    199 
    200 void UIMiniToolBarPrivate::addMenus(const QList<QMenu*> &menus)
    201 {
    202     /* For each of the passed menu items: */
    203     for (int i = 0; i < menus.size(); ++i)
     101    if (m_pScaleSlider && value != m_pScaleSlider->value())
    204102    {
    205         /* Get corresponding menu-action: */
    206         QAction *pAction = menus[i]->menuAction();
    207         /* Insert it into corresponding place: */
    208         insertAction(m_pMenuInsertPosition, pAction);
    209         /* Configure corresponding tool-button: */
    210         if (QToolButton *pButton = qobject_cast<QToolButton*>(widgetForAction(pAction)))
    211         {
    212             pButton->setPopupMode(QToolButton::InstantPopup);
    213             pButton->setAutoRaise(true);
    214         }
    215         /* Add some spacing: */
    216         if (i != menus.size() - 1)
    217             m_spacings << widgetForAction(insertWidget(m_pMenuInsertPosition, new QWidget(this)));
    218     }
    219 
    220     /* Resize to sizehint: */
    221     resize(sizeHint());
    222 }
    223 
    224 void UIMiniToolBarPrivate::showEvent(QShowEvent *pEvent)
    225 {
    226     /* Make sure we should polish dialog: */
    227     if (m_fPolished)
    228         return;
    229 
    230     /* Call to polish-event: */
    231     polishEvent(pEvent);
    232 
    233     /* Mark dialog as polished: */
    234     m_fPolished = true;
    235 }
    236 
    237 void UIMiniToolBarPrivate::polishEvent(QShowEvent*)
    238 {
    239     /* Toolbar spacings: */
    240     foreach(QWidget *pSpacing, m_spacings)
    241         pSpacing->setMinimumWidth(5);
    242 
    243     /* Title spacings: */
    244     foreach(QWidget *pLableMargin, m_margins)
    245         pLableMargin->setMinimumWidth(15);
    246 
    247     /* Resize to sizehint: */
    248     resize(sizeHint());
    249 }
    250 
    251 void UIMiniToolBarPrivate::resizeEvent(QResizeEvent*)
    252 {
    253     /* Rebuild shape: */
    254     rebuildShape();
    255 
    256     /* Notify listeners: */
    257     emit sigResized();
    258 }
    259 
    260 void UIMiniToolBarPrivate::paintEvent(QPaintEvent*)
    261 {
    262     /* Prepare painter: */
    263     QPainter painter(this);
    264 
    265     /* Fill background: */
    266     if (!m_shape.isEmpty())
    267     {
    268         painter.setRenderHint(QPainter::Antialiasing);
    269         painter.setClipPath(m_shape);
    270     }
    271     QRect backgroundRect = rect();
    272     QColor backgroundColor = palette().color(QPalette::Window);
    273     QLinearGradient headerGradient(backgroundRect.bottomLeft(), backgroundRect.topLeft());
    274     headerGradient.setColorAt(0, backgroundColor.darker(120));
    275     headerGradient.setColorAt(1, backgroundColor.darker(90));
    276     painter.fillRect(backgroundRect, headerGradient);
    277 }
    278 
    279 void UIMiniToolBarPrivate::prepare()
    280 {
    281     /* Determine icon metric: */
    282     const QStyle *pStyle = QApplication::style();
    283     const int iIconMetric = pStyle->pixelMetric(QStyle::PM_SmallIconSize);
    284 
    285     /* Configure toolbar: */
    286     setIconSize(QSize(iIconMetric, iIconMetric));
    287 
    288     /* Left margin: */
    289 #ifdef VBOX_WS_X11
    290     if (vboxGlobal().isCompositingManagerRunning())
    291         m_spacings << widgetForAction(addWidget(new QWidget));
    292 #else /* !VBOX_WS_X11 */
    293     m_spacings << widgetForAction(addWidget(new QWidget));
    294 #endif /* !VBOX_WS_X11 */
    295 
    296     /* Prepare push-pin: */
    297     m_pAutoHideAction = new QAction(this);
    298     m_pAutoHideAction->setIcon(UIIconPool::iconSet(":/pin_16px.png"));
    299     m_pAutoHideAction->setToolTip(UIMiniToolBar::tr("Always show the toolbar"));
    300     m_pAutoHideAction->setCheckable(true);
    301     connect(m_pAutoHideAction, SIGNAL(toggled(bool)), this, SIGNAL(sigAutoHideToggled()));
    302     addAction(m_pAutoHideAction);
    303 
    304     /* Left menu margin: */
    305     m_spacings << widgetForAction(addWidget(new QWidget));
    306 
    307     /* Right menu margin: */
    308     m_pMenuInsertPosition = addWidget(new QWidget);
    309     m_spacings << widgetForAction(m_pMenuInsertPosition);
    310 
    311     /* Left label margin: */
    312     m_margins << widgetForAction(addWidget(new QWidget));
    313 
    314     /* Insert a label for VM Name: */
    315     m_pLabel = new QLabel;
    316     m_pLabel->setAlignment(Qt::AlignCenter);
    317     addWidget(m_pLabel);
    318 
    319     /* Right label margin: */
    320     m_margins << widgetForAction(addWidget(new QWidget));
    321 
    322     /* Minimize action: */
    323     m_pMinimizeAction = new QAction(this);
    324     m_pMinimizeAction->setIcon(UIIconPool::iconSet(":/minimize_16px.png"));
    325     m_pMinimizeAction->setToolTip(UIMiniToolBar::tr("Minimize Window"));
    326     connect(m_pMinimizeAction, SIGNAL(triggered()), this, SIGNAL(sigMinimizeAction()));
    327     addAction(m_pMinimizeAction);
    328 
    329     /* Exit action: */
    330     m_pRestoreAction = new QAction(this);
    331     m_pRestoreAction->setIcon(UIIconPool::iconSet(":/restore_16px.png"));
    332     m_pRestoreAction->setToolTip(UIMiniToolBar::tr("Exit Full Screen or Seamless Mode"));
    333     connect(m_pRestoreAction, SIGNAL(triggered()), this, SIGNAL(sigExitAction()));
    334     addAction(m_pRestoreAction);
    335 
    336     /* Close action: */
    337     m_pCloseAction = new QAction(this);
    338     m_pCloseAction->setIcon(UIIconPool::iconSet(":/close_16px.png"));
    339     m_pCloseAction->setToolTip(UIMiniToolBar::tr("Close VM"));
    340     connect(m_pCloseAction, SIGNAL(triggered()), this, SIGNAL(sigCloseAction()));
    341     addAction(m_pCloseAction);
    342 
    343     /* Right margin: */
    344 #ifdef VBOX_WS_X11
    345     if (vboxGlobal().isCompositingManagerRunning())
    346         m_spacings << widgetForAction(addWidget(new QWidget));
    347 #else /* !VBOX_WS_X11 */
    348     m_spacings << widgetForAction(addWidget(new QWidget));
    349 #endif /* !VBOX_WS_X11 */
    350 }
    351 
    352 void UIMiniToolBarPrivate::rebuildShape()
    353 {
    354 #ifdef VBOX_WS_X11
    355     if (!vboxGlobal().isCompositingManagerRunning())
    356         return;
    357 #endif /* VBOX_WS_X11 */
    358 
    359     /* Rebuild shape: */
    360     QPainterPath shape;
    361     switch (m_alignment)
    362     {
    363         case Qt::AlignTop:
    364         {
    365             shape.moveTo(0, 0);
    366             shape.lineTo(shape.currentPosition().x(), height() - 10);
    367             shape.arcTo(QRectF(shape.currentPosition(), QSizeF(20, 20)).translated(0, -10), 180, 90);
    368             shape.lineTo(width() - 10, shape.currentPosition().y());
    369             shape.arcTo(QRectF(shape.currentPosition(), QSizeF(20, 20)).translated(-10, -20), 270, 90);
    370             shape.lineTo(shape.currentPosition().x(), 0);
    371             shape.closeSubpath();
    372             break;
    373         }
    374         case Qt::AlignBottom:
    375         {
    376             shape.moveTo(0, height());
    377             shape.lineTo(shape.currentPosition().x(), 10);
    378             shape.arcTo(QRectF(shape.currentPosition(), QSizeF(20, 20)).translated(0, -10), 180, -90);
    379             shape.lineTo(width() - 10, shape.currentPosition().y());
    380             shape.arcTo(QRectF(shape.currentPosition(), QSizeF(20, 20)).translated(-10, 0), 90, -90);
    381             shape.lineTo(shape.currentPosition().x(), height());
    382             shape.closeSubpath();
    383             break;
    384         }
    385         default:
    386             break;
    387     }
    388     m_shape = shape;
    389 
    390     /* Update: */
    391     update();
    392 }
    393 
    394 
    395 /*********************************************************************************************************************************
    396 *   Class UIMiniToolBar implementation.                                                                                          *
    397 *********************************************************************************************************************************/
    398 
    399 /* static */
    400 Qt::WindowFlags UIMiniToolBar::defaultWindowFlags(GeometryType geometryType)
    401 {
    402     /* Not everywhere: */
    403     Q_UNUSED(geometryType);
    404 
    405 #ifdef VBOX_WS_X11
    406     /* Depending on current WM: */
    407     switch (vboxGlobal().typeOfWindowManager())
    408     {
    409         // WORKAROUND:
    410         // By strange reason, frameless full-screen windows under certain WMs
    411         // do not respect the transient relationship between each other.
    412         // By nor less strange reason, frameless full-screen *tool* windows
    413         // respects such relationship, so we are doing what WM want.
    414         case X11WMType_GNOMEShell:
    415         case X11WMType_KWin:
    416         case X11WMType_Metacity:
    417         case X11WMType_Mutter:
    418         case X11WMType_Xfwm4:
    419             return geometryType == GeometryType_Full ?
    420                    Qt::Tool | Qt::FramelessWindowHint :
    421                    Qt::Window | Qt::FramelessWindowHint;
    422         default: break;
    423     }
    424 #endif /* VBOX_WS_X11 */
    425 
    426     /* Frameless window by default: */
    427     return Qt::Window | Qt::FramelessWindowHint;
    428 }
    429 
    430 UIMiniToolBar::UIMiniToolBar(QWidget *pParent,
    431                              GeometryType geometryType,
    432                              Qt::Alignment alignment,
    433                              bool fAutoHide /* = true */,
    434                              int iWindowIndex /* = -1 */)
    435     : QWidget(0, defaultWindowFlags(geometryType))
    436     /* Variables: General stuff: */
    437     , m_pParent(pParent)
    438     , m_geometryType(geometryType)
    439     , m_alignment(alignment)
    440     , m_fAutoHide(fAutoHide)
    441     , m_iWindowIndex(iWindowIndex)
    442     /* Variables: Contents stuff: */
    443     , m_pArea(0)
    444     , m_pToolbar(0)
    445     /* Variables: Hover stuff: */
    446     , m_fHovered(false)
    447     , m_pHoverEnterTimer(0)
    448     , m_pHoverLeaveTimer(0)
    449     , m_pAnimation(0)
    450 #ifdef VBOX_WS_X11
    451     , m_fIsParentMinimized(false)
    452 #endif
    453 {
    454     /* Prepare: */
    455     prepare();
    456 }
    457 
    458 UIMiniToolBar::~UIMiniToolBar()
    459 {
    460     /* Cleanup: */
    461     cleanup();
    462 }
    463 
    464 void UIMiniToolBar::setAlignment(Qt::Alignment alignment)
    465 {
    466     /* Make sure toolbar created: */
    467     AssertPtrReturnVoid(m_pToolbar);
    468 
    469     /* Make sure alignment really changed: */
    470     if (m_alignment == alignment)
    471         return;
    472 
    473     /* Update alignment: */
    474     m_alignment = alignment;
    475 
    476     /* Adjust geometry: */
    477     adjustGeometry();
    478 
    479     /* Propagate to child to update shape: */
    480     m_pToolbar->setAlignment(m_alignment);
    481 }
    482 
    483 void UIMiniToolBar::setAutoHide(bool fAutoHide, bool fPropagateToChild /* = true */)
    484 {
    485     /* Make sure toolbar created: */
    486     AssertPtrReturnVoid(m_pToolbar);
    487 
    488     /* Make sure auto-hide really changed: */
    489     if (m_fAutoHide == fAutoHide)
    490         return;
    491 
    492     /* Update auto-hide: */
    493     m_fAutoHide = fAutoHide;
    494 
    495     /* Adjust geometry: */
    496     adjustGeometry();
    497 
    498     /* Propagate to child to update action if necessary: */
    499     if (fPropagateToChild)
    500         m_pToolbar->setAutoHide(m_fAutoHide);
    501 }
    502 
    503 void UIMiniToolBar::setText(const QString &strText)
    504 {
    505     /* Make sure toolbar created: */
    506     AssertPtrReturnVoid(m_pToolbar);
    507 
    508     /* Propagate to child: */
    509     m_pToolbar->setText(strText);
    510 }
    511 
    512 void UIMiniToolBar::addMenus(const QList<QMenu*> &menus)
    513 {
    514     /* Make sure toolbar created: */
    515     AssertPtrReturnVoid(m_pToolbar);
    516 
    517     /* Propagate to child: */
    518     m_pToolbar->addMenus(menus);
    519 }
    520 
    521 void UIMiniToolBar::adjustGeometry()
    522 {
    523     /* Resize toolbar to minimum size: */
    524     m_pToolbar->resize(m_pToolbar->sizeHint());
    525 
    526     /* Calculate toolbar position: */
    527     int iX = 0, iY = 0;
    528     iX = width() / 2 - m_pToolbar->width() / 2;
    529     switch (m_alignment)
    530     {
    531         case Qt::AlignTop:    iY = 0; break;
    532         case Qt::AlignBottom: iY = height() - m_pToolbar->height(); break;
    533         default: break;
    534     }
    535 
    536     /* Update auto-hide animation: */
    537     m_shownToolbarPosition = QPoint(iX, iY);
    538     switch (m_alignment)
    539     {
    540         case Qt::AlignTop:    m_hiddenToolbarPosition = m_shownToolbarPosition - QPoint(0, m_pToolbar->height() - 3); break;
    541         case Qt::AlignBottom: m_hiddenToolbarPosition = m_shownToolbarPosition + QPoint(0, m_pToolbar->height() - 3); break;
    542     }
    543     m_pAnimation->update();
    544 
    545     /* Update toolbar geometry if known: */
    546     if (property("AnimationState").toString() == "Final")
    547         m_pToolbar->move(m_shownToolbarPosition);
    548     else
    549         m_pToolbar->move(m_hiddenToolbarPosition);
    550 
    551 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
    552     /* Adjust window mask: */
    553     setMask(m_pToolbar->geometry());
    554 #endif /* VBOX_WS_WIN || VBOX_WS_X11 */
    555 }
    556 
    557 void UIMiniToolBar::sltHandleToolbarResize()
    558 {
    559     /* Adjust geometry: */
    560     adjustGeometry();
    561 }
    562 
    563 void UIMiniToolBar::sltAutoHideToggled()
    564 {
    565     /* Propagate from child: */
    566     setAutoHide(m_pToolbar->autoHide(), false);
    567 }
    568 
    569 void UIMiniToolBar::sltHoverEnter()
    570 {
    571     /* Mark as 'hovered' if necessary: */
    572     if (!m_fHovered)
    573     {
    574         m_fHovered = true;
    575         emit sigHoverEnter();
     103        m_pScaleSlider->blockSignals(true);
     104        m_pScaleSlider->setValue(value);
     105        m_pScaleSlider->blockSignals(false);
    576106    }
    577107}
    578108
    579 void UIMiniToolBar::sltHoverLeave()
     109void UIScaleFactorEditor::sltScaleSliderValueChanged(int value)
    580110{
    581     /* Mark as 'unhovered' if necessary: */
    582     if (m_fHovered)
     111    if (m_pScaleSpinBox && value != m_pScaleSpinBox->value())
    583112    {
    584         m_fHovered = false;
    585         if (m_fAutoHide)
    586             emit sigHoverLeave();
     113        m_pScaleSpinBox->blockSignals(true);
     114        m_pScaleSpinBox->setValue(value);
     115        m_pScaleSpinBox->blockSignals(false);
    587116    }
    588117}
    589118
    590 void UIMiniToolBar::sltHide()
     119void UIScaleFactorEditor::retranslateUi()
    591120{
    592     LogRel(("GUI: Hide mini-toolbar for window #%d\n", m_iWindowIndex));
    593 
    594 #if defined(VBOX_WS_MAC)
    595 
    596     // Nothing
    597 
    598 #elif defined(VBOX_WS_WIN)
    599 
    600     /* Reset window state to NONE and hide it: */
    601     setWindowState(Qt::WindowNoState);
    602     hide();
    603 
    604 #elif defined(VBOX_WS_X11)
    605 
    606     /* Just hide window: */
    607     hide();
    608 
    609 #else
    610 
    611 # warning "port me"
    612 
    613 #endif
    614121}
    615 
    616 void UIMiniToolBar::sltShow()
    617 {
    618     LogRel(("GUI: Show mini-toolbar for window #%d\n", m_iWindowIndex));
    619 
    620     /* Update transience: */
    621     sltAdjustTransience();
    622 
    623 #if defined(VBOX_WS_MAC)
    624 
    625     // Nothing
    626 
    627 #elif defined(VBOX_WS_WIN)
    628 
    629     // WORKAROUND:
    630     // If the host-screen is changed => we should
    631     // reset window state to NONE first because
    632     // we need an expose on showFullScreen call.
    633     if (m_geometryType == GeometryType_Full)
    634         setWindowState(Qt::WindowNoState);
    635 
    636     /* Adjust window: */
    637     sltAdjust();
    638     /* Show window in necessary mode: */
    639     switch (m_geometryType)
    640     {
    641         case GeometryType_Available:
    642         {
    643             /* Show normal: */
    644             show();
    645             break;
    646         }
    647         case GeometryType_Full:
    648         {
    649             /* Show full-screen: */
    650             showFullScreen();
    651             break;
    652         }
    653     }
    654 
    655 #elif defined(VBOX_WS_X11)
    656 
    657     /* Show window in necessary mode: */
    658     switch (m_geometryType)
    659     {
    660         case GeometryType_Available:
    661         {
    662             /* Adjust window: */
    663             sltAdjust();
    664             /* Show maximized: */
    665             if (!isMaximized())
    666                 showMaximized();
    667             break;
    668         }
    669         case GeometryType_Full:
    670         {
    671             /* Show full-screen: */
    672             showFullScreen();
    673             /* Adjust window: */
    674             sltAdjust();
    675             break;
    676         }
    677     }
    678 
    679 #else
    680 
    681 # warning "port me"
    682 
    683 #endif
    684 
    685     /* Simulate toolbar auto-hiding: */
    686     simulateToolbarAutoHiding();
    687 }
    688 
    689 void UIMiniToolBar::sltAdjust()
    690 {
    691     LogRel(("GUI: Adjust mini-toolbar for window #%d\n", m_iWindowIndex));
    692 
    693     /* Get corresponding host-screen: */
    694     const int iHostScreenCount = gpDesktop->screenCount();
    695     int iHostScreen = gpDesktop->screenNumber(m_pParent);
    696     // WORKAROUND:
    697     // When switching host-screen count, especially in complex cases where RDP client is "replacing" host-screen(s) with own virtual-screen(s),
    698     // Qt could behave quite arbitrary and laggy, and due to racing there could be a situation when QDesktopWidget::screenNumber() returns -1
    699     // as a host-screen number where the parent window is currently located. We should handle this situation anyway, so let's assume the parent
    700     // window is located on primary (0) host-screen if it's present or ignore this request at all.
    701     if (iHostScreen < 0 || iHostScreen >= iHostScreenCount)
    702     {
    703         if (iHostScreenCount > 0)
    704         {
    705             LogRel(("GUI:  Mini-toolbar parent window #%d is located on invalid host-screen #%d. Fallback to primary.\n", m_iWindowIndex, iHostScreen));
    706             iHostScreen = 0;
    707         }
    708         else
    709         {
    710             LogRel(("GUI:  Mini-toolbar parent window #%d is located on invalid host-screen #%d. Ignore request.\n", m_iWindowIndex, iHostScreen));
    711             return;
    712         }
    713     }
    714 
    715     /* Get corresponding working area: */
    716     QRect workingArea;
    717     switch (m_geometryType)
    718     {
    719         case GeometryType_Available: workingArea = gpDesktop->availableGeometry(iHostScreen); break;
    720         case GeometryType_Full:      workingArea = gpDesktop->screenGeometry(iHostScreen); break;
    721     }
    722     Q_UNUSED(workingArea);
    723 
    724 #if defined(VBOX_WS_MAC)
    725 
    726     // Nothing
    727 
    728 #elif defined(VBOX_WS_WIN)
    729 
    730     switch (m_geometryType)
    731     {
    732         case GeometryType_Available:
    733         {
    734             /* Set appropriate window size: */
    735             const QSize newSize = workingArea.size();
    736             LogRel(("GUI:  Resize mini-toolbar for window #%d to %dx%d\n",
    737                      m_iWindowIndex, newSize.width(), newSize.height()));
    738             resize(newSize);
    739 
    740             /* Move window onto required screen: */
    741             const QPoint newPosition = workingArea.topLeft();
    742             LogRel(("GUI:  Move mini-toolbar for window #%d to %dx%d\n",
    743                      m_iWindowIndex, newPosition.x(), newPosition.y()));
    744             move(newPosition);
    745 
    746             break;
    747         }
    748         case GeometryType_Full:
    749         {
    750             /* Map window onto required screen: */
    751             LogRel(("GUI:  Map mini-toolbar for window #%d to screen %d of %d\n",
    752                      m_iWindowIndex, iHostScreen, qApp->screens().size()));
    753             windowHandle()->setScreen(qApp->screens().at(iHostScreen));
    754 
    755             /* Set appropriate window size: */
    756             const QSize newSize = workingArea.size();
    757             LogRel(("GUI:  Resize mini-toolbar for window #%d to %dx%d\n",
    758                      m_iWindowIndex, newSize.width(), newSize.height()));
    759             resize(newSize);
    760 
    761             break;
    762         }
    763     }
    764 
    765 #elif defined(VBOX_WS_X11)
    766 
    767     switch (m_geometryType)
    768     {
    769         case GeometryType_Available:
    770         {
    771             /* Make sure we are located on corresponding host-screen: */
    772             if (   gpDesktop->screenCount() > 1
    773                 && (x() != workingArea.x() || y() != workingArea.y()))
    774             {
    775                 // WORKAROUND:
    776                 // With Qt5 on KDE we can't just move the window onto desired host-screen if
    777                 // window is maximized. So we have to show it normal first of all:
    778                 if (isVisible() && isMaximized())
    779                     showNormal();
    780 
    781                 // WORKAROUND:
    782                 // With Qt5 on X11 we can't just move the window onto desired host-screen if
    783                 // window size is more than the available geometry (working area) of that
    784                 // host-screen. So we are resizing it to a smaller size first of all:
    785                 const QSize newSize = workingArea.size() * .9;
    786                 LogRel(("GUI:  Resize mini-toolbar for window #%d to smaller size %dx%d\n",
    787                         m_iWindowIndex, newSize.width(), newSize.height()));
    788                 resize(newSize);
    789 
    790                 /* Move window onto required screen: */
    791                 const QPoint newPosition = workingArea.topLeft();
    792                 LogRel(("GUI:  Move mini-toolbar for window #%d to %dx%d\n",
    793                         m_iWindowIndex, newPosition.x(), newPosition.y()));
    794                 move(newPosition);
    795             }
    796 
    797             break;
    798         }
    799         case GeometryType_Full:
    800         {
    801             /* Determine whether we should use the native full-screen mode: */
    802             const bool fUseNativeFullScreen = VBoxGlobal::supportsFullScreenMonitorsProtocolX11() &&
    803                                               !gEDataManager->legacyFullscreenModeRequested();
    804             if (fUseNativeFullScreen)
    805             {
    806                 /* Tell recent window managers which host-screen this window should be mapped to: */
    807                 VBoxGlobal::setFullScreenMonitorX11(this, iHostScreen);
    808             }
    809 
    810             /* Set appropriate window size: */
    811             const QSize newSize = workingArea.size();
    812             LogRel(("GUI:  Resize mini-toolbar for window #%d to %dx%d\n",
    813                     m_iWindowIndex, newSize.width(), newSize.height()));
    814             resize(newSize);
    815 
    816             /* Move window onto required screen: */
    817             const QPoint newPosition = workingArea.topLeft();
    818             LogRel(("GUI:  Move mini-toolbar for window #%d to %dx%d\n",
    819                     m_iWindowIndex, newPosition.x(), newPosition.y()));
    820             move(newPosition);
    821 
    822             /* Re-apply the full-screen state lost on above move(): */
    823             setWindowState(Qt::WindowFullScreen);
    824 
    825             break;
    826         }
    827     }
    828 
    829 #else
    830 
    831 # warning "port me"
    832 
    833 #endif
    834 }
    835 
    836 void UIMiniToolBar::sltAdjustTransience()
    837 {
    838     // WORKAROUND:
    839     // Make sure win id is generated,
    840     // else Qt5 can crash otherwise.
    841     winId();
    842     m_pParent->winId();
    843 
    844     /* Add the transience dependency: */
    845     windowHandle()->setTransientParent(m_pParent->windowHandle());
    846 }
    847 
    848 void UIMiniToolBar::prepare()
    849 {
    850     /* Install event-filters: */
    851     installEventFilter(this);
    852     m_pParent->installEventFilter(this);
    853 
    854 #if   defined(VBOX_WS_WIN)
    855     /* No background until first paint-event: */
    856     setAttribute(Qt::WA_NoSystemBackground);
    857     /* Enable translucency through Qt API: */
    858     setAttribute(Qt::WA_TranslucentBackground);
    859 #elif defined(VBOX_WS_X11)
    860     /* Enable translucency through Qt API if supported: */
    861     if (vboxGlobal().isCompositingManagerRunning())
    862         setAttribute(Qt::WA_TranslucentBackground);
    863 #endif /* VBOX_WS_X11 */
    864 
    865     /* Make sure we have no focus: */
    866     setFocusPolicy(Qt::NoFocus);
    867 
    868     /* Prepare area: */
    869     m_pArea = new QWidget;
    870     {
    871         /* Allow any area size: */
    872         m_pArea->setMinimumSize(QSize(1, 1));
    873         /* Configure own background: */
    874         QPalette pal = m_pArea->palette();
    875         pal.setColor(QPalette::Window, QColor(Qt::transparent));
    876         m_pArea->setPalette(pal);
    877         /* Layout area according parent-widget: */
    878         QVBoxLayout *pMainLayout = new QVBoxLayout(this);
    879         pMainLayout->setContentsMargins(0, 0, 0, 0);
    880         pMainLayout->addWidget(m_pArea);
    881         /* Make sure we have no focus: */
    882         m_pArea->setFocusPolicy(Qt::NoFocus);
    883     }
    884 
    885     /* Prepare mini-toolbar: */
    886     m_pToolbar = new UIMiniToolBarPrivate;
    887     {
    888         /* Make sure we have no focus: */
    889         m_pToolbar->setFocusPolicy(Qt::NoFocus);
    890         /* Propagate known options to child: */
    891         m_pToolbar->setAutoHide(m_fAutoHide);
    892         m_pToolbar->setAlignment(m_alignment);
    893         /* Configure own background: */
    894         QPalette pal = m_pToolbar->palette();
    895         pal.setColor(QPalette::Window, palette().color(QPalette::Window));
    896         m_pToolbar->setPalette(pal);
    897         /* Configure child connections: */
    898         connect(m_pToolbar, SIGNAL(sigResized()), this, SLOT(sltHandleToolbarResize()));
    899         connect(m_pToolbar, SIGNAL(sigAutoHideToggled()), this, SLOT(sltAutoHideToggled()));
    900         connect(m_pToolbar, SIGNAL(sigMinimizeAction()), this, SIGNAL(sigMinimizeAction()));
    901         connect(m_pToolbar, SIGNAL(sigExitAction()), this, SIGNAL(sigExitAction()));
    902         connect(m_pToolbar, SIGNAL(sigCloseAction()), this, SIGNAL(sigCloseAction()));
    903         /* Add child to area: */
    904         m_pToolbar->setParent(m_pArea);
    905         /* Make sure we have no focus: */
    906         m_pToolbar->setFocusPolicy(Qt::NoFocus);
    907     }
    908 
    909     /* Prepare hover-enter/leave timers: */
    910     m_pHoverEnterTimer = new QTimer(this);
    911     {
    912         m_pHoverEnterTimer->setSingleShot(true);
    913         m_pHoverEnterTimer->setInterval(500);
    914         connect(m_pHoverEnterTimer, SIGNAL(timeout()), this, SLOT(sltHoverEnter()));
    915     }
    916     m_pHoverLeaveTimer = new QTimer(this);
    917     {
    918         m_pHoverLeaveTimer->setSingleShot(true);
    919         m_pHoverLeaveTimer->setInterval(500);
    920         connect(m_pHoverLeaveTimer, SIGNAL(timeout()), this, SLOT(sltHoverLeave()));
    921     }
    922 
    923     /* Install 'auto-hide' animation to 'toolbarPosition' property: */
    924     m_pAnimation = UIAnimation::installPropertyAnimation(this,
    925                                                          "toolbarPosition",
    926                                                          "hiddenToolbarPosition", "shownToolbarPosition",
    927                                                          SIGNAL(sigHoverEnter()), SIGNAL(sigHoverLeave()),
    928                                                          true);
    929 
    930     /* Adjust geometry first time: */
    931     adjustGeometry();
    932 
    933 #ifdef VBOX_WS_X11
    934     /* Hide mini-toolbar from taskbar and pager: */
    935     vboxGlobal().setSkipTaskBarFlag(this);
    936     vboxGlobal().setSkipPagerFlag(this);
    937 #endif
    938 }
    939 
    940 void UIMiniToolBar::cleanup()
    941 {
    942     /* Stop hover-enter/leave timers: */
    943     if (m_pHoverEnterTimer && m_pHoverEnterTimer->isActive())
    944         m_pHoverEnterTimer->stop();
    945     if (m_pHoverLeaveTimer && m_pHoverLeaveTimer->isActive())
    946         m_pHoverLeaveTimer->stop();
    947 
    948     /* Destroy animation before toolbar: */
    949     delete m_pAnimation;
    950     m_pAnimation = 0;
    951 
    952     /* Destroy toolbar after animation: */
    953     delete m_pToolbar;
    954     m_pToolbar = 0;
    955 }
    956 
    957 void UIMiniToolBar::enterEvent(QEvent*)
    958 {
    959     /* Stop the hover-leave timer if necessary: */
    960     if (m_pHoverLeaveTimer && m_pHoverLeaveTimer->isActive())
    961         m_pHoverLeaveTimer->stop();
    962 
    963     /* Start the hover-enter timer: */
    964     if (m_pHoverEnterTimer)
    965         m_pHoverEnterTimer->start();
    966 }
    967 
    968 void UIMiniToolBar::leaveEvent(QEvent*)
    969 {
    970     // WORKAROUND:
    971     // No idea why, but GUI receives mouse leave event
    972     // when the mouse cursor is on the border of screen
    973     // even if underlying widget is on the border of
    974     // screen as well, we should detect and ignore that.
    975     // Besides that, this is a good way to keep the
    976     // tool-bar visible when the mouse moving through
    977     // the desktop strut till the real screen border.
    978     const QPoint cursorPosition = QCursor::pos();
    979     if (   cursorPosition.y() <= y() + 1
    980         || cursorPosition.y() >= y() + height() - 1)
    981         return;
    982 
    983     /* Stop the hover-enter timer if necessary: */
    984     if (m_pHoverEnterTimer && m_pHoverEnterTimer->isActive())
    985         m_pHoverEnterTimer->stop();
    986 
    987     /* Start the hover-leave timer: */
    988     if (m_fAutoHide && m_pHoverLeaveTimer)
    989         m_pHoverLeaveTimer->start();
    990 }
    991 
    992 void UIMiniToolBar::resizeEvent(QResizeEvent*)
    993 {
    994     /* Adjust geometry: */
    995     adjustGeometry();
    996 }
    997 
    998 bool UIMiniToolBar::eventFilter(QObject *pWatched, QEvent *pEvent)
    999 {
    1000     /* Detect if we have window activation stolen: */
    1001     if (pWatched == this && pEvent->type() == QEvent::WindowActivate)
    1002     {
    1003 #if   defined(VBOX_WS_WIN)
    1004         emit sigNotifyAboutWindowActivationStolen();
    1005 #elif defined(VBOX_WS_X11)
    1006         switch (vboxGlobal().typeOfWindowManager())
    1007         {
    1008             case X11WMType_GNOMEShell:
    1009             case X11WMType_Mutter:
    1010             {
    1011                 // WORKAROUND:
    1012                 // Under certain WMs we can receive stolen activation event too early,
    1013                 // returning activation to initial source immediately makes no sense.
    1014                 // In fact, Qt is not become aware of actual window activation later,
    1015                 // so we are going to return window activation in let's say 100ms.
    1016                 QTimer::singleShot(100, this, SLOT(sltNotifyAboutWindowActivationStolen()));
    1017                 break;
    1018             }
    1019             default:
    1020             {
    1021                 emit sigNotifyAboutWindowActivationStolen();
    1022                 break;
    1023             }
    1024         }
    1025 #endif /* VBOX_WS_X11 */
    1026     }
    1027 
    1028     /* If that's parent window event: */
    1029     if (pWatched == m_pParent)
    1030     {
    1031         switch (pEvent->type())
    1032         {
    1033             case QEvent::Hide:
    1034             {
    1035                 /* Skip if parent or we are minimized: */
    1036                 if (   isParentMinimized()
    1037                     || isMinimized())
    1038                     break;
    1039 
    1040                 /* Asynchronously call for sltHide(): */
    1041                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent hide event\n"));
    1042                 QMetaObject::invokeMethod(this, "sltHide", Qt::QueuedConnection);
    1043                 break;
    1044             }
    1045             case QEvent::Show:
    1046             {
    1047                 /* Skip if parent or we are minimized: */
    1048                 if (   isParentMinimized()
    1049                     || isMinimized())
    1050                     break;
    1051 
    1052                 /* Asynchronously call for sltShow(): */
    1053                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent show event\n"));
    1054                 QMetaObject::invokeMethod(this, "sltShow", Qt::QueuedConnection);
    1055                 break;
    1056             }
    1057             case QEvent::Move:
    1058             {
    1059                 // WORKAROUND:
    1060                 // In certain cases there can be that parent is moving outside of
    1061                 // full-screen geometry. That for example can happen if virtual
    1062                 // desktop being changed. We should ignore Move event in such case.
    1063                 /* Skip if parent is outside of full-screen geometry: */
    1064                 QMoveEvent *pMoveEvent = static_cast<QMoveEvent*>(pEvent);
    1065                 if (!gpDesktop->screenGeometry(m_pParent).contains(pMoveEvent->pos()))
    1066                     break;
    1067                 /* Skip if parent or we are invisible: */
    1068                 if (   !m_pParent->isVisible()
    1069                     || !isVisible())
    1070                     break;
    1071                 /* Skip if parent or we are minimized: */
    1072                 if (   isParentMinimized()
    1073                     || isMinimized())
    1074                     break;
    1075 
    1076                 /* Asynchronously call for sltShow(): */
    1077                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent move event\n"));
    1078                 QMetaObject::invokeMethod(this, "sltShow", Qt::QueuedConnection);
    1079                 break;
    1080             }
    1081             case QEvent::Resize:
    1082             {
    1083                 /* Skip if parent or we are invisible: */
    1084                 if (   !m_pParent->isVisible()
    1085                     || !isVisible())
    1086                     break;
    1087                 /* Skip if parent or we are minimized: */
    1088                 if (   isParentMinimized()
    1089                     || isMinimized())
    1090                     break;
    1091 
    1092                 /* Asynchronously call for sltShow(): */
    1093                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent resize event\n"));
    1094                 QMetaObject::invokeMethod(this, "sltShow", Qt::QueuedConnection);
    1095                 break;
    1096             }
    1097 #ifdef VBOX_WS_X11
    1098             case QEvent::WindowStateChange:
    1099             {
    1100                 /* Watch for parent window state changes: */
    1101                 QWindowStateChangeEvent *pChangeEvent = static_cast<QWindowStateChangeEvent*>(pEvent);
    1102                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent window state changed from %d to %d\n",
    1103                          (int)pChangeEvent->oldState(), (int)m_pParent->windowState()));
    1104 
    1105                 if (   m_pParent->windowState() & Qt::WindowMinimized
    1106                     && !m_fIsParentMinimized)
    1107                 {
    1108                     /* Mark parent window minimized, isMinimized() is not enough due to Qt5vsX11 fight: */
    1109                     LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent window is minimized\n"));
    1110                     m_fIsParentMinimized = true;
    1111                 }
    1112                 else
    1113                 if (m_fIsParentMinimized)
    1114                 {
    1115                     switch (m_geometryType)
    1116                     {
    1117                         case GeometryType_Available:
    1118                         {
    1119                             if (   m_pParent->windowState() == Qt::WindowMaximized
    1120                                 && pChangeEvent->oldState() == Qt::WindowNoState)
    1121                             {
    1122                                 /* Mark parent window non-minimized, isMinimized() is not enough due to Qt5vsX11 fight: */
    1123                                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent window is maximized\n"));
    1124                                 m_fIsParentMinimized = false;
    1125                             }
    1126                             break;
    1127                         }
    1128                         case GeometryType_Full:
    1129                         {
    1130                             if (   m_pParent->windowState() == Qt::WindowFullScreen
    1131                                 && pChangeEvent->oldState() == Qt::WindowNoState)
    1132                             {
    1133                                 /* Mark parent window non-minimized, isMinimized() is not enough due to Qt5vsX11 fight: */
    1134                                 LogRel2(("GUI: UIMiniToolBar::eventFilter: Parent window is full-screen\n"));
    1135                                 m_fIsParentMinimized = false;
    1136                             }
    1137                             break;
    1138                         }
    1139                     }
    1140                 }
    1141                 break;
    1142             }
    1143 #endif /* VBOX_WS_X11 */
    1144             default:
    1145                 break;
    1146         }
    1147     }
    1148 
    1149     /* Call to base-class: */
    1150     return QWidget::eventFilter(pWatched, pEvent);
    1151 }
    1152 
    1153 void UIMiniToolBar::simulateToolbarAutoHiding()
    1154 {
    1155     /* This simulation helps user to notice
    1156      * toolbar location, so it will be used only
    1157      * 1. if toolbar unhovered and
    1158      * 2. auto-hide feature enabled: */
    1159     if (m_fHovered || !m_fAutoHide)
    1160         return;
    1161 
    1162     /* Simulate hover-leave event: */
    1163     m_fHovered = true;
    1164     m_pHoverLeaveTimer->start();
    1165 }
    1166 
    1167 void UIMiniToolBar::setToolbarPosition(QPoint point)
    1168 {
    1169     /* Update position: */
    1170     AssertPtrReturnVoid(m_pToolbar);
    1171     m_pToolbar->move(point);
    1172 
    1173 #if defined(VBOX_WS_WIN) || defined(VBOX_WS_X11)
    1174     /* Update window mask: */
    1175     setMask(m_pToolbar->geometry());
    1176 #endif /* VBOX_WS_WIN || VBOX_WS_X11 */
    1177 }
    1178 
    1179 QPoint UIMiniToolBar::toolbarPosition() const
    1180 {
    1181     /* Return position: */
    1182     AssertPtrReturn(m_pToolbar, QPoint());
    1183     return m_pToolbar->pos();
    1184 }
    1185 
    1186 bool UIMiniToolBar::isParentMinimized() const
    1187 {
    1188 #ifdef VBOX_WS_X11
    1189     return m_fIsParentMinimized;
    1190 #else
    1191     return m_pParent->isMinimized();
    1192 #endif
    1193 }
    1194 
    1195 #include "UIMiniToolBar.moc"
    1196 
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/UIScaleFactorEditor.h

    r74627 r74701  
    11/* $Id$ */
    22/** @file
    3  * VBox Qt GUI - UIMiniToolBar class declaration.
     3 * VBox Qt GUI - UIScaleFactorEditor class declaration.
    44 */
    55
     
    1616 */
    1717
    18 #ifndef ___UIMiniToolBar_h___
    19 #define ___UIMiniToolBar_h___
     18#ifndef ___UIScaleFactorEditor_h___
     19#define ___UIScaleFactorEditor_h___
     20
     21/* Qt includes: */
     22//# include <QWidget>
    2023
    2124/* GUI includes: */
    22 #include "UIToolBar.h"
     25#include "QIWithRetranslateUI.h"
     26#include "UILibraryDefs.h"
     27
    2328
    2429/* Forward declarations: */
    25 class QMenu;
    26 class QTimer;
    27 class QLabel;
    28 class UIAnimation;
    29 class UIMiniToolBarPrivate;
    30 
    31 /** Geometry types. */
    32 enum GeometryType
    33 {
    34     GeometryType_Available,
    35     GeometryType_Full
    36 };
    37 
     30class QComboBox;
     31class QGridLayout;
     32class QSpinBox;
     33class QWidget;
     34class QIAdvancedSlider;
    3835
    3936/** QWidget reimplementation
    40   * providing GUI with slideable mini-toolbar used in full-screen/seamless modes. */
    41 class UIMiniToolBar : public QWidget
     37 * providing GUI with monitor scale factor editing functionality. */
     38class SHARED_LIBRARY_STUFF UIScaleFactorEditor : public QIWithRetranslateUI<QWidget>
    4239{
    4340    Q_OBJECT;
    44     Q_PROPERTY(QPoint toolbarPosition READ toolbarPosition WRITE setToolbarPosition);
    45     Q_PROPERTY(QPoint hiddenToolbarPosition READ hiddenToolbarPosition);
    46     Q_PROPERTY(QPoint shownToolbarPosition READ shownToolbarPosition);
    4741
    4842signals:
    49 
    50     /** Notifies listeners about action triggered to minimize. */
    51     void sigMinimizeAction();
    52     /** Notifies listeners about action triggered to exit. */
    53     void sigExitAction();
    54     /** Notifies listeners about action triggered to close. */
    55     void sigCloseAction();
    56 
    57     /** Notifies listeners about we are hovered. */
    58     void sigHoverEnter();
    59     /** Notifies listeners about we are unhovered. */
    60     void sigHoverLeave();
    61 
    62     /** Notifies listeners about we stole window activation. */
    63     void sigNotifyAboutWindowActivationStolen();
     43    void sigScaleFactorChanged(int iMonitorID, double scaleFactor);
    6444
    6545public:
    6646
    67     /** Proposes default set of window flags for particular platform. */
    68     static Qt::WindowFlags defaultWindowFlags(GeometryType geometryType);
     47    /** Constructor, passes @a pParent to the QWidget constructor.*/
     48    UIScaleFactorEditor(QWidget *pParent);
     49    void setMonitorCount(int iMonitorCount);
    6950
    70     /** Constructor, passes @a pParent to the QWidget constructor.
    71       * @param geometryType determines the geometry type,
    72       * @param alignment    determines the alignment type,
    73       * @param fAutoHide    determines whether we should auto-hide.
    74       * @param iWindowIndex determines the parent window index. */
    75     UIMiniToolBar(QWidget *pParent,
    76                   GeometryType geometryType,
    77                   Qt::Alignment alignment,
    78                   bool fAutoHide = true,
    79                   int iWindowIndex = -1);
    80     /** Destructor. */
    81     ~UIMiniToolBar();
    82 
    83     /** Defines @a alignment. */
    84     void setAlignment(Qt::Alignment alignment);
    85 
    86     /** Returns whether internal widget do auto-hide. */
    87     bool autoHide() const { return m_fAutoHide; }
    88     /** Defines whether internal widget do @a fAutoHide.
    89       * @param fPropagateToChild determines should we propagate defined
    90       *                          option value to internal widget. */
    91     void setAutoHide(bool fAutoHide, bool fPropagateToChild = true);
    92 
    93     /** Defines @a strText for internal widget. */
    94     void setText(const QString &strText);
    95 
    96     /** Adds @a menus to internal widget. */
    97     void addMenus(const QList<QMenu*> &menus);
    98 
    99     /** Adjusts geometry. */
    100     void adjustGeometry();
     51protected:
     52    virtual void retranslateUi() /* override */;
    10153
    10254private slots:
    103 
    104     /** Handles internal widget resize event. */
    105     void sltHandleToolbarResize();
    106 
    107     /** Handles internal widget auto-hide toggling. */
    108     void sltAutoHideToggled();
    109 
    110     /** Handles hovering. */
    111     void sltHoverEnter();
    112     /** Handles unhovering. */
    113     void sltHoverLeave();
    114 
    115     /** Notifies listeners about we stole window activation. */
    116     void sltNotifyAboutWindowActivationStolen() { emit sigNotifyAboutWindowActivationStolen(); }
    117 
    118     /** Hides window. */
    119     void sltHide();
    120     /** Shows and adjusts window according to parent. */
    121     void sltShow();
    122     /** Adjusts window according to parent. */
    123     void sltAdjust();
    124     /** Adjusts window transience according to parent. */
    125     void sltAdjustTransience();
     55    void sltScaleSpinBoxValueChanged(int value);
     56    void sltScaleSliderValueChanged(int value);
    12657
    12758private:
    128 
    129     /** Prepare routine. */
    13059    void prepare();
    131     /** Cleanup routine. */
    132     void cleanup();
    133 
    134     /** Mouse enter @a pEvent handler. */
    135     void enterEvent(QEvent *pEvent);
    136     /** Mouse leave @a pEvent handler. */
    137     void leaveEvent(QEvent *pEvent);
    138 
    139     /** Resize @a pEvent handler. */
    140     void resizeEvent(QResizeEvent *pEvent);
    141 
    142     /** Filters @a pEvent if <i>this</i> object has been
    143       * installed as an event-filter for the @a pWatched. */
    144     bool eventFilter(QObject *pWatched, QEvent *pEvent);
    145 
    146     /** Simulates auto-hide animation. */
    147     void simulateToolbarAutoHiding();
    148 
    149     /** Defines internal widget @a position. */
    150     void setToolbarPosition(QPoint position);
    151     /** Returns internal widget position. */
    152     QPoint toolbarPosition() const;
    153     /** Returns internal widget position when it's hidden. */
    154     QPoint hiddenToolbarPosition() const { return m_hiddenToolbarPosition; }
    155     /** Returns internal widget position when it's shown. */
    156     QPoint shownToolbarPosition() const { return m_shownToolbarPosition; }
    157 
    158     /** Returns whether the parent is currently minimized. */
    159     bool isParentMinimized() const;
    160 
    161     /** Holds the parent reference. */
    162     QWidget *m_pParent;
    163 
    164     /** Holds the geometry type. */
    165     const GeometryType m_geometryType;
    166     /** Holds the alignment type. */
    167     Qt::Alignment m_alignment;
    168     /** Holds whether we should auto-hide. */
    169     bool m_fAutoHide;
    170     /** Holds the parent window index. */
    171     int m_iWindowIndex;
    172 
    173     /** Holds the area. */
    174     QWidget *m_pArea;
    175     /** Holds the internal widget. */
    176     UIMiniToolBarPrivate *m_pToolbar;
    177 
    178     /** Holds whether we are hovered. */
    179     bool m_fHovered;
    180     /** Holds the hover timer. */
    181     QTimer *m_pHoverEnterTimer;
    182     /** Holds the unhover timer. */
    183     QTimer *m_pHoverLeaveTimer;
    184     /** Holds the internal widget position when it's hidden. */
    185     QPoint m_hiddenToolbarPosition;
    186     /** Holds the internal widget position when it's shown. */
    187     QPoint m_shownToolbarPosition;
    188     /** Holds the animation framework object. */
    189     UIAnimation *m_pAnimation;
    190 
    191 #ifdef VBOX_WS_X11
    192     /** X11: Holds whether the parent is currently minimized.
    193       * Used to restore the full-screen/maximized state
    194       * when the parent restored again. */
    195     bool m_fIsParentMinimized;
    196 #endif
     60    QSpinBox          *m_pScaleSpinBox;
     61    QGridLayout       *m_pMainLayout;
     62    QComboBox         *m_pMonitorComboBox;
     63    QIAdvancedSlider  *m_pScaleSlider;
    19764};
    19865
    199 #endif /* !___UIMiniToolBar_h___ */
    200 
     66#endif /* !___UIScaleFactorEditor_h___ */
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