Changeset 79860 in vbox for trunk/src/VBox
- Timestamp:
- Jul 18, 2019 3:47:48 PM (5 years ago)
- 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 46 46 , m_dRatio((double)QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize) / 16) 47 47 , m_iMargin(0) 48 , m_ preset(AspectRatioPreset_16x9)48 , m_enmPreset(AspectRatioPreset_16x9) 49 49 , m_pPreviewImg(0) 50 50 { 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(); 111 52 } 112 53 113 54 UIMachinePreview::~UIMachinePreview() 114 55 { 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 59 void UIMachinePreview::setMachine(const CMachine& comMachine) 141 60 { 142 61 /* Pause: */ … … 144 63 145 64 /* Assign new machine: */ 146 m_ machine = machine;65 m_comMachine = comMachine; 147 66 148 67 /* Fetch machine data: */ 149 68 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() : 152 71 QApplication::translate("UIVMListView", "Inaccessible"); 153 72 … … 158 77 CMachine UIMachinePreview::machine() const 159 78 { 160 return m_machine; 79 return m_comMachine; 80 } 81 82 void 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 93 void UIMachinePreview::resizeEvent(QGraphicsSceneResizeEvent *pEvent) 94 { 95 recalculatePreviewRectangle(); 96 sltRecreatePreview(); 97 98 /* Call to base-class: */ 99 QIGraphicsWidget::resizeEvent(pEvent); 100 } 101 102 void UIMachinePreview::showEvent(QShowEvent *pEvent) 103 { 104 restart(); 105 106 /* Call to base-class: */ 107 QIGraphicsWidget::showEvent(pEvent); 108 } 109 110 void UIMachinePreview::hideEvent(QHideEvent *pEvent) 111 { 112 stop(); 113 114 /* Call to base-class: */ 115 QIGraphicsWidget::hideEvent(pEvent); 116 } 117 118 void 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 129 void 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 185 QSizeF 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); 161 202 } 162 203 … … 164 205 { 165 206 /* 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) 167 208 return; 168 209 … … 185 226 186 227 /* 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(); 188 229 189 230 /* 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 && 191 232 m_vRect.width() > 0 && m_vRect.height() > 0) 192 233 { … … 195 236 196 237 /* Use 10x9 as the aspect-ratio preset by default: */ 197 AspectRatioPreset preset = AspectRatioPreset_16x9;238 AspectRatioPreset enmPreset = AspectRatioPreset_16x9; 198 239 199 240 /* Preview update enabled? */ … … 201 242 { 202 243 /* Depending on machine state: */ 203 switch ( machineState)244 switch (enmMachineState) 204 245 { 205 246 /* If machine is in SAVED/RESTORING state: */ … … 209 250 /* Use the screenshot from saved-state if possible: */ 210 251 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); 212 253 213 254 /* Make sure screen-data is OK: */ 214 if (!m_ machine.isOk() || screenData.isEmpty())255 if (!m_comMachine.isOk() || screenData.isEmpty()) 215 256 break; 216 257 … … 220 261 const double dAspectRatio = (double)uGuestWidth / uGuestHeight; 221 262 /* Look for the best aspect-ratio preset: */ 222 preset = bestAspectRatioPreset(dAspectRatio, m_ratios);263 enmPreset = bestAspectRatioPreset(dAspectRatio, m_ratios); 223 264 } 224 265 … … 239 280 { 240 281 /* Make sure session state is Locked: */ 241 if (m_ session.GetState() != KSessionState_Locked)282 if (m_comSession.GetState() != KSessionState_Locked) 242 283 break; 243 284 244 285 /* 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()) 247 288 break; 248 289 /* Make sure display is OK: */ … … 261 302 const double dAspectRatio = (double)uGuestWidth / uGuestHeight; 262 303 /* Look for the best aspect-ratio preset: */ 263 preset = bestAspectRatioPreset(dAspectRatio, m_ratios);304 enmPreset = bestAspectRatioPreset(dAspectRatio, m_ratios); 264 305 } 265 306 … … 289 330 image.detach(); 290 331 /* Dim image to give it required look for PAUSED state: */ 291 if ( machineState == KMachineState_Paused)332 if (enmMachineState == KMachineState_Paused) 292 333 dimImage(image); 293 334 break; … … 308 349 309 350 /* If preset changed: */ 310 if (m_ preset != preset)351 if (m_enmPreset != enmPreset) 311 352 { 312 353 /* Save new preset: */ 313 m_ preset = preset;354 m_enmPreset = enmPreset; 314 355 /* And update geometry: */ 315 356 updateGeometry(); … … 322 363 } 323 364 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: */ 365 void 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 429 void 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: */ 389 448 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; 435 454 } 436 455 … … 476 495 { 477 496 /* 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(); 479 498 480 499 /* 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()) 484 503 { 485 504 /* 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); 488 507 } 489 508 … … 492 511 493 512 /* 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) 497 516 m_pUpdateTimer->start(); 498 517 } … … 507 526 /* static */ 508 527 UIMachinePreview::AspectRatioPreset UIMachinePreview::bestAspectRatioPreset(const double dAspectRatio, 509 528 const QMap<AspectRatioPreset, double> &ratios) 510 529 { 511 530 /* Use 16x9 preset as the 'best' by 'default': */ … … 568 587 return QSize(iWidth, iHeight); 569 588 } 570 -
trunk/src/VBox/Frontends/VirtualBox/src/manager/details/UIMachinePreview.h
r76581 r79860 32 32 /* COM includes: */ 33 33 #include "COMEnums.h" 34 #include "CMachine.h" 34 35 #include "CSession.h" 35 #include "CMachine.h"36 36 37 37 /* Forward declarations: */ … … 42 42 class QTimer; 43 43 44 /* Preview window class:*/44 /** QIGraphicsWidget sub-class used as VM Preview widget inside Details pane. */ 45 45 class UIMachinePreview : public QIWithRetranslateUI4<QIGraphicsWidget> 46 46 { … … 49 49 signals: 50 50 51 /** Notifies about size-hint changes. */ 52 void sigSizeHintChanged(); 51 /** @name Layout stuff. 52 * @{ */ 53 /** Notifies about size-hint changes. */ 54 void sigSizeHintChanged(); 55 /** @} */ 53 56 54 57 public: 55 58 56 /* Graphics-item type:*/59 /** RTTI item type. */ 57 60 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. */ 61 63 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 75 protected: 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 /** @} */ 67 110 68 111 private slots: 69 112 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 /** @} */ 75 124 76 125 private: … … 84 133 }; 85 134 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 /** @} */ 106 157 107 158 /** Looks for the best aspect-ratio preset for the passed @a dAspectRatio among all the passed @a ratios. */ … … 110 161 static QSize imageAspectRatioSize(const QSize &hostSize, const QSize &guestSize); 111 162 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 /** @} */ 128 206 }; 129 207 130 208 #endif /* !FEQT_INCLUDED_SRC_manager_details_UIMachinePreview_h */ 131
Note:
See TracChangeset
for help on using the changeset viewer.