- Timestamp:
- Aug 4, 2017 10:30:55 AM (7 years ago)
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/widgets
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UITabBar.cpp
r68296 r68298 22 22 /* Qt includes: */ 23 23 # include <QApplication> 24 # include <QDrag> 25 # include <QDragEnterEvent> 26 # include <QDragMoveEvent> 27 # include <QDropEvent> 24 28 # include <QEvent> 25 29 # include <QHBoxLayout> 26 30 # include <QLabel> 31 # include <QMimeData> 27 32 # include <QMouseEvent> 33 # include <QStyleOption> 28 34 # include <QPainter> 29 35 # ifdef VBOX_WS_MAC … … 43 49 /* Forward declarations: */ 44 50 class QApplication; 51 class QDrag; 45 52 class QEvent; 46 53 class QHBoxLayout; 47 54 class QLabel; 55 class QMimeData; 48 56 class QMouseEvent; 49 57 #ifdef VBOX_WS_MAC … … 51 59 #endif 52 60 class QStyle; 61 class QStyleOption; 53 62 class QToolButton; 54 63 … … 67 76 void sigCloseClicked(UITabBarItem *pItem); 68 77 78 /** Notifies about drag-object destruction. */ 79 void sigDragObjectDestroy(); 80 69 81 public: 82 83 /** Holds the mime-type for the D&D system. */ 84 static const QString MimeType; 70 85 71 86 /** Creates tab-bar item on the basis of passed @a uuid, @a icon and @a strName. */ … … 87 102 virtual void paintEvent(QPaintEvent *pEvent) /* override */; 88 103 104 /** Handles mouse-press @a pEvent. */ 105 virtual void mousePressEvent(QMouseEvent *pEvent) /* override */; 89 106 /** Handles mouse-release @a pEvent. */ 90 107 virtual void mouseReleaseEvent(QMouseEvent *pEvent) /* override */; 108 /** Handles mouse-move @a pEvent. */ 109 virtual void mouseMoveEvent(QMouseEvent *pEvent) /* override */; 91 110 /** Handles mouse-enter @a pEvent. */ 92 111 virtual void enterEvent(QEvent *pEvent) /* override */; … … 129 148 /** Holds the close button instance. */ 130 149 QToolButton *m_pButtonClose; 150 151 /** Holds the last mouse-press position. */ 152 QPoint m_mousePressPosition; 131 153 }; 132 154 … … 135 157 * Class UITabBarItem implementation. * 136 158 *********************************************************************************************************************************/ 159 160 /* static */ 161 const QString UITabBarItem::MimeType = QString("application/virtualbox;value=TabID"); 137 162 138 163 UITabBarItem::UITabBarItem(const QUuid &uuid, const QIcon &icon /* = QIcon() */, const QString &strName /* = QString() */) … … 247 272 } 248 273 274 void UITabBarItem::mousePressEvent(QMouseEvent *pEvent) 275 { 276 /* We are interested in left button only: */ 277 if (pEvent->button() != Qt::LeftButton) 278 return QWidget::mousePressEvent(pEvent); 279 280 /* Remember mouse-press position: */ 281 m_mousePressPosition = pEvent->globalPos(); 282 } 283 249 284 void UITabBarItem::mouseReleaseEvent(QMouseEvent *pEvent) 250 285 { … … 253 288 return QWidget::mouseReleaseEvent(pEvent); 254 289 290 /* Forget mouse-press position: */ 291 m_mousePressPosition = QPoint(); 292 255 293 /* Notify listeners about the item was clicked: */ 256 294 emit sigClicked(this); 295 } 296 297 void UITabBarItem::mouseMoveEvent(QMouseEvent *pEvent) 298 { 299 /* Make sure item isn't already dragged: */ 300 if (m_mousePressPosition.isNull()) 301 return QWidget::mouseMoveEvent(pEvent); 302 303 /* Make sure item is now being dragged: */ 304 if (QLineF(pEvent->globalPos(), m_mousePressPosition).length() < QApplication::startDragDistance()) 305 return QWidget::mouseMoveEvent(pEvent); 306 307 /* Revoke hovered state: */ 308 m_fHovered = false; 309 /* And call for repaint: */ 310 update(); 311 312 /* Initialize dragging: */ 313 m_mousePressPosition = QPoint(); 314 QDrag *pDrag = new QDrag(this); 315 connect(pDrag, &QObject::destroyed, this, &UITabBarItem::sigDragObjectDestroy); 316 QMimeData *pMimeData = new QMimeData; 317 pMimeData->setData(MimeType, uuid().toByteArray()); 318 pDrag->setMimeData(pMimeData); 319 const int iMetric = QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize); 320 pDrag->setPixmap(icon().pixmap(iMetric, iMetric)); 321 pDrag->exec(); 257 322 } 258 323 … … 385 450 , m_pLayoutTab(0) 386 451 , m_pCurrentItem(0) 452 , m_pItemToken(0) 453 , m_fDropAfterTokenItem(0) 387 454 { 388 455 /* Prepare: */ … … 399 466 { 400 467 /* Configure item: */ 401 connect(pItem, &UITabBarItem::sigClicked, this, &UITabBar::sltHandleMakeChildCurrent); 402 connect(pItem, &UITabBarItem::sigCloseClicked, this, &UITabBar::sltHandleChildClose); 468 connect(pItem, &UITabBarItem::sigClicked, this, &UITabBar::sltHandleMakeChildCurrent); 469 connect(pItem, &UITabBarItem::sigCloseClicked, this, &UITabBar::sltHandleChildClose); 470 connect(pItem, &UITabBarItem::sigDragObjectDestroy, this, &UITabBar::sltHandleDragObjectDestroy); 403 471 /* Add item into layout and list: */ 404 472 m_pLayoutTab->insertWidget(0, pItem); … … 472 540 } 473 541 542 void UITabBar::paintEvent(QPaintEvent *pEvent) 543 { 544 /* Call to base-class: */ 545 QWidget::paintEvent(pEvent); 546 547 /* If we have a token item: */ 548 if (m_pItemToken) 549 { 550 /* Prepare painter: */ 551 QPainter painter(this); 552 553 /* Paint drop token: */ 554 QStyleOption option; 555 option.state |= QStyle::State_Horizontal; 556 const QRect geo = m_pItemToken->geometry(); 557 option.rect = !m_fDropAfterTokenItem 558 ? QRect(geo.topLeft() - QPoint(5, 5), 559 geo.bottomLeft() + QPoint(0, 5)) 560 : QRect(geo.topRight() - QPoint(0, 5), 561 geo.bottomRight() + QPoint(5, 5)); 562 QApplication::style()->drawPrimitive(QStyle::PE_IndicatorToolBarSeparator, 563 &option, &painter); 564 } 565 } 566 567 void UITabBar::dragEnterEvent(QDragEnterEvent *pEvent) 568 { 569 /* Make sure event is valid: */ 570 AssertPtrReturnVoid(pEvent); 571 /* And mime-data is set: */ 572 const QMimeData *pMimeData = pEvent->mimeData(); 573 AssertPtrReturnVoid(pMimeData); 574 575 /* Make sure mime-data format is valid: */ 576 if (!pMimeData->hasFormat(UITabBarItem::MimeType)) 577 return; 578 579 /* Accept drag-enter event: */ 580 pEvent->acceptProposedAction(); 581 } 582 583 void UITabBar::dragMoveEvent(QDragMoveEvent *pEvent) 584 { 585 /* Make sure event is valid: */ 586 AssertPtrReturnVoid(pEvent); 587 /* And mime-data is set: */ 588 const QMimeData *pMimeData = pEvent->mimeData(); 589 AssertPtrReturnVoid(pMimeData); 590 591 /* Make sure mime-data format is valid: */ 592 if (!pMimeData->hasFormat(UITabBarItem::MimeType)) 593 return; 594 595 /* Reset token: */ 596 m_pItemToken = 0; 597 m_fDropAfterTokenItem = true; 598 599 /* Get event position: */ 600 const QPoint pos = pEvent->pos(); 601 /* Search for most suitable item: */ 602 foreach (UITabBarItem *pItem, m_aItems) 603 { 604 /* Advance token: */ 605 m_pItemToken = pItem; 606 const QRect geo = m_pItemToken->geometry(); 607 if (pos.x() < geo.center().x()) 608 { 609 m_fDropAfterTokenItem = false; 610 break; 611 } 612 } 613 614 /* Update: */ 615 update(); 616 } 617 618 void UITabBar::dragLeaveEvent(QDragLeaveEvent * /* pEvent */) 619 { 620 /* Reset token: */ 621 m_pItemToken = 0; 622 m_fDropAfterTokenItem = true; 623 624 /* Update: */ 625 update(); 626 } 627 628 void UITabBar::dropEvent(QDropEvent *pEvent) 629 { 630 /* Make sure event is valid: */ 631 AssertPtrReturnVoid(pEvent); 632 /* And mime-data is set: */ 633 const QMimeData *pMimeData = pEvent->mimeData(); 634 AssertPtrReturnVoid(pMimeData); 635 636 /* Make sure mime-data format is valid: */ 637 if (!pMimeData->hasFormat(UITabBarItem::MimeType)) 638 return; 639 640 /* Make sure token-item set: */ 641 if (!m_pItemToken) 642 return; 643 644 /* Determine ID of token-item: */ 645 const QUuid tokenUuid = m_pItemToken->uuid(); 646 /* Determine ID of dropped-item: */ 647 const QUuid droppedUuid = pMimeData->data(UITabBarItem::MimeType); 648 649 /* Make sure these uuids are different: */ 650 if (droppedUuid == tokenUuid) 651 return; 652 653 /* Search for an item with dropped ID: */ 654 UITabBarItem *pItemDropped = 0; 655 foreach (UITabBarItem *pItem, m_aItems) 656 { 657 if (pItem->uuid() == droppedUuid) 658 { 659 pItemDropped = pItem; 660 break; 661 } 662 } 663 664 /* Make sure dropped-item found: */ 665 if (!pItemDropped) 666 return; 667 668 /* Remove dropped-item: */ 669 m_aItems.removeAll(pItemDropped); 670 m_pLayoutTab->removeWidget(pItemDropped); 671 /* Insert dropped-item into position of token-item: */ 672 int iPosition = m_aItems.indexOf(m_pItemToken); 673 AssertReturnVoid(iPosition != -1); 674 if (m_fDropAfterTokenItem) 675 ++iPosition; 676 m_aItems.insert(iPosition, pItemDropped); 677 m_pLayoutTab->insertWidget(iPosition, pItemDropped); 678 } 679 474 680 void UITabBar::sltHandleMakeChildCurrent(UITabBarItem *pItem) 475 681 { … … 501 707 } 502 708 709 void UITabBar::sltHandleDragObjectDestroy() 710 { 711 /* Reset token: */ 712 m_pItemToken = 0; 713 m_fDropAfterTokenItem = true; 714 715 /* Update: */ 716 update(); 717 } 718 503 719 void UITabBar::prepare() 504 720 { 721 /* Track D&D events: */ 722 setAcceptDrops(true); 723 505 724 /* Create main layout: */ 506 725 m_pLayoutMain = new QHBoxLayout(this); -
trunk/src/VBox/Frontends/VirtualBox/src/widgets/UITabBar.h
r68295 r68298 26 26 27 27 /* Forward declarations: */ 28 class QDragEnterEvent; 29 class QDragLeaveEvent; 30 class QDragMoveEvent; 31 class QDropEvent; 28 32 class QHBoxLayout; 29 33 class QIcon; 34 class QPaintEvent; 30 35 class QString; 31 36 class QUuid; … … 62 67 bool setCurrent(const QUuid &uuid); 63 68 69 protected: 70 71 /** Handles paint @a pEvent. */ 72 virtual void paintEvent(QPaintEvent *pEvent) /* override */; 73 74 /** Handles drag-enter @a pEvent. */ 75 virtual void dragEnterEvent(QDragEnterEvent *pEvent) /* override */; 76 /** Handles drag-move @a pEvent. */ 77 virtual void dragMoveEvent(QDragMoveEvent *pEvent) /* override */; 78 /** Handles drag-leave @a pEvent. */ 79 virtual void dragLeaveEvent(QDragLeaveEvent *pEvent) /* override */; 80 /** Handles drop @a pEvent. */ 81 virtual void dropEvent(QDropEvent *pEvent) /* override */; 82 64 83 private slots: 65 84 … … 69 88 /** Handles request to close @a pItem. */ 70 89 void sltHandleChildClose(UITabBarItem *pItem); 90 91 /** Handles drag object destruction. */ 92 void sltHandleDragObjectDestroy(); 71 93 72 94 private: … … 88 110 QList<UITabBarItem*> m_aItems; 89 111 /** @} */ 112 113 /** @name Contents: Order 114 * @{ */ 115 /** Holds the token-item to drop dragged-item nearby. */ 116 UITabBarItem *m_pItemToken; 117 118 /** Holds whether the dragged-item should be dropped <b>after</b> the token-item. */ 119 bool m_fDropAfterTokenItem; 120 /** @} */ 90 121 }; 91 122
Note:
See TracChangeset
for help on using the changeset viewer.