VirtualBox

Changeset 79860 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jul 18, 2019 3:47:48 PM (5 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9241: VirtualBox Manager: Details pane: Heavy cleanup/rework for UIMachinePreview.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/manager/details
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIMachinePreview.cpp

    r79365 r79860  
    4646    , m_dRatio((double)QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 16)
    4747    , m_iMargin(0)
    48     , m_preset(AspectRatioPreset_16x9)
     48    , m_enmPreset(AspectRatioPreset_16x9)
    4949    , m_pPreviewImg(0)
    5050{
    51     /* Create session instance: */
    52     m_session.createInstance(CLSID_Session);
    53 
    54     /* Cache aspect-ratio preset settings: */
    55     const QIcon empty16x10 = UIIconPool::iconSet(":/preview_empty_16to10_242x167px.png");
    56     const QIcon empty16x9 = UIIconPool::iconSet(":/preview_empty_16to9_242x155px.png");
    57     const QIcon empty4x3 = UIIconPool::iconSet(":/preview_empty_4to3_242x192px.png");
    58     const QIcon full16x10 = UIIconPool::iconSet(":/preview_full_16to10_242x167px.png");
    59     const QIcon full16x9 = UIIconPool::iconSet(":/preview_full_16to9_242x155px.png");
    60     const QIcon full4x3 = UIIconPool::iconSet(":/preview_full_4to3_242x192px.png");
    61 
    62     // WORKAROUND:
    63     // Since we don't have x3 and x4 HiDPI icons yet,
    64     // and we hadn't enabled automatic up-scaling for now,
    65     // we have to make sure m_dRatio is within possible bounds.
    66     const QList<QSize> sizes = empty16x10.availableSizes();
    67     if (sizes.size() >= 2)
    68         m_dRatio = qMin(m_dRatio, (double)sizes.last().width() / sizes.first().width());
    69 
    70     m_sizes.insert(AspectRatioPreset_16x10, QSize(242 * m_dRatio, 167 * m_dRatio));
    71     m_sizes.insert(AspectRatioPreset_16x9, QSize(242 * m_dRatio, 155 * m_dRatio));
    72     m_sizes.insert(AspectRatioPreset_4x3, QSize(242 * m_dRatio, 192 * m_dRatio));
    73     m_ratios.insert(AspectRatioPreset_16x10, (double)16/10);
    74     m_ratios.insert(AspectRatioPreset_16x9, (double)16/9);
    75     m_ratios.insert(AspectRatioPreset_4x3, (double)4/3);
    76     m_emptyPixmaps.insert(AspectRatioPreset_16x10, new QPixmap(empty16x10.pixmap(m_sizes.value(AspectRatioPreset_16x10))));
    77     m_emptyPixmaps.insert(AspectRatioPreset_16x9, new QPixmap(empty16x9.pixmap(m_sizes.value(AspectRatioPreset_16x9))));
    78     m_emptyPixmaps.insert(AspectRatioPreset_4x3, new QPixmap(empty4x3.pixmap(m_sizes.value(AspectRatioPreset_4x3))));
    79     m_fullPixmaps.insert(AspectRatioPreset_16x10, new QPixmap(full16x10.pixmap(m_sizes.value(AspectRatioPreset_16x10))));
    80     m_fullPixmaps.insert(AspectRatioPreset_16x9, new QPixmap(full16x9.pixmap(m_sizes.value(AspectRatioPreset_16x9))));
    81     m_fullPixmaps.insert(AspectRatioPreset_4x3, new QPixmap(full4x3.pixmap(m_sizes.value(AspectRatioPreset_4x3))));
    82 
    83     /* Setup contents (depends on presets above!): */
    84     setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    85 
    86     /* Create the context menu: */
    87     m_pUpdateTimerMenu = new QMenu;
    88     QActionGroup *pUpdateTimeG = new QActionGroup(this);
    89     pUpdateTimeG->setExclusive(true);
    90     for(int i = 0; i < PreviewUpdateIntervalType_Max; ++i)
    91     {
    92         QAction *pUpdateTime = new QAction(pUpdateTimeG);
    93         pUpdateTime->setData(i);
    94         pUpdateTime->setCheckable(true);
    95         pUpdateTimeG->addAction(pUpdateTime);
    96         m_pUpdateTimerMenu->addAction(pUpdateTime);
    97         m_actions[static_cast<PreviewUpdateIntervalType>(i)] = pUpdateTime;
    98     }
    99     m_pUpdateTimerMenu->insertSeparator(m_actions[static_cast<PreviewUpdateIntervalType>(PreviewUpdateIntervalType_500ms)]);
    100 
    101     /* Initialize with the new update interval: */
    102     setUpdateInterval(gEDataManager->selectorWindowPreviewUpdateInterval(), false);
    103 
    104     /* Setup connections: */
    105     connect(m_pUpdateTimer, SIGNAL(timeout()), this, SLOT(sltRecreatePreview()));
    106     connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QUuid, KMachineState)),
    107             this, SLOT(sltMachineStateChange(QUuid)));
    108 
    109     /* Retranslate the UI */
    110     retranslateUi();
     51    prepare();
    11152}
    11253
    11354UIMachinePreview::~UIMachinePreview()
    11455{
    115     /* Close any open session: */
    116     if (m_session.GetState() == KSessionState_Locked)
    117         m_session.UnlockMachine();
    118 
    119     /* Destroy background images: */
    120     foreach (const AspectRatioPreset &preset, m_emptyPixmaps.keys())
    121     {
    122         delete m_emptyPixmaps.value(preset);
    123         m_emptyPixmaps.remove(preset);
    124     }
    125     foreach (const AspectRatioPreset &preset, m_fullPixmaps.keys())
    126     {
    127         delete m_fullPixmaps.value(preset);
    128         m_fullPixmaps.remove(preset);
    129     }
    130 
    131     /* Destroy preview image: */
    132     if (m_pPreviewImg)
    133         delete m_pPreviewImg;
    134 
    135     /* Destroy update timer: */
    136     if (m_pUpdateTimerMenu)
    137         delete m_pUpdateTimerMenu;
    138 }
    139 
    140 void UIMachinePreview::setMachine(const CMachine& machine)
     56    cleanup();
     57}
     58
     59void UIMachinePreview::setMachine(const CMachine& comMachine)
    14160{
    14261    /* Pause: */
     
    14463
    14564    /* Assign new machine: */
    146     m_machine = machine;
     65    m_comMachine = comMachine;
    14766
    14867    /* Fetch machine data: */
    14968    m_strPreviewName = tr("No preview");
    150     if (!m_machine.isNull())
    151         m_strPreviewName = m_machine.GetAccessible() ? m_machine.GetName() :
     69    if (!m_comMachine.isNull())
     70        m_strPreviewName = m_comMachine.GetAccessible() ? m_comMachine.GetName() :
    15271                           QApplication::translate("UIVMListView", "Inaccessible");
    15372
     
    15877CMachine UIMachinePreview::machine() const
    15978{
    160     return m_machine;
     79    return m_comMachine;
     80}
     81
     82void UIMachinePreview::retranslateUi()
     83{
     84    /* Translate actions: */
     85    m_actions.value(PreviewUpdateIntervalType_Disabled)->setText(tr("Update disabled"));
     86    m_actions.value(PreviewUpdateIntervalType_500ms)->setText(tr("Every 0.5 s"));
     87    m_actions.value(PreviewUpdateIntervalType_1000ms)->setText(tr("Every 1 s"));
     88    m_actions.value(PreviewUpdateIntervalType_2000ms)->setText(tr("Every 2 s"));
     89    m_actions.value(PreviewUpdateIntervalType_5000ms)->setText(tr("Every 5 s"));
     90    m_actions.value(PreviewUpdateIntervalType_10000ms)->setText(tr("Every 10 s"));
     91}
     92
     93void UIMachinePreview::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
     94{
     95    recalculatePreviewRectangle();
     96    sltRecreatePreview();
     97
     98    /* Call to base-class: */
     99    QIGraphicsWidget::resizeEvent(pEvent);
     100}
     101
     102void UIMachinePreview::showEvent(QShowEvent *pEvent)
     103{
     104    restart();
     105
     106    /* Call to base-class: */
     107    QIGraphicsWidget::showEvent(pEvent);
     108}
     109
     110void UIMachinePreview::hideEvent(QHideEvent *pEvent)
     111{
     112    stop();
     113
     114    /* Call to base-class: */
     115    QIGraphicsWidget::hideEvent(pEvent);
     116}
     117
     118void UIMachinePreview::contextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent)
     119{
     120    QAction *pReturn = m_pUpdateTimerMenu->exec(pEvent->screenPos(), 0);
     121    if (pReturn)
     122    {
     123        PreviewUpdateIntervalType enmInterval = static_cast<PreviewUpdateIntervalType>(pReturn->data().toInt());
     124        setUpdateInterval(enmInterval, true);
     125        restart();
     126    }
     127}
     128
     129void UIMachinePreview::paint(QPainter *pPainter, const QStyleOptionGraphicsItem*, QWidget*)
     130{
     131    /* Where should the content go: */
     132    QRect cr = contentsRect().toRect();
     133    if (!cr.isValid())
     134        return;
     135
     136    /* If there is a preview image available: */
     137    if (m_pPreviewImg)
     138    {
     139        /* Draw empty monitor frame: */
     140        pPainter->drawPixmap(cr.x() + m_iMargin, cr.y() + m_iMargin, *m_emptyPixmaps.value(m_enmPreset));
     141
     142        /* Move image to viewport center: */
     143        QRect imageRect(QPoint(0, 0), m_pPreviewImg->size());
     144        imageRect.moveCenter(m_vRect.center());
     145
     146#ifdef VBOX_WS_MAC
     147        /* Set composition-mode to opaque: */
     148        pPainter->setCompositionMode(QPainter::CompositionMode_Source);
     149        /* Replace translucent background with black one: */
     150        pPainter->fillRect(imageRect, QColor(Qt::black));
     151        /* Return default composition-mode back: */
     152        pPainter->setCompositionMode(QPainter::CompositionMode_SourceAtop);
     153#endif /* VBOX_WS_MAC */
     154
     155        /* Draw preview image: */
     156        pPainter->drawImage(imageRect.topLeft(), *m_pPreviewImg);
     157    }
     158    else
     159    {
     160        /* Draw full monitor frame: */
     161        pPainter->drawPixmap(cr.x() + m_iMargin, cr.y() + m_iMargin, *m_fullPixmaps.value(m_enmPreset));
     162
     163        /* Paint preview name: */
     164        QFont font = pPainter->font();
     165        font.setBold(true);
     166        int fFlags = Qt::AlignCenter | Qt::TextWordWrap;
     167        float h = m_vRect.size().height() * .2;
     168        QRect r;
     169        /* Make a little magic to find out if the given text fits into our rectangle.
     170         * Decrease the font pixel size as long as it doesn't fit. */
     171        int cMax = 30;
     172        do
     173        {
     174            h = h * .8;
     175            font.setPixelSize((int)h);
     176            pPainter->setFont(font);
     177            r = pPainter->boundingRect(m_vRect, fFlags, m_strPreviewName);
     178        }
     179        while ((r.height() > m_vRect.height() || r.width() > m_vRect.width()) && cMax-- != 0);
     180        pPainter->setPen(Qt::white);
     181        pPainter->drawText(m_vRect, fFlags, m_strPreviewName);
     182    }
     183}
     184
     185QSizeF UIMachinePreview::sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint /* = QSizeF() */) const
     186{
     187    if (enmWhich == Qt::MinimumSize)
     188    {
     189        AssertReturn(m_emptyPixmaps.contains(m_enmPreset),
     190                     QIGraphicsWidget::sizeHint(enmWhich, constraint));
     191        QSize size = m_sizes.value(m_enmPreset);
     192        if (m_iMargin != 0)
     193        {
     194            size.setWidth(size.width() - 2 * m_iMargin);
     195            size.setHeight(size.height() - 2 * m_iMargin);
     196        }
     197        return size;
     198    }
     199
     200    /* Call to base-class: */
     201    return QIGraphicsWidget::sizeHint(enmWhich, constraint);
    161202}
    162203
     
    164205{
    165206    /* Make sure its the event for our machine: */
    166     if (m_machine.isNull() || m_machine.GetId() != uId)
     207    if (m_comMachine.isNull() || m_comMachine.GetId() != uId)
    167208        return;
    168209
     
    185226
    186227    /* Fetch actual machine-state: */
    187     const KMachineState machineState = m_machine.isNull() ? KMachineState_Null : m_machine.GetState();
     228    const KMachineState enmMachineState = m_comMachine.isNull() ? KMachineState_Null : m_comMachine.GetState();
    188229
    189230    /* We are creating preview only for assigned and accessible VMs: */
    190     if (!m_machine.isNull() && machineState != KMachineState_Null &&
     231    if (!m_comMachine.isNull() && enmMachineState != KMachineState_Null &&
    191232        m_vRect.width() > 0 && m_vRect.height() > 0)
    192233    {
     
    195236
    196237        /* Use 10x9 as the aspect-ratio preset by default: */
    197         AspectRatioPreset preset = AspectRatioPreset_16x9;
     238        AspectRatioPreset enmPreset = AspectRatioPreset_16x9;
    198239
    199240        /* Preview update enabled? */
     
    201242        {
    202243            /* Depending on machine state: */
    203             switch (machineState)
     244            switch (enmMachineState)
    204245            {
    205246                /* If machine is in SAVED/RESTORING state: */
     
    209250                    /* Use the screenshot from saved-state if possible: */
    210251                    ULONG uGuestWidth = 0, uGuestHeight = 0;
    211                     QVector<BYTE> screenData = m_machine.ReadSavedScreenshotToArray(0, KBitmapFormat_PNG, uGuestWidth, uGuestHeight);
     252                    QVector<BYTE> screenData = m_comMachine.ReadSavedScreenshotToArray(0, KBitmapFormat_PNG, uGuestWidth, uGuestHeight);
    212253
    213254                    /* Make sure screen-data is OK: */
    214                     if (!m_machine.isOk() || screenData.isEmpty())
     255                    if (!m_comMachine.isOk() || screenData.isEmpty())
    215256                        break;
    216257
     
    220261                        const double dAspectRatio = (double)uGuestWidth / uGuestHeight;
    221262                        /* Look for the best aspect-ratio preset: */
    222                         preset = bestAspectRatioPreset(dAspectRatio, m_ratios);
     263                        enmPreset = bestAspectRatioPreset(dAspectRatio, m_ratios);
    223264                    }
    224265
     
    239280                {
    240281                    /* Make sure session state is Locked: */
    241                     if (m_session.GetState() != KSessionState_Locked)
     282                    if (m_comSession.GetState() != KSessionState_Locked)
    242283                        break;
    243284
    244285                    /* Make sure console is OK: */
    245                     CConsole console = m_session.GetConsole();
    246                     if (!m_session.isOk() || console.isNull())
     286                    CConsole console = m_comSession.GetConsole();
     287                    if (!m_comSession.isOk() || console.isNull())
    247288                        break;
    248289                    /* Make sure display is OK: */
     
    261302                        const double dAspectRatio = (double)uGuestWidth / uGuestHeight;
    262303                        /* Look for the best aspect-ratio preset: */
    263                         preset = bestAspectRatioPreset(dAspectRatio, m_ratios);
     304                        enmPreset = bestAspectRatioPreset(dAspectRatio, m_ratios);
    264305                    }
    265306
     
    289330                    image.detach();
    290331                    /* Dim image to give it required look for PAUSED state: */
    291                     if (machineState == KMachineState_Paused)
     332                    if (enmMachineState == KMachineState_Paused)
    292333                        dimImage(image);
    293334                    break;
     
    308349
    309350        /* If preset changed: */
    310         if (m_preset != preset)
     351        if (m_enmPreset != enmPreset)
    311352        {
    312353            /* Save new preset: */
    313             m_preset = preset;
     354            m_enmPreset = enmPreset;
    314355            /* And update geometry: */
    315356            updateGeometry();
     
    322363}
    323364
    324 void UIMachinePreview::resizeEvent(QGraphicsSceneResizeEvent *pEvent)
    325 {
    326     recalculatePreviewRectangle();
    327     sltRecreatePreview();
    328     QIGraphicsWidget::resizeEvent(pEvent);
    329 }
    330 
    331 void UIMachinePreview::showEvent(QShowEvent *pEvent)
    332 {
    333     restart();
    334     QIGraphicsWidget::showEvent(pEvent);
    335 }
    336 
    337 void UIMachinePreview::hideEvent(QHideEvent *pEvent)
    338 {
    339     stop();
    340     QIGraphicsWidget::hideEvent(pEvent);
    341 }
    342 
    343 void UIMachinePreview::contextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent)
    344 {
    345     QAction *pReturn = m_pUpdateTimerMenu->exec(pEvent->screenPos(), 0);
    346     if (pReturn)
    347     {
    348         PreviewUpdateIntervalType interval = static_cast<PreviewUpdateIntervalType>(pReturn->data().toInt());
    349         setUpdateInterval(interval, true);
    350         restart();
    351     }
    352 }
    353 
    354 void UIMachinePreview::retranslateUi()
    355 {
    356     m_actions.value(PreviewUpdateIntervalType_Disabled)->setText(tr("Update disabled"));
    357     m_actions.value(PreviewUpdateIntervalType_500ms)->setText(tr("Every 0.5 s"));
    358     m_actions.value(PreviewUpdateIntervalType_1000ms)->setText(tr("Every 1 s"));
    359     m_actions.value(PreviewUpdateIntervalType_2000ms)->setText(tr("Every 2 s"));
    360     m_actions.value(PreviewUpdateIntervalType_5000ms)->setText(tr("Every 5 s"));
    361     m_actions.value(PreviewUpdateIntervalType_10000ms)->setText(tr("Every 10 s"));
    362 }
    363 
    364 QSizeF UIMachinePreview::sizeHint(Qt::SizeHint which, const QSizeF &constraint /* = QSizeF() */) const
    365 {
    366     if (which == Qt::MinimumSize)
    367     {
    368         AssertReturn(m_emptyPixmaps.contains(m_preset),
    369                      QIGraphicsWidget::sizeHint(which, constraint));
    370         QSize size = m_sizes.value(m_preset);
    371         if (m_iMargin != 0)
    372         {
    373             size.setWidth(size.width() - 2 * m_iMargin);
    374             size.setHeight(size.height() - 2 * m_iMargin);
    375         }
    376         return size;
    377     }
    378     return QIGraphicsWidget::sizeHint(which, constraint);
    379 }
    380 
    381 void UIMachinePreview::paint(QPainter *pPainter, const QStyleOptionGraphicsItem*, QWidget*)
    382 {
    383     /* Where should the content go: */
    384     QRect cr = contentsRect().toRect();
    385     if (!cr.isValid())
    386         return;
    387 
    388     /* If there is a preview image available: */
     365void UIMachinePreview::prepare()
     366{
     367    /* Create session instance: */
     368    m_comSession.createInstance(CLSID_Session);
     369
     370    /* Cache aspect-ratio preset settings: */
     371    const QIcon empty16x10 = UIIconPool::iconSet(":/preview_empty_16to10_242x167px.png");
     372    const QIcon empty16x9 = UIIconPool::iconSet(":/preview_empty_16to9_242x155px.png");
     373    const QIcon empty4x3 = UIIconPool::iconSet(":/preview_empty_4to3_242x192px.png");
     374    const QIcon full16x10 = UIIconPool::iconSet(":/preview_full_16to10_242x167px.png");
     375    const QIcon full16x9 = UIIconPool::iconSet(":/preview_full_16to9_242x155px.png");
     376    const QIcon full4x3 = UIIconPool::iconSet(":/preview_full_4to3_242x192px.png");
     377
     378    // WORKAROUND:
     379    // Since we don't have x3 and x4 HiDPI icons yet,
     380    // and we hadn't enabled automatic up-scaling for now,
     381    // we have to make sure m_dRatio is within possible bounds.
     382    const QList<QSize> sizes = empty16x10.availableSizes();
     383    if (sizes.size() >= 2)
     384        m_dRatio = qMin(m_dRatio, (double)sizes.last().width() / sizes.first().width());
     385
     386    m_sizes.insert(AspectRatioPreset_16x10, QSize(242 * m_dRatio, 167 * m_dRatio));
     387    m_sizes.insert(AspectRatioPreset_16x9, QSize(242 * m_dRatio, 155 * m_dRatio));
     388    m_sizes.insert(AspectRatioPreset_4x3, QSize(242 * m_dRatio, 192 * m_dRatio));
     389    m_ratios.insert(AspectRatioPreset_16x10, (double)16/10);
     390    m_ratios.insert(AspectRatioPreset_16x9, (double)16/9);
     391    m_ratios.insert(AspectRatioPreset_4x3, (double)4/3);
     392    m_emptyPixmaps.insert(AspectRatioPreset_16x10, new QPixmap(empty16x10.pixmap(m_sizes.value(AspectRatioPreset_16x10))));
     393    m_emptyPixmaps.insert(AspectRatioPreset_16x9, new QPixmap(empty16x9.pixmap(m_sizes.value(AspectRatioPreset_16x9))));
     394    m_emptyPixmaps.insert(AspectRatioPreset_4x3, new QPixmap(empty4x3.pixmap(m_sizes.value(AspectRatioPreset_4x3))));
     395    m_fullPixmaps.insert(AspectRatioPreset_16x10, new QPixmap(full16x10.pixmap(m_sizes.value(AspectRatioPreset_16x10))));
     396    m_fullPixmaps.insert(AspectRatioPreset_16x9, new QPixmap(full16x9.pixmap(m_sizes.value(AspectRatioPreset_16x9))));
     397    m_fullPixmaps.insert(AspectRatioPreset_4x3, new QPixmap(full4x3.pixmap(m_sizes.value(AspectRatioPreset_4x3))));
     398
     399    /* Setup contents (depends on presets above!): */
     400    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
     401
     402    /* Create the context menu: */
     403    m_pUpdateTimerMenu = new QMenu;
     404    QActionGroup *pUpdateTimeG = new QActionGroup(this);
     405    pUpdateTimeG->setExclusive(true);
     406    for(int i = 0; i < PreviewUpdateIntervalType_Max; ++i)
     407    {
     408        QAction *pUpdateTime = new QAction(pUpdateTimeG);
     409        pUpdateTime->setData(i);
     410        pUpdateTime->setCheckable(true);
     411        pUpdateTimeG->addAction(pUpdateTime);
     412        m_pUpdateTimerMenu->addAction(pUpdateTime);
     413        m_actions[static_cast<PreviewUpdateIntervalType>(i)] = pUpdateTime;
     414    }
     415    m_pUpdateTimerMenu->insertSeparator(m_actions[static_cast<PreviewUpdateIntervalType>(PreviewUpdateIntervalType_500ms)]);
     416
     417    /* Initialize with the new update interval: */
     418    setUpdateInterval(gEDataManager->selectorWindowPreviewUpdateInterval(), false);
     419
     420    /* Setup connections: */
     421    connect(m_pUpdateTimer, SIGNAL(timeout()), this, SLOT(sltRecreatePreview()));
     422    connect(gVBoxEvents, SIGNAL(sigMachineStateChange(QUuid, KMachineState)),
     423            this, SLOT(sltMachineStateChange(QUuid)));
     424
     425    /* Retranslate the UI */
     426    retranslateUi();
     427}
     428
     429void UIMachinePreview::cleanup()
     430{
     431    /* Close any open session: */
     432    if (m_comSession.GetState() == KSessionState_Locked)
     433        m_comSession.UnlockMachine();
     434
     435    /* Destroy background images: */
     436    foreach (const AspectRatioPreset &enmPreset, m_emptyPixmaps.keys())
     437    {
     438        delete m_emptyPixmaps.value(enmPreset);
     439        m_emptyPixmaps.remove(enmPreset);
     440    }
     441    foreach (const AspectRatioPreset &enmPreset, m_fullPixmaps.keys())
     442    {
     443        delete m_fullPixmaps.value(enmPreset);
     444        m_fullPixmaps.remove(enmPreset);
     445    }
     446
     447    /* Destroy preview image: */
    389448    if (m_pPreviewImg)
    390     {
    391         /* Draw empty monitor frame: */
    392         pPainter->drawPixmap(cr.x() + m_iMargin, cr.y() + m_iMargin, *m_emptyPixmaps.value(m_preset));
    393 
    394         /* Move image to viewport center: */
    395         QRect imageRect(QPoint(0, 0), m_pPreviewImg->size());
    396         imageRect.moveCenter(m_vRect.center());
    397 
    398 #ifdef VBOX_WS_MAC
    399         /* Set composition-mode to opaque: */
    400         pPainter->setCompositionMode(QPainter::CompositionMode_Source);
    401         /* Replace translucent background with black one: */
    402         pPainter->fillRect(imageRect, QColor(Qt::black));
    403         /* Return default composition-mode back: */
    404         pPainter->setCompositionMode(QPainter::CompositionMode_SourceAtop);
    405 #endif /* VBOX_WS_MAC */
    406 
    407         /* Draw preview image: */
    408         pPainter->drawImage(imageRect.topLeft(), *m_pPreviewImg);
    409     }
    410     else
    411     {
    412         /* Draw full monitor frame: */
    413         pPainter->drawPixmap(cr.x() + m_iMargin, cr.y() + m_iMargin, *m_fullPixmaps.value(m_preset));
    414 
    415         /* Paint preview name: */
    416         QFont font = pPainter->font();
    417         font.setBold(true);
    418         int fFlags = Qt::AlignCenter | Qt::TextWordWrap;
    419         float h = m_vRect.size().height() * .2;
    420         QRect r;
    421         /* Make a little magic to find out if the given text fits into our rectangle.
    422          * Decrease the font pixel size as long as it doesn't fit. */
    423         int cMax = 30;
    424         do
    425         {
    426             h = h * .8;
    427             font.setPixelSize((int)h);
    428             pPainter->setFont(font);
    429             r = pPainter->boundingRect(m_vRect, fFlags, m_strPreviewName);
    430         }
    431         while ((r.height() > m_vRect.height() || r.width() > m_vRect.width()) && cMax-- != 0);
    432         pPainter->setPen(Qt::white);
    433         pPainter->drawText(m_vRect, fFlags, m_strPreviewName);
    434     }
     449        delete m_pPreviewImg;
     450
     451    /* Destroy update timer: */
     452    if (m_pUpdateTimerMenu)
     453        delete m_pUpdateTimerMenu;
    435454}
    436455
     
    476495{
    477496    /* Fetch the latest machine-state: */
    478     KMachineState machineState = m_machine.isNull() ? KMachineState_Null : m_machine.GetState();
     497    KMachineState enmMachineState = m_comMachine.isNull() ? KMachineState_Null : m_comMachine.GetState();
    479498
    480499    /* Reopen session if necessary: */
    481     if (m_session.GetState() == KSessionState_Locked)
    482         m_session.UnlockMachine();
    483     if (!m_machine.isNull())
     500    if (m_comSession.GetState() == KSessionState_Locked)
     501        m_comSession.UnlockMachine();
     502    if (!m_comMachine.isNull())
    484503    {
    485504        /* Lock the session for the current machine: */
    486         if (machineState == KMachineState_Running || machineState == KMachineState_Paused)
    487             m_machine.LockMachine(m_session, KLockType_Shared);
     505        if (enmMachineState == KMachineState_Running || enmMachineState == KMachineState_Paused)
     506            m_comMachine.LockMachine(m_comSession, KLockType_Shared);
    488507    }
    489508
     
    492511
    493512    /* Start the timer if necessary: */
    494     if (!m_machine.isNull())
    495     {
    496         if (m_pUpdateTimer->interval() > 0 && machineState == KMachineState_Running)
     513    if (!m_comMachine.isNull())
     514    {
     515        if (m_pUpdateTimer->interval() > 0 && enmMachineState == KMachineState_Running)
    497516            m_pUpdateTimer->start();
    498517    }
     
    507526/* static */
    508527UIMachinePreview::AspectRatioPreset UIMachinePreview::bestAspectRatioPreset(const double dAspectRatio,
    509                                                                               const QMap<AspectRatioPreset, double> &ratios)
     528                                                                            const QMap<AspectRatioPreset, double> &ratios)
    510529{
    511530    /* Use 16x9 preset as the 'best' by 'default': */
     
    568587    return QSize(iWidth, iHeight);
    569588}
    570 
  • trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIMachinePreview.h

    r76581 r79860  
    3232/* COM includes: */
    3333#include "COMEnums.h"
     34#include "CMachine.h"
    3435#include "CSession.h"
    35 #include "CMachine.h"
    3636
    3737/* Forward declarations: */
     
    4242class QTimer;
    4343
    44 /* Preview window class: */
     44/** QIGraphicsWidget sub-class used as VM Preview widget inside Details pane. */
    4545class UIMachinePreview : public QIWithRetranslateUI4<QIGraphicsWidget>
    4646{
     
    4949signals:
    5050
    51     /** Notifies about size-hint changes. */
    52     void sigSizeHintChanged();
     51    /** @name Layout stuff.
     52      * @{ */
     53        /** Notifies about size-hint changes. */
     54        void sigSizeHintChanged();
     55    /** @} */
    5356
    5457public:
    5558
    56     /* Graphics-item type: */
     59    /** RTTI item type. */
    5760    enum { Type = UIDetailsItemType_Preview };
    58     int type() const { return Type; }
    59 
    60     /* Constructor/destructor: */
     61
     62    /** Constructs preview element, passing pParent to the base-class. */
    6163    UIMachinePreview(QIGraphicsWidget *pParent);
    62     ~UIMachinePreview();
    63 
    64     /* API: Machine stuff: */
    65     void setMachine(const CMachine& machine);
    66     CMachine machine() const;
     64    /** Destructs preview element. */
     65    virtual ~UIMachinePreview() /* override */;
     66
     67    /** @name Item stuff.
     68      * @{ */
     69        /** Defines @a comMachine to make preview for. */
     70        void setMachine(const CMachine &comMachine);
     71        /** Retuirns machine we do preview for. */
     72        CMachine machine() const;
     73    /** @} */
     74
     75protected:
     76
     77    /** @name Event-handling stuff.
     78      * @{ */
     79        /** Handles translation event. */
     80        virtual void retranslateUi() /* override */;
     81
     82        /** Handles resize @a pEvent. */
     83        virtual void resizeEvent(QGraphicsSceneResizeEvent *pEvent) /* override */;
     84
     85        /** Handles show @a pEvent. */
     86        virtual void showEvent(QShowEvent *pEvent) /* override */;
     87        /** Handles hide @a pEvent. */
     88        virtual void hideEvent(QHideEvent *pEvent) /* override */;
     89
     90        /** Handles context-menu @a pEvent. */
     91        virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent) /* override */;
     92
     93        /** Performs painting using passed @a pPainter, @a pOptions and optionally specified @a pWidget. */
     94        virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOptions, QWidget *pWidget = 0) /* override */;
     95    /** @} */
     96
     97    /** @name Item stuff.
     98      * @{ */
     99        /** Returns RTTI item type. */
     100        virtual int type() const /* override */ { return Type; }
     101    /** @} */
     102
     103    /** @name Layout stuff.
     104      * @{ */
     105        /** Returns size-hint.
     106          * @param  enmWhich    Brings size-hint type.
     107          * @param  constraint  Brings size constraint. */
     108        virtual QSizeF sizeHint(Qt::SizeHint enmWhich, const QSizeF &constraint = QSizeF()) const /* override */;
     109    /** @} */
    67110
    68111private slots:
    69112
    70     /* Handler: Global-event listener stuff: */
    71     void sltMachineStateChange(const QUuid &uId);
    72 
    73     /* Handler: Preview recreator: */
    74     void sltRecreatePreview();
     113    /** @name Event-handling stuff.
     114      * @{ */
     115        /** Handles machine-state change for item with @a uId. */
     116        void sltMachineStateChange(const QUuid &uId);
     117    /** @} */
     118
     119    /** @name Item stuff.
     120      * @{ */
     121        /** Handles request to recreate preview. */
     122        void sltRecreatePreview();
     123    /** @} */
    75124
    76125private:
     
    84133    };
    85134
    86     /* Helpers: Event handlers: */
    87     void resizeEvent(QGraphicsSceneResizeEvent *pEvent);
    88     void showEvent(QShowEvent *pEvent);
    89     void hideEvent(QHideEvent *pEvent);
    90     void contextMenuEvent(QGraphicsSceneContextMenuEvent *pEvent);
    91 
    92     /* Helpers: Translate stuff; */
    93     void retranslateUi();
    94 
    95     /* Helpers: Layout stuff: */
    96     QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
    97 
    98     /* Helpers: Paint stuff: */
    99     void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
    100 
    101     /* Helpers: Update stuff: */
    102     void setUpdateInterval(PreviewUpdateIntervalType interval, bool fSave);
    103     void recalculatePreviewRectangle();
    104     void restart();
    105     void stop();
     135    /** @name Prepare/cleanup cascade.
     136      * @{ */
     137        /** Prepares all. */
     138        void prepare();
     139
     140        /** Cleanups all. */
     141        void cleanup();
     142    /** @} */
     143
     144    /** @name Item stuff.
     145      * @{ */
     146        /** Define update @a enmInterval, @a fSave it if requested. */
     147        void setUpdateInterval(PreviewUpdateIntervalType enmInterval, bool fSave);
     148
     149        /** Recalculates preview rectangle. */
     150        void recalculatePreviewRectangle();
     151
     152        /** Restarts preview uppdate routine. */
     153        void restart();
     154        /** Stops preview uppdate routine. */
     155        void stop();
     156    /** @} */
    106157
    107158    /** Looks for the best aspect-ratio preset for the passed @a dAspectRatio among all the passed @a ratios. */
     
    110161    static QSize imageAspectRatioSize(const QSize &hostSize, const QSize &guestSize);
    111162
    112     /* Variables: */
    113     CSession m_session;
    114     CMachine m_machine;
    115     QTimer *m_pUpdateTimer;
    116     QMenu *m_pUpdateTimerMenu;
    117     QHash<PreviewUpdateIntervalType, QAction*> m_actions;
    118     double m_dRatio;
    119     const int m_iMargin;
    120     QRect m_vRect;
    121     AspectRatioPreset m_preset;
    122     QMap<AspectRatioPreset, QSize> m_sizes;
    123     QMap<AspectRatioPreset, double> m_ratios;
    124     QMap<AspectRatioPreset, QPixmap*> m_emptyPixmaps;
    125     QMap<AspectRatioPreset, QPixmap*> m_fullPixmaps;
    126     QImage *m_pPreviewImg;
    127     QString m_strPreviewName;
     163    /** @name Item stuff.
     164      * @{ */
     165        /** Holds the session reference. */
     166        CSession  m_comSession;
     167        /** Holds the machine reference. */
     168        CMachine  m_comMachine;
     169
     170        /** Holds the update timer instance. */
     171        QTimer                                     *m_pUpdateTimer;
     172        /** Holds the update timer menu instance. */
     173        QMenu                                      *m_pUpdateTimerMenu;
     174        /** Holds the update timer menu action list. */
     175        QHash<PreviewUpdateIntervalType, QAction*>  m_actions;
     176    /** @} */
     177
     178    /** @name Layout stuff.
     179      * @{ */
     180        /** Holds the aspect-ratio of the preview. */
     181        double     m_dRatio;
     182        /** Holds the layout margin. */
     183        const int  m_iMargin;
     184        /** Holds the viewport rectangle. */
     185        QRect      m_vRect;
     186
     187        /** Holds the current aspect-ratio preset. */
     188        AspectRatioPreset                  m_enmPreset;
     189        /** Holds the aspect-ratio preset sizes. */
     190        QMap<AspectRatioPreset, QSize>     m_sizes;
     191        /** Holds the aspect-ratio preset ratios. */
     192        QMap<AspectRatioPreset, double>    m_ratios;
     193        /** Holds the aspect-ratio preset empty pixmaps. */
     194        QMap<AspectRatioPreset, QPixmap*>  m_emptyPixmaps;
     195        /** Holds the aspect-ratio preset filled pixmaps. */
     196        QMap<AspectRatioPreset, QPixmap*>  m_fullPixmaps;
     197    /** @} */
     198
     199    /** @name Painting stuff.
     200      * @{ */
     201        /** Holds the preview image instance. */
     202        QImage  *m_pPreviewImg;
     203        /** Holds the preview name. */
     204        QString  m_strPreviewName;
     205    /** @} */
    128206};
    129207
    130208#endif /* !FEQT_INCLUDED_SRC_manager_details_UIMachinePreview_h */
    131 
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