VirtualBox

Changeset 42678 in vbox for trunk


Ignore:
Timestamp:
Aug 8, 2012 11:25:47 AM (12 years ago)
Author:
vboxsync
Message:

FE/Qt: 6234: Support for VM groups: Sliding buttons, anti-aliasing, frames redraw, few bug-fixes.

Location:
trunk/src/VBox/Frontends/VirtualBox/src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserHandlerMouse.cpp

    r42632 r42678  
    7272                    pClickedItem = pMachineItem;
    7373                /* If we had clicked one of the required item types: */
    74                 if (pClickedItem && pClickedItem->parentItem())
     74                if (pClickedItem && !pClickedItem->isRoot())
    7575                {
    7676                    /* Old selection list: */
     
    132132                {
    133133                    /* For non-root items: */
    134                     if (pClickedItem->parentItem())
     134                    if (!pClickedItem->isRoot())
    135135                    {
    136136                        /* Is clicked item in selection list: */
     
    177177                    if (iMouseDoubleClickX < iGroupItemWidth / 2)
    178178                    {
     179                        /* Do not allow for unhovered root: */
     180                        if (pGroupItem->isRoot() && !pGroupItem->isHovered())
     181                            return false;
    179182                        /* Unindent root if possible: */
    180183                        if (model()->root() != model()->mainRoot())
     
    186189                    else
    187190                    {
     191                        /* Do not allow for root: */
     192                        if (pGroupItem->isRoot())
     193                            return false;
    188194                        /* Indent root with group item: */
    189195                        pGroupItem->setHovered(false);
     
    193199                    return true;
    194200                }
     201                /* Or a machine one? */
     202                else if (pItemUnderMouse->type() == UIGChooserItemType_Machine)
     203                {
     204                    /* Activate machine item: */
     205                    model()->activate();
     206                }
     207#if 0
    195208                /* Or a machine one? */
    196209                else if (UIGChooserItemMachine *pMachineItem = qgraphicsitem_cast<UIGChooserItemMachine*>(pItemUnderMouse))
     
    217230                    return true;
    218231                }
     232#endif
    219233                break;
    220234            }
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItem.cpp

    r42593 r42678  
    5353    setFocusPolicy(Qt::NoFocus);
    5454    setFlag(QGraphicsItem::ItemIsSelectable, false);
     55    setAcceptHoverEvents(!isRoot());
    5556
    5657    /* Non-root item? */
    5758    if (!isRoot())
    5859    {
    59         /* Non-root item setup: */
    60         setAcceptHoverEvents(true);
    61 
    6260        /* Create state machine: */
    6361        m_pHighlightMachine = new QStateMachine(this);
     
    133131{
    134132    m_fRoot = fRoot;
    135     setAcceptHoverEvents(!m_fRoot);
    136133}
    137134
     
    139136{
    140137    return m_fRoot;
     138}
     139
     140bool UIGChooserItem::isHovered() const
     141{
     142    return m_fHovered;
     143}
     144
     145void UIGChooserItem::setHovered(bool fHovered)
     146{
     147    m_fHovered = fHovered;
     148    if (m_fHovered)
     149        emit sigHoverEnter();
     150    else
     151        emit sigHoverLeave();
    141152}
    142153
     
    282293        QPainterPath roundedPath;
    283294        roundedPath.addRoundedRect(pOption->rect, iRadius, iRadius);
    284         pPainter->setRenderHint(QPainter::Antialiasing);
    285295        pPainter->setClipPath(roundedPath);
    286296    }
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItem.h

    r42632 r42678  
    8282    void setRoot(bool fRoot);
    8383    bool isRoot() const;
    84     bool isHovered() const { return m_fHovered; }
    85     void setHovered(bool fHovered) { m_fHovered = fHovered; }
     84    bool isHovered() const;
     85    void setHovered(bool fHovered);
    8686
    8787    /* API: Children stuff: */
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemGroup.cpp

    r42630 r42678  
    3939    : UIGChooserItem(0)
    4040    , m_fClosed(false)
    41     , m_pButton(0)
     41    , m_pToggleButton(0)
     42    , m_pEnterButton(0)
     43    , m_pExitButton(0)
    4244    , m_pNameEditorWidget(0)
    4345    , m_pNameEditor(0)
    4446    , m_iAdditionalHeight(0)
    4547    , m_iCornerRadius(10)
    46 {
     48    , m_fMainRoot(true)
     49{
     50    /* Prepare: */
     51    prepare();
     52
    4753    /* Add item to the scene: */
    4854    if (pScene)
     
    5157
    5258UIGChooserItemGroup::UIGChooserItemGroup(QGraphicsScene *pScene,
    53                                          UIGChooserItemGroup *pCopyFrom)
     59                                         UIGChooserItemGroup *pCopyFrom,
     60                                         bool fMainRoot)
    5461    : UIGChooserItem(0)
    5562    , m_strName(pCopyFrom->name())
    5663    , m_fClosed(pCopyFrom->closed())
    57     , m_pButton(0)
     64    , m_pToggleButton(0)
     65    , m_pEnterButton(0)
     66    , m_pExitButton(0)
    5867    , m_pNameEditorWidget(0)
    5968    , m_pNameEditor(0)
    6069    , m_iAdditionalHeight(0)
    6170    , m_iCornerRadius(10)
    62 {
     71    , m_fMainRoot(fMainRoot)
     72{
     73    /* Prepare: */
     74    prepare();
     75
    6376    /* Add item to the scene: */
    6477    if (pScene)
     
    7689    , m_strName(strName)
    7790    , m_fClosed(!fOpened)
    78     , m_pButton(0)
     91    , m_pToggleButton(0)
     92    , m_pEnterButton(0)
     93    , m_pExitButton(0)
    7994    , m_pNameEditorWidget(0)
    8095    , m_pNameEditor(0)
    8196    , m_iAdditionalHeight(0)
    8297    , m_iCornerRadius(10)
     98    , m_fMainRoot(false)
    8399{
    84100    /* Prepare: */
     
    97113    , m_strName(pCopyFrom->name())
    98114    , m_fClosed(pCopyFrom->closed())
    99     , m_pButton(0)
     115    , m_pToggleButton(0)
     116    , m_pEnterButton(0)
     117    , m_pExitButton(0)
    100118    , m_pNameEditorWidget(0)
    101119    , m_pNameEditor(0)
    102120    , m_iAdditionalHeight(0)
    103121    , m_iCornerRadius(10)
     122    , m_fMainRoot(false)
    104123{
    105124    /* Prepare: */
     
    158177{
    159178    AssertMsg(parentItem(), ("Can't close root-item!"));
    160     m_pButton->setToggled(false ,fAnimated);
     179    m_pToggleButton->setToggled(false ,fAnimated);
    161180}
    162181
     
    164183{
    165184    AssertMsg(parentItem(), ("Can't open root-item!"));
    166     m_pButton->setToggled(true, fAnimated);
     185    m_pToggleButton->setToggled(true, fAnimated);
    167186}
    168187
     
    244263}
    245264
     265void UIGChooserItemGroup::sltIndentRoot()
     266{
     267    setHovered(false);
     268    model()->indentRoot(this);
     269}
     270
     271void UIGChooserItemGroup::sltUnindentRoot()
     272{
     273    setHovered(false);
     274    model()->unindentRoot();
     275}
     276
    246277QVariant UIGChooserItemGroup::data(int iKey) const
    247278{
     
    250281    {
    251282        /* Layout hints: */
    252         case GroupItemData_HorizonalMargin: return isRoot() ? 1 : 8;
    253         case GroupItemData_VerticalMargin: return isRoot() ? 1 : 5;
    254         case GroupItemData_MajorSpacing: return isRoot() ? 0 : 10;
    255         case GroupItemData_MinorSpacing: return 0;
     283        case GroupItemData_HorizonalMargin: return 8;
     284        case GroupItemData_VerticalMargin: return 5;
     285        case GroupItemData_MajorSpacing: return 10;
     286        case GroupItemData_MinorSpacing: return 3;
    256287        /* Pixmaps: */
    257         case GroupItemData_ButtonPixmap: return UIIconPool::iconSet(":/arrow_right_10px.png");
     288        case GroupItemData_ToggleButtonPixmap: return UIIconPool::iconSet(":/arrow_right_10px.png");
     289        case GroupItemData_EnterButtonPixmap: return UIIconPool::iconSet(":/start_16px.png");
    258290        case GroupItemData_GroupPixmap: return UIIconPool::iconSet(":/nw_16px.png");
    259291        case GroupItemData_MachinePixmap: return UIIconPool::iconSet(":/machine_16px.png");
     
    275307            /* Prepare variables: */
    276308            int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    277             int iButtonWidth = data(GroupItemData_ButtonSize).toSize().width();
    278             int iMinorSpacing = data(GroupItemData_MinorSpacing).toInt();
     309            int iMajorSpacing = data(GroupItemData_MajorSpacing).toInt();
     310            int iToggleButtonWidth = data(GroupItemData_ToggleButtonSize).toSizeF().width();
     311            int iEnterButtonWidth = data(GroupItemData_EnterButtonSize).toSizeF().width();
     312            int iExitButtonWidth = data(GroupItemData_ExitButtonSize).toSizeF().width();
    279313            int iGroupPixmapWidth = data(GroupItemData_GroupPixmapSize).toSize().width();
    280314            int iMachinePixmapWidth = data(GroupItemData_MachinePixmapSize).toSize().width();
    281315            int iGroupCountTextWidth = data(GroupItemData_GroupCountTextSize).toSize().width();
    282316            int iMachineCountTextWidth = data(GroupItemData_MachineCountTextSize).toSize().width();
    283             int iMaximumWidth = (int)geometry().width() - iHorizontalMargin -
    284                                                           iButtonWidth - iMinorSpacing -
    285                                                           iHorizontalMargin -
    286                                                           iGroupPixmapWidth - iMinorSpacing -
    287                                                           iMachinePixmapWidth - iMinorSpacing -
    288                                                           iGroupCountTextWidth - iMinorSpacing -
    289                                                           iMachineCountTextWidth;
    290             QString strCompressedName = compressText(data(GroupItemData_NameFont).value<QFont>(),
    291                                                      m_strName, iMaximumWidth);
    292             return strCompressedName;
    293         }
    294         case GroupItemData_GroupCountText: return QString::number(m_groupItems.size());
    295         case GroupItemData_MachineCountText: return QString::number(m_machineItems.size());
     317            int iMaximumWidth = (int)geometry().width();
     318            QString strGroupCountText = data(GroupItemData_GroupCountText).toString();
     319            QString strMachineCountText = data(GroupItemData_MachineCountText).toString();
     320
     321            /* Calculate name width: */
     322            iMaximumWidth -= 2 * iHorizontalMargin;
     323            if (isRoot())
     324                iMaximumWidth -= (iExitButtonWidth + iMajorSpacing);
     325            else
     326            {
     327                iMaximumWidth -= (iToggleButtonWidth + iMajorSpacing);
     328                if (isHovered())
     329                    iMaximumWidth -= (iEnterButtonWidth + iMajorSpacing);
     330            }
     331            if (isHovered() && !strGroupCountText.isEmpty())
     332                iMaximumWidth -= (iGroupPixmapWidth + iGroupCountTextWidth);
     333            if (isHovered() && !strMachineCountText.isEmpty())
     334                iMaximumWidth -= (iMachinePixmapWidth + iMachineCountTextWidth);
     335            return compressText(data(GroupItemData_NameFont).value<QFont>(), m_strName, iMaximumWidth);
     336        }
     337        case GroupItemData_GroupCountText: return m_groupItems.isEmpty() ? QString() : QString::number(m_groupItems.size());
     338        case GroupItemData_MachineCountText: return m_machineItems.isEmpty() ? QString() : QString::number(m_machineItems.size());
    296339        /* Sizes: */
    297         case GroupItemData_ButtonSize: return m_pButton ? m_pButton->minimumSizeHint() : QSizeF(0, 0);
     340        case GroupItemData_ToggleButtonSize: return m_pToggleButton ? m_pToggleButton->minimumSizeHint() : QSizeF(0, 0);
     341        case GroupItemData_EnterButtonSize: return m_pEnterButton ? m_pEnterButton->minimumSizeHint() : QSizeF(0, 0);
     342        case GroupItemData_ExitButtonSize: return m_pExitButton ? m_pExitButton->minimumSizeHint() : QSizeF(0, 0);
    298343        case GroupItemData_MinimumNameSize:
    299344        {
    300             if (isRoot())
     345            if (isMainRoot())
    301346                return QSizeF(0, 0);
    302347            QFont font = data(GroupItemData_NameFont).value<QFont>();
     
    308353        case GroupItemData_NameSize:
    309354        {
    310             if (isRoot())
     355            if (isMainRoot())
    311356                return QSizeF(0, 0);
    312357            QFontMetrics fm(data(GroupItemData_NameFont).value<QFont>());
     
    320365        }
    321366        case GroupItemData_GroupPixmapSize:
    322             return isRoot() ? QSizeF(0, 0) : data(GroupItemData_GroupPixmap).value<QIcon>().availableSizes().at(0);
     367            return isMainRoot() ? QSizeF(0, 0) : data(GroupItemData_GroupPixmap).value<QIcon>().availableSizes().at(0);
    323368        case GroupItemData_MachinePixmapSize:
    324             return isRoot() ? QSizeF(0, 0) : data(GroupItemData_MachinePixmap).value<QIcon>().availableSizes().at(0);
     369            return isMainRoot() ? QSizeF(0, 0) : data(GroupItemData_MachinePixmap).value<QIcon>().availableSizes().at(0);
    325370        case GroupItemData_GroupCountTextSize:
    326371        {
    327             if (isRoot())
     372            if (isMainRoot())
    328373                return QSizeF(0, 0);
    329374            QFontMetrics fm(data(GroupItemData_InfoFont).value<QFont>());
     
    332377        case GroupItemData_MachineCountTextSize:
    333378        {
    334             if (isRoot())
     379            if (isMainRoot())
    335380                return QSizeF(0, 0);
    336381            QFontMetrics fm(data(GroupItemData_InfoFont).value<QFont>());
     
    341386            /* Prepare variables: */
    342387            int iMajorSpacing = data(GroupItemData_MajorSpacing).toInt();
    343             int iMinorSpacing = data(GroupItemData_MinorSpacing).toInt();
    344             QSize buttonSize = data(GroupItemData_ButtonSize).toSize();
     388            QSize toggleButtonSize = data(GroupItemData_ToggleButtonSize).toSize();
     389            QSize enterButtonSize = data(GroupItemData_EnterButtonSize).toSize();
     390            QSize exitButtonSize = data(GroupItemData_ExitButtonSize).toSize();
    345391            QSize minimumNameSize = data(GroupItemData_MinimumNameSize).toSize();
    346392            QSize groupPixmapSize = data(GroupItemData_GroupPixmapSize).toSize();
     
    350396
    351397            /* Calculate minimum width: */
    352             int iGroupItemHeaderWidth = /* Button width: */
    353                                         buttonSize.width() +
    354                                         /* Spacing between button and name: */
    355                                         iMajorSpacing +
    356                                         /* Some hardcoded magic: */
    357                                         1 /* frame width from Qt sources */ +
    358                                         2 /* internal QLineEdit margin from Qt sources */ +
    359                                         1 /* internal QLineEdit align shifting from Qt sources */ +
    360                                         /* Minimum name width: */
    361                                         minimumNameSize.width() +
    362                                         /* Spacing between name and info: */
    363                                         iMajorSpacing +
    364                                         /* Group stuff width: */
    365                                         groupPixmapSize.width() + iMinorSpacing +
    366                                         groupCountTextSize.width() + iMinorSpacing +
    367                                         /* Machine stuff width: */
    368                                         machinePixmapSize.width() + iMinorSpacing +
    369                                         machineCountTextSize.width();
     398            int iGroupItemHeaderWidth = 0;
     399            if (isRoot() && !isMainRoot())
     400                iGroupItemHeaderWidth += exitButtonSize.width();
     401            if (!isRoot())
     402                iGroupItemHeaderWidth += toggleButtonSize.width();
     403            if (!isMainRoot())
     404                iGroupItemHeaderWidth += /* Spacing between button and name: */
     405                                         iMajorSpacing +
     406                                         minimumNameSize.width() +
     407                                         /* Spacing between name and info: */
     408                                         iMajorSpacing +
     409                                         /* Group stuff width: */
     410                                         groupPixmapSize.width() +
     411                                         groupCountTextSize.width() +
     412                                         /* Machine stuff width: */
     413                                         machinePixmapSize.width() +
     414                                         machineCountTextSize.width();
     415            if (!isRoot())
     416                iGroupItemHeaderWidth += enterButtonSize.width();
    370417
    371418            /* Search for maximum height: */
    372419            QList<int> heights;
    373             heights << buttonSize.height()
    374                     << minimumNameSize.height()
    375                     << groupPixmapSize.height() << machinePixmapSize.height()
    376                     << groupCountTextSize.height() << machineCountTextSize.height();
     420            if (isRoot() && !isMainRoot())
     421                heights << exitButtonSize.height();
     422            if (!isRoot())
     423                heights << toggleButtonSize.height();
     424            if (!isMainRoot())
     425                heights << minimumNameSize.height()
     426                        << groupPixmapSize.height() << machinePixmapSize.height()
     427                        << groupCountTextSize.height() << machineCountTextSize.height();
     428            if (!isRoot())
     429                heights << enterButtonSize.height();
    377430            int iGroupItemHeaderHeight = 0;
    378431            foreach (int iHeight, heights)
     
    426479        case UIGChooserItemType_Group:
    427480        {
     481            AssertMsg(!m_groupItems.contains(pItem), ("Group item already added!"));
    428482            if (iPosition < 0 || iPosition >= m_groupItems.size())
    429483                m_groupItems.append(pItem);
     
    435489        case UIGChooserItemType_Machine:
    436490        {
     491            AssertMsg(!m_machineItems.contains(pItem), ("Machine item already added!"));
    437492            if (iPosition < 0 || iPosition >= m_machineItems.size())
    438493                m_machineItems.append(pItem);
     
    457512        case UIGChooserItemType_Group:
    458513        {
     514            AssertMsg(m_groupItems.contains(pItem), ("Group item was not found!"));
    459515            scene()->removeItem(pItem);
    460516            m_groupItems.removeAt(m_groupItems.indexOf(pItem));
     
    463519        case UIGChooserItemType_Machine:
    464520        {
     521            AssertMsg(m_machineItems.contains(pItem), ("Machine item was not found!"));
    465522            scene()->removeItem(pItem);
    466523            m_machineItems.removeAt(m_machineItems.indexOf(pItem));
     
    524581        case UIGChooserItemType_Group:
    525582        {
    526             while (!m_groupItems.isEmpty()) { delete m_groupItems.takeLast(); }
     583            while (!m_groupItems.isEmpty()) { delete m_groupItems.last(); }
    527584            AssertMsg(m_groupItems.isEmpty(), ("Group items cleanup failed!"));
    528585            break;
     
    530587        case UIGChooserItemType_Machine:
    531588        {
    532             while (!m_machineItems.isEmpty()) { delete m_machineItems.takeLast(); }
     589            while (!m_machineItems.isEmpty()) { delete m_machineItems.last(); }
    533590            AssertMsg(m_machineItems.isEmpty(), ("Machine items cleanup failed!"));
    534591            break;
     
    551608    int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    552609    int iVerticalMargin = data(GroupItemData_VerticalMargin).toInt();
     610    int iMajorSpacing = data(GroupItemData_MajorSpacing).toInt();
    553611    int iMinorSpacing = data(GroupItemData_MinorSpacing).toInt();
    554     int iButtonHeight = data(GroupItemData_ButtonSize).toSize().height();
    555     int iButtonWidth = data(GroupItemData_ButtonSize).toSize().width();
    556612    int iFullHeaderHeight = data(GroupItemData_FullHeaderSize).toSize().height();
    557613    int iPreviousVerticalIndent = 0;
     
    560616    if (isRoot())
    561617    {
    562         /* Hide button: */
    563         if (m_pButton && m_pButton->isVisible())
    564             m_pButton->hide();
    565 
    566         /* Hide name-editor: */
    567         if (m_pNameEditor && m_pNameEditor->isVisible())
    568             m_pNameEditor->hide();
    569 
    570         /* Prepare body indent: */
    571         iPreviousVerticalIndent = iVerticalMargin;
     618        /* Hide widgets: */
     619        if (m_pToggleButton)
     620            m_pToggleButton->hide();
     621        if (m_pEnterButton)
     622            m_pEnterButton->hide();
     623
     624        if (!isMainRoot())
     625        {
     626            /* Exit-button? */
     627            if (m_pExitButton)
     628            {
     629                /* Show exit-button: */
     630                m_pExitButton->show();
     631
     632                /* Prepare variables: */
     633                int iExitButtonHeight = data(GroupItemData_ExitButtonSize).toSizeF().height();
     634
     635                /* Layout exit-button: */
     636                int iExitButtonX = iHorizontalMargin;
     637                int iExitButtonY = iExitButtonHeight == iFullHeaderHeight ? iVerticalMargin :
     638                                   iVerticalMargin + (iFullHeaderHeight - iExitButtonHeight) / 2;
     639                m_pExitButton->setPos(iExitButtonX, iExitButtonY);
     640            }
     641
     642            /* Prepare body indent: */
     643            iPreviousVerticalIndent = iVerticalMargin + iFullHeaderHeight + iVerticalMargin + iMinorSpacing;
     644        }
     645        else
     646        {
     647            /* Prepare body indent: */
     648            iPreviousVerticalIndent = 2;
     649        }
    572650    }
    573651    /* Header (non-root item): */
    574652    else
    575653    {
    576         /* Show button: */
    577         if (!m_pButton->isVisible())
    578             m_pButton->show();
    579         /* Layout button: */
    580         int iButtonX = iHorizontalMargin;
    581         int iButtonY = iButtonHeight == iFullHeaderHeight ? iVerticalMargin :
    582                        iVerticalMargin + (iFullHeaderHeight - iButtonHeight) / 2;
    583         m_pButton->setPos(iButtonX, iButtonY);
     654        /* Hide exit-button: */
     655        if (m_pExitButton)
     656            m_pExitButton->hide();
     657        /* Show toggle-button: */
     658        if (m_pToggleButton)
     659            m_pToggleButton->show();
     660
     661        /* Prepare variables: */
     662        int iFullWidth = geometry().width();
     663        QSizeF toggleButtonSize = data(GroupItemData_ToggleButtonSize).toSizeF().toSize();
     664        int iToggleButtonWidth = toggleButtonSize.width();
     665        int iButtonHeight = toggleButtonSize.height();
     666        QSizeF enterButtonSize = data(GroupItemData_EnterButtonSize).toSizeF().toSize();
     667        int iEnterButtonWidth = enterButtonSize.width();
     668        int iEnterButtonHeight = enterButtonSize.height();
     669
     670        /* Layout toggle-button: */
     671        int iToggleButtonX = iHorizontalMargin;
     672        int iToggleButtonY = iButtonHeight == iFullHeaderHeight ? iVerticalMargin :
     673                             iVerticalMargin + (iFullHeaderHeight - iButtonHeight) / 2;
     674        m_pToggleButton->setPos(iToggleButtonX, iToggleButtonY);
     675
     676        /* Layout enter-button: */
     677        int iEnterButtonX = iFullWidth - iHorizontalMargin - iEnterButtonWidth;
     678        int iEnterButtonY = iEnterButtonHeight == iFullHeaderHeight ? iVerticalMargin :
     679                            iVerticalMargin + (iFullHeaderHeight - iEnterButtonHeight) / 2;
     680        m_pEnterButton->setPos(iEnterButtonX, iEnterButtonY);
    584681
    585682        /* Layout name-editor: */
    586         int iNameEditorX = iHorizontalMargin + iButtonWidth + iMinorSpacing;
     683        int iNameEditorX = iHorizontalMargin + iToggleButtonWidth + iMajorSpacing;
    587684        int iNameEditorY = 1;
    588685        m_pNameEditor->setPos(iNameEditorX, iNameEditorY);
     
    598695        /* Hide all the items: */
    599696        foreach (UIGChooserItem *pItem, items())
    600             if (pItem->isVisible())
    601                 pItem->hide();
     697            pItem->hide();
    602698    }
    603699    /* Body for opened group: */
     
    605701    {
    606702        /* Prepare variables: */
    607         int iMinorSpacing = data(GroupItemData_MinorSpacing).toInt();
     703        int iHorizontalIndent = isRoot() ? 1 : iHorizontalMargin;
    608704        QRect geo = geometry().toRect();
    609705        int iX = geo.x();
    610706        int iY = geo.y();
    611707        int iWidth = geo.width();
     708
    612709        /* Layout all the items: */
    613710        foreach (UIGChooserItem *pItem, items())
    614711        {
    615712            /* Show if hidden: */
    616             if (!pItem->isVisible())
    617                 pItem->show();
     713            pItem->show();
    618714            /* Get item's height-hint: */
    619715            int iMinimumHeight = pItem->minimumHeightHint();
    620716            /* Set item's position: */
    621             pItem->setPos(iX + iHorizontalMargin, iY + iPreviousVerticalIndent);
     717            pItem->setPos(iX + iHorizontalIndent, iY + iPreviousVerticalIndent);
    622718            /* Set item's size: */
    623             pItem->resize(iWidth - 2 * iHorizontalMargin, iMinimumHeight);
     719            pItem->resize(iWidth - 2 * iHorizontalIndent, iMinimumHeight);
    624720            /* Relayout group: */
    625721            pItem->updateLayout();
     
    646742    if (!fClosedGroup)
    647743    {
     744        /* Prepare variables: */
     745        int iHorizontalIndent = isRoot() ? 1 : iHorizontalMargin;
    648746        /* We have to make sure that we had taken into account: */
    649747        foreach (UIGChooserItem *pItem, items())
    650748        {
    651             int iItemWidth = 2 * iHorizontalMargin + pItem->minimumWidthHint();
     749            int iItemWidth = 2 * iHorizontalIndent + pItem->minimumWidthHint();
    652750            iProposedWidth = qMax(iProposedWidth, iItemWidth);
    653751        }
     
    677775    {
    678776        /* We should take into account: */
    679         for (int i = 0; i < m_groupItems.size(); ++i)
    680         {
    681             /* Every group item height: */
    682             UIGChooserItem *pItem = m_groupItems[i];
    683             iProposedHeight += pItem->minimumHeightHint();
    684             /* And every spacing between sub-groups: */
    685             if (i < m_groupItems.size() - 1)
    686                 iProposedHeight += iMinorSpacing;
    687         }
    688         /* Minor spacing between group and machine item: */
    689         if (hasItems(UIGChooserItemType_Group) && hasItems(UIGChooserItemType_Machine))
    690             iProposedHeight += iMinorSpacing;
    691         for (int i = 0; i < m_machineItems.size(); ++i)
    692         {
    693             /* Every machine item height: */
    694             UIGChooserItem *pItem = m_machineItems[i];
    695             iProposedHeight += pItem->minimumHeightHint();
    696             /* And every spacing between sub-machines: */
    697             if (i < m_machineItems.size() - 1)
    698                 iProposedHeight += iMinorSpacing;
    699         }
     777        QList<UIGChooserItem*> allItems = items();
     778        for (int i = 0; i < allItems.size(); ++i)
     779        {
     780            /* Every item height: */
     781            UIGChooserItem *pItem = allItems[i];
     782            iProposedHeight += (pItem->minimumHeightHint() + iMinorSpacing);
     783        }
     784        /* Minus last spacing: */
     785        iProposedHeight -= iMinorSpacing;
    700786        /* Bottom margin: */
    701787        iProposedHeight += iHorizontalMargin;
    702788    }
    703789    /* Finally, additional height during animation: */
    704     if (fClosedGroup && m_pButton && m_pButton->isAnimationRunning())
     790    if (fClosedGroup && m_pToggleButton && m_pToggleButton->isAnimationRunning())
    705791        iProposedHeight += m_iAdditionalHeight;
    706792
     
    9441030void UIGChooserItemGroup::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, bool fClosedGroup)
    9451031{
    946     /* Non-root item: */
    947     if (!isRoot())
    948     {
    949         /* Configure painter shape: */
    950         configurePainterShape(pPainter, pOption, m_iCornerRadius);
    951     }
    952 
    953     /* Any item: */
    954     {
    955         /* Paint decorations: */
    956         paintDecorations(pPainter, pOption);
    957     }
    958 
    959     /* Non-root item: */
    960     if (!isRoot())
     1032    /* Setup: */
     1033    pPainter->setRenderHint(QPainter::Antialiasing);
     1034
     1035    /* Paint decorations: */
     1036    paintDecorations(pPainter, pOption);
     1037
     1038    /* Non for main root: */
     1039    if (!isMainRoot())
    9611040    {
    9621041        /* Paint group info: */
     
    9671046void UIGChooserItemGroup::paintDecorations(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption)
    9681047{
    969     /* Prepare variables: */
    970     QRect fullRect = pOption->rect;
    971 
    972     /* Any item: */
    973     {
    974         /* Paint background: */
    975         paintBackground(/* Painter: */
    976                         pPainter,
    977                         /* Rectangle to paint in: */
    978                         fullRect);
    979     }
    980 
    981     /* Non-root item: */
    982     if (!isRoot())
    983     {
    984         /* Paint frame: */
    985         paintFrameRect(/* Painter: */
    986                        pPainter,
    987                        /* Rectangle to paint in: */
    988                        fullRect,
    989                        /* Is item selected? */
    990                        model()->selectionList().contains(this),
    991                        /* Rounded corner radius: */
    992                        m_iCornerRadius);
    993     }
     1048    /* Paint background: */
     1049    paintBackground(pPainter, pOption->rect);
    9941050}
    9951051
     
    10071063    if (isRoot())
    10081064    {
    1009         /* Simple and clear: */
    1010         pPainter->fillRect(rect, base.darker(100));
     1065        /* Main root item: */
     1066        if (isMainRoot())
     1067        {
     1068            /* Simple and clear: */
     1069            pPainter->fillRect(rect, base);
     1070        }
     1071        else
     1072        {
     1073            /* Prepare variables: */
     1074            int iMargin = data(GroupItemData_VerticalMargin).toInt();
     1075            int iHeaderHeight = data(GroupItemData_FullHeaderSize).toSize().height();
     1076            int iFullHeaderHeight = 2 * iMargin + iHeaderHeight;
     1077            QRect backgroundRect = QRect(0, 0, rect.width(), iFullHeaderHeight);
     1078
     1079            /* Add clipping: */
     1080            QPainterPath path;
     1081            path.moveTo(1, 0);
     1082            path.lineTo(path.currentPosition().x(), iFullHeaderHeight - 10);
     1083            path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(0, -10), 180, 90);
     1084            path.lineTo(rect.width() - 10 - 1, path.currentPosition().y());
     1085            path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(-10, -20), 270, 90);
     1086            path.lineTo(path.currentPosition().x(), 0);
     1087            path.closeSubpath();
     1088            pPainter->setClipPath(path);
     1089
     1090            /* Fill background: */
     1091            QLinearGradient headerGradient(backgroundRect.bottomLeft(), backgroundRect.topLeft());
     1092            headerGradient.setColorAt(0, base.darker(gradient()));
     1093            headerGradient.setColorAt(1, base.darker(110));
     1094            pPainter->fillRect(backgroundRect, headerGradient);
     1095
     1096            /* Stroke path: */
     1097            pPainter->setClipping(false);
     1098            pPainter->strokePath(path, base.darker(130));
     1099        }
    10111100    }
    10121101    /* Non-root item: */
     
    10171106        int iHeaderHeight = data(GroupItemData_FullHeaderSize).toSize().height();
    10181107        int iFullHeaderHeight = 2 * iMargin + iHeaderHeight;
    1019 
    1020         /* Fill rectangle with brush/color: */
    1021         pPainter->fillRect(rect, Qt::white);
    1022 
    1023         /* Make even less rectangle: */
    1024         QRect backGroundRect = rect;
    1025         backGroundRect.setTopLeft(backGroundRect.topLeft() + QPoint(2, 2));
    1026         backGroundRect.setBottomRight(backGroundRect.bottomRight() - QPoint(2, 2));
    1027         /* Add even more clipping: */
    1028         QPainterPath roundedPath;
    1029         roundedPath.addRoundedRect(backGroundRect, m_iCornerRadius, m_iCornerRadius);
    1030         pPainter->setClipPath(roundedPath);
     1108        int iFullHeight = rect.height();
     1109
     1110        /* Add clipping: */
     1111        QPainterPath path;
     1112        path.moveTo(10, 0);
     1113        path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(-10, 0), 90, 90);
     1114        path.lineTo(path.currentPosition().x(), iFullHeight - 10);
     1115        path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(0, -10), 180, 90);
     1116        path.lineTo(rect.width() - 10, path.currentPosition().y());
     1117        path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(-10, -20), 270, 90);
     1118        path.lineTo(path.currentPosition().x(), 10);
     1119        path.arcTo(QRectF(path.currentPosition(), QSizeF(20, 20)).translated(-20, -10), 0, 90);
     1120        path.closeSubpath();
     1121        pPainter->setClipPath(path);
    10311122
    10321123        /* Calculate top rectangle: */
    1033         QRect tRect = backGroundRect;
     1124        QRect tRect = rect;
    10341125        tRect.setBottom(tRect.top() + iFullHeaderHeight);
    10351126        /* Prepare top gradient: */
     
    10401131        pPainter->fillRect(tRect, tGradient);
    10411132
    1042         if (backGroundRect.height() > tRect.height())
     1133        if (rect.height() > tRect.height())
    10431134        {
    10441135            /* Calculate middle rectangle: */
    1045             QRect midRect = QRect(tRect.bottomLeft(), backGroundRect.bottomRight());
     1136            QRect midRect = QRect(tRect.bottomLeft(), rect.bottomRight());
    10461137            /* Paint all the stuff: */
    10471138            pPainter->fillRect(midRect, base.darker(110));
    10481139        }
    10491140
     1141         /* Stroke path: */
     1142        pPainter->setClipping(false);
     1143        pPainter->strokePath(path, base.darker(130));
     1144        pPainter->setClipPath(path);
     1145
    10501146        /* Paint drag token UP? */
    10511147        if (dragTokenPlace() != DragToken_Off)
    10521148        {
    10531149            QLinearGradient dragTokenGradient;
    1054             QRect dragTokenRect = backGroundRect;
     1150            QRect dragTokenRect = rect;
    10551151            if (dragTokenPlace() == DragToken_Up)
    10561152            {
     
    10781174{
    10791175    /* Prepare variables: */
    1080     int iMinorSpacing = data(GroupItemData_MinorSpacing).toInt();
    10811176    int iHorizontalMargin = data(GroupItemData_HorizonalMargin).toInt();
    10821177    int iVerticalMargin = data(GroupItemData_VerticalMargin).toInt();
    1083     QSize buttonSize = data(GroupItemData_ButtonSize).toSize();
     1178    int iMajorSpacing = data(GroupItemData_MajorSpacing).toInt();
     1179    QSize toggleButtonSize = data(GroupItemData_ToggleButtonSize).toSize();
     1180    QSize exitButtonSize = data(GroupItemData_ExitButtonSize).toSize();
    10841181    QSize nameSize = data(GroupItemData_NameSize).toSize();
    10851182    int iFullHeaderHeight = data(GroupItemData_FullHeaderSize).toSize().height();
    10861183
    10871184    /* Paint name: */
    1088     int iNameX = iHorizontalMargin + buttonSize.width() + iMinorSpacing +
    1089                  1 /* frame width from Qt sources */ +
    1090                  2 /* internal QLineEdit margin from Qt sources */ +
    1091                  1 /* internal QLineEdit align shifting from Qt sources */;
     1185    int iNameX = iHorizontalMargin + iMajorSpacing;
     1186    if (!isRoot())
     1187        iNameX += toggleButtonSize.width();
     1188    else if (!isMainRoot())
     1189        iNameX += exitButtonSize.width();
    10921190    int iNameY = nameSize.height() == iFullHeaderHeight ? iVerticalMargin :
    10931191                 iVerticalMargin + (iFullHeaderHeight - nameSize.height()) / 2;
     
    11041202    if (isHovered())
    11051203    {
     1204        /* Show enter-button: */
     1205        if (!isRoot() && m_pEnterButton)
     1206            m_pEnterButton->show();
     1207
    11061208        /* Prepare variables: */
    11071209        QRect fullRect = pOption->rect;
     1210        int iEnterButtonWidth = data(GroupItemData_EnterButtonSize).toSizeF().width();
    11081211        QSize groupPixmapSize = data(GroupItemData_GroupPixmapSize).toSize();
    11091212        QSize machinePixmapSize = data(GroupItemData_MachinePixmapSize).toSize();
     
    11161219        QPixmap machinePixmap = data(GroupItemData_MachinePixmap).value<QIcon>().pixmap(machinePixmapSize);
    11171220
    1118         /* We should add machine count: */
    1119         int iMachineCountTextX = fullRect.right() -
    1120                                  iHorizontalMargin -
    1121                                  machineCountTextSize.width();
    1122         int iMachineCountTextY = machineCountTextSize.height() == iFullHeaderHeight ?
    1123                                  iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - machineCountTextSize.height()) / 2;
    1124         paintText(/* Painter: */
    1125                   pPainter,
    1126                   /* Rectangle to paint in: */
    1127                   QRect(QPoint(iMachineCountTextX, iMachineCountTextY), machineCountTextSize),
    1128                   /* Font to paint text: */
    1129                   infoFont,
    1130                   /* Text to paint: */
    1131                   strMachineCountText);
    1132 
    1133         /* We should draw machine pixmap: */
    1134         int iMachinePixmapX = iMachineCountTextX -
    1135                               iMinorSpacing -
    1136                               machinePixmapSize.width();
    1137         int iMachinePixmapY = machinePixmapSize.height() == iFullHeaderHeight ?
    1138                               iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - machinePixmapSize.height()) / 2;
    1139         paintPixmap(/* Painter: */
    1140                     pPainter,
    1141                     /* Rectangle to paint in: */
    1142                     QRect(QPoint(iMachinePixmapX, iMachinePixmapY), machinePixmapSize),
    1143                     /* Pixmap to paint: */
    1144                     machinePixmap);
    1145 
    1146         /* We should add group count: */
    1147         int iGroupCountTextX = iMachinePixmapX -
    1148                                iMinorSpacing -
    1149                                groupCountTextSize.width();
    1150         int iGroupCountTextY = groupCountTextSize.height() == iFullHeaderHeight ?
    1151                                iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - groupCountTextSize.height()) / 2;
    1152         paintText(/* Painter: */
    1153                   pPainter,
    1154                   /* Rectangle to paint in: */
    1155                   QRect(QPoint(iGroupCountTextX, iGroupCountTextY), groupCountTextSize),
    1156                   /* Font to paint text: */
    1157                   infoFont,
    1158                   /* Text to paint: */
    1159                   strGroupCountText);
    1160 
    1161         /* We should draw group pixmap: */
    1162         int iGroupPixmapX = iGroupCountTextX -
    1163                             iMinorSpacing -
    1164                             groupPixmapSize.width();
    1165         int iGroupPixmapY = groupPixmapSize.height() == iFullHeaderHeight ?
    1166                             iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - groupPixmapSize.height()) / 2;
    1167         paintPixmap(/* Painter: */
    1168                     pPainter,
    1169                     /* Rectangle to paint in: */
    1170                     QRect(QPoint(iGroupPixmapX, iGroupPixmapY), groupPixmapSize),
    1171                     /* Pixmap to paint: */
    1172                     groupPixmap);
     1221        /* Indent: */
     1222        int iHorizontalIndent = fullRect.right() - iHorizontalMargin;
     1223        if (!isRoot())
     1224            iHorizontalIndent -= iEnterButtonWidth;
     1225
     1226        /* Should we draw machine count info? */
     1227        if (!strMachineCountText.isEmpty())
     1228        {
     1229            iHorizontalIndent -= machineCountTextSize.width();
     1230            int iMachineCountTextX = iHorizontalIndent;
     1231            int iMachineCountTextY = machineCountTextSize.height() == iFullHeaderHeight ?
     1232                                     iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - machineCountTextSize.height()) / 2;
     1233            paintText(/* Painter: */
     1234                      pPainter,
     1235                      /* Rectangle to paint in: */
     1236                      QRect(QPoint(iMachineCountTextX, iMachineCountTextY), machineCountTextSize),
     1237                      /* Font to paint text: */
     1238                      infoFont,
     1239                      /* Text to paint: */
     1240                      strMachineCountText);
     1241
     1242            iHorizontalIndent -= machinePixmapSize.width();
     1243            int iMachinePixmapX = iHorizontalIndent;
     1244            int iMachinePixmapY = machinePixmapSize.height() == iFullHeaderHeight ?
     1245                                  iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - machinePixmapSize.height()) / 2;
     1246            paintPixmap(/* Painter: */
     1247                        pPainter,
     1248                        /* Rectangle to paint in: */
     1249                        QRect(QPoint(iMachinePixmapX, iMachinePixmapY), machinePixmapSize),
     1250                        /* Pixmap to paint: */
     1251                        machinePixmap);
     1252        }
     1253
     1254        /* Should we draw group count info? */
     1255        if (!strGroupCountText.isEmpty())
     1256        {
     1257            iHorizontalIndent -= groupCountTextSize.width();
     1258            int iGroupCountTextX = iHorizontalIndent;
     1259            int iGroupCountTextY = groupCountTextSize.height() == iFullHeaderHeight ?
     1260                                   iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - groupCountTextSize.height()) / 2;
     1261            paintText(/* Painter: */
     1262                      pPainter,
     1263                      /* Rectangle to paint in: */
     1264                      QRect(QPoint(iGroupCountTextX, iGroupCountTextY), groupCountTextSize),
     1265                      /* Font to paint text: */
     1266                      infoFont,
     1267                      /* Text to paint: */
     1268                      strGroupCountText);
     1269
     1270            iHorizontalIndent -= groupPixmapSize.width();
     1271            int iGroupPixmapX = iHorizontalIndent;
     1272            int iGroupPixmapY = groupPixmapSize.height() == iFullHeaderHeight ?
     1273                                iVerticalMargin : iVerticalMargin + (iFullHeaderHeight - groupPixmapSize.height()) / 2;
     1274            paintPixmap(/* Painter: */
     1275                        pPainter,
     1276                        /* Rectangle to paint in: */
     1277                        QRect(QPoint(iGroupPixmapX, iGroupPixmapY), groupPixmapSize),
     1278                        /* Pixmap to paint: */
     1279                        groupPixmap);
     1280        }
     1281    }
     1282    else
     1283    {
     1284        /* Hide enter-button: */
     1285        if (m_pEnterButton)
     1286            m_pEnterButton->hide();
    11731287    }
    11741288}
     
    11771291{
    11781292    /* Only for item with button: */
    1179     if (!m_pButton)
     1293    if (!m_pToggleButton)
    11801294        return;
    11811295
     
    11841298    QSizeF closedSize = minimumSizeHint(true);
    11851299    int iAdditionalHeight = openedSize.height() - closedSize.height();
    1186     m_pButton->setAnimationRange(0, iAdditionalHeight);
     1300    m_pToggleButton->setAnimationRange(0, iAdditionalHeight);
    11871301}
    11881302
     
    12001314void UIGChooserItemGroup::prepare()
    12011315{
    1202     /* Setup toggle-button: */
    1203     m_pButton = new UIGraphicsRotatorButton(this, "additionalHeight", opened());
    1204     m_pButton->setIcon(data(GroupItemData_ButtonPixmap).value<QIcon>());
    1205     connect(m_pButton, SIGNAL(sigRotationStart()), this, SLOT(sltGroupToggleStart()));
    1206     connect(m_pButton, SIGNAL(sigRotationFinish(bool)), this, SLOT(sltGroupToggleFinish(bool)));
    1207     m_pButton->hide();
    1208 
    1209     /* Setup name-editor: */
    1210     m_pNameEditorWidget = new QLineEdit(m_strName);
    1211     m_pNameEditorWidget->setTextMargins(0, 0, 0, 0);
    1212     m_pNameEditorWidget->setFont(data(GroupItemData_NameFont).value<QFont>());
    1213     connect(m_pNameEditorWidget, SIGNAL(editingFinished()), this, SLOT(sltNameEditingFinished()));
    1214     m_pNameEditor = new QGraphicsProxyWidget(this);
    1215     m_pNameEditor->setWidget(m_pNameEditorWidget);
    1216     m_pNameEditor->hide();
     1316    /* Non root item only: */
     1317    if (!isRoot())
     1318    {
     1319        /* Setup toggle-button: */
     1320        m_pToggleButton = new UIGraphicsRotatorButton(this, "additionalHeight", opened());
     1321        m_pToggleButton->setIcon(data(GroupItemData_ToggleButtonPixmap).value<QIcon>());
     1322        connect(m_pToggleButton, SIGNAL(sigRotationStart()), this, SLOT(sltGroupToggleStart()));
     1323        connect(m_pToggleButton, SIGNAL(sigRotationFinish(bool)), this, SLOT(sltGroupToggleFinish(bool)));
     1324        m_pToggleButton->hide();
     1325
     1326        /* Setup enter-button: */
     1327        m_pEnterButton = new UIGraphicsButton(this);
     1328        m_pEnterButton->setIcon(data(GroupItemData_EnterButtonPixmap).value<QIcon>());
     1329        connect(m_pEnterButton, SIGNAL(sigButtonClicked()), this, SLOT(sltIndentRoot()));
     1330        m_pEnterButton->hide();
     1331
     1332        /* Setup name-editor: */
     1333        m_pNameEditorWidget = new QLineEdit(m_strName);
     1334        m_pNameEditorWidget->setTextMargins(0, 0, 0, 0);
     1335        m_pNameEditorWidget->setFont(data(GroupItemData_NameFont).value<QFont>());
     1336        connect(m_pNameEditorWidget, SIGNAL(editingFinished()), this, SLOT(sltNameEditingFinished()));
     1337        m_pNameEditor = new QGraphicsProxyWidget(this);
     1338        m_pNameEditor->setWidget(m_pNameEditorWidget);
     1339        m_pNameEditor->hide();
     1340    }
     1341    /* Root item but non main: */
     1342    if (!isMainRoot())
     1343    {
     1344        /* Setup exit-button: */
     1345        m_pExitButton = new UIGraphicsButton(this);
     1346        m_pExitButton->setIcon(data(GroupItemData_EnterButtonPixmap).value<QIcon>());
     1347        connect(m_pExitButton, SIGNAL(sigButtonClicked()), this, SLOT(sltUnindentRoot()));
     1348        QSizeF sh = m_pExitButton->minimumSizeHint();
     1349        m_pExitButton->setTransformOriginPoint(sh.width() / 2, sh.height() / 2);
     1350        m_pExitButton->setRotation(180);
     1351        m_pExitButton->hide();
     1352    }
    12171353}
    12181354
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemGroup.h

    r42630 r42678  
    2525/* Forward declarations: */
    2626class QGraphicsScene;
     27class UIGraphicsButton;
    2728class UIGraphicsRotatorButton;
    2829class QLineEdit;
     
    4748    /* Constructor/destructor: */
    4849    UIGChooserItemGroup(QGraphicsScene *pScene);
    49     UIGChooserItemGroup(QGraphicsScene *pScene, UIGChooserItemGroup *pCopyFrom);
     50    UIGChooserItemGroup(QGraphicsScene *pScene, UIGChooserItemGroup *pCopyFrom,
     51                        bool fMainRoot);
    5052    UIGChooserItemGroup(UIGChooserItem *pParent, const QString &strName,
    5153                        bool fOpened  = false , int iPosition  = -1 );
     
    7375    void sltGroupToggleFinish(bool fToggled);
    7476
     77    /* Handler: Indent root stuff: */
     78    void sltIndentRoot();
     79    void sltUnindentRoot();
     80
    7581private:
    7682
     
    8490        GroupItemData_MinorSpacing,
    8591        /* Pixmaps: */
    86         GroupItemData_ButtonPixmap,
     92        GroupItemData_ToggleButtonPixmap,
     93        GroupItemData_EnterButtonPixmap,
    8794        GroupItemData_GroupPixmap,
    8895        GroupItemData_MachinePixmap,
     
    95102        GroupItemData_MachineCountText,
    96103        /* Sizes: */
    97         GroupItemData_ButtonSize,
     104        GroupItemData_ToggleButtonSize,
     105        GroupItemData_EnterButtonSize,
     106        GroupItemData_ExitButtonSize,
    98107        GroupItemData_MinimumNameSize,
    99108        GroupItemData_NameSize,
     
    113122    void hide();
    114123    void startEditing();
     124    bool isMainRoot() const { return m_fMainRoot; }
    115125
    116126    /* Helpers: Children stuff: */
     
    161171    QString m_strName;
    162172    bool m_fClosed;
    163     UIGraphicsRotatorButton *m_pButton;
     173    UIGraphicsRotatorButton *m_pToggleButton;
     174    UIGraphicsButton *m_pEnterButton;
     175    UIGraphicsButton *m_pExitButton;
    164176    QLineEdit *m_pNameEditorWidget;
    165177    QGraphicsProxyWidget *m_pNameEditor;
     
    168180    int m_iAdditionalHeight;
    169181    int m_iCornerRadius;
     182    bool m_fMainRoot;
    170183};
    171184
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserItemMachine.cpp

    r42658 r42678  
    502502void UIGChooserItemMachine::paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget * /* pWidget = 0 */)
    503503{
     504    /* Setup: */
     505    pPainter->setRenderHint(QPainter::Antialiasing);
     506
    504507    /* Configure painter shape: */
    505508    configurePainterShape(pPainter, pOption, m_iCornerRadius);
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/chooser/UIGChooserModel.cpp

    r42659 r42678  
    129129
    130130    /* Create left root: */
    131     m_pLeftRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem());
     131    bool fLeftRootIsMain = root() == mainRoot();
     132    m_pLeftRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), fLeftRootIsMain);
    132133    m_pLeftRoot->setPos(0, 0);
    133134    m_pLeftRoot->resize(root()->geometry().size());
    134135
    135136    /* Create right root: */
    136     m_pRightRoot = new UIGChooserItemGroup(scene(), pNewRootItem->toGroupItem());
     137    m_pRightRoot = new UIGChooserItemGroup(scene(), pNewRootItem->toGroupItem(), false);
    137138    m_pRightRoot->setPos(root()->geometry().width(), 0);
    138139    m_pRightRoot->resize(root()->geometry().size());
     
    162163
    163164    /* Create left root: */
    164     m_pLeftRoot = new UIGChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem());
     165    bool fLeftRootIsMain = m_rootStack.at(m_rootStack.size() - 2) == mainRoot();
     166    m_pLeftRoot = new UIGChooserItemGroup(scene(), m_rootStack.at(m_rootStack.size() - 2)->toGroupItem(), fLeftRootIsMain);
    165167    m_pLeftRoot->setPos(- root()->geometry().width(), 0);
    166168    m_pLeftRoot->resize(root()->geometry().size());
    167169
    168170    /* Create right root: */
    169     m_pRightRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem());
     171    m_pRightRoot = new UIGChooserItemGroup(scene(), root()->toGroupItem(), false);
    170172    m_pRightRoot->setPos(0, 0);
    171173    m_pRightRoot->resize(root()->geometry().size());
     
    14911493                        /* Get group item: */
    14921494                        UIGChooserItem *pGroupItem = qgraphicsitem_cast<UIGChooserItemGroup*>(pItem);
     1495                        /* Make sure thats not root: */
     1496                        if (pGroupItem->isRoot())
     1497                            return false;
    14931498                        /* Is this group item only the one selected? */
    14941499                        if (selectionList().contains(pGroupItem) && selectionList().size() == 1)
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp

    r42639 r42678  
    428428        /* Add text height: */
    429429        if (!m_text.isEmpty())
    430             iProposedHeight += iMargin + iTextHeight;
     430            iProposedHeight += 2 * iMargin + iTextHeight;
    431431    }
    432432    else
     
    471471void UIGDetailsElement::paintDecorations(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption)
    472472{
    473     /* Prepare variables: */
    474     QRect fullRect = pOption->rect;
    475 
    476473    /* Paint background: */
    477474    paintBackground(/* Painter: */
    478475                    pPainter,
    479476                    /* Rectangle to paint in: */
    480                     fullRect,
     477                    pOption->rect,
    481478                    /* Rounded corners radius: */
    482479                    m_iCornerRadius,
    483480                    /* Header height: */
    484                     data(ElementData_Margin).toInt() +
    485                     data(ElementData_HeaderSize).toSize().height() +
    486                     1);
    487 
    488     /* Paint frame: */
    489     paintFrameRect(/* Painter: */
    490                    pPainter,
    491                    /* Rectangle to paint in: */
    492                    fullRect,
    493                    /* Rounded corner radius: */
    494                    m_iCornerRadius);
     481                    2 * data(ElementData_Margin).toInt() +
     482                    data(ElementData_HeaderSize).toSize().height());
    495483}
    496484
     
    565553        /* Where to paint? */
    566554        int iMachineTextX = iMachinePixmapX;
    567         int iMachineTextY = iMachinePixmapY + iHeaderHeight + iMargin;
     555        int iMachineTextY = iMachinePixmapY + iHeaderHeight + 2 * iMargin;
    568556
    569557        /* For each the line: */
     
    604592    pPainter->save();
    605593
    606     /* Fill rectangle with white color: */
     594    /* Prepare variables: */
     595    int iFullHeight = rect.height();
     596
     597    /* Prepare color: */
    607598    QPalette pal = QApplication::palette();
    608     pPainter->fillRect(rect, Qt::white);
    609 
    610     /* Prepare color: */
    611599    QColor windowColor = pal.color(QPalette::Active, QPalette::Window);
    612600
    613     /* Make even less rectangle: */
    614     QRect backGroundRect = rect;
    615     backGroundRect.setTopLeft(backGroundRect.topLeft() + QPoint(2, 2));
    616     backGroundRect.setBottomRight(backGroundRect.bottomRight() - QPoint(2, 2));
    617     /* Add even more clipping: */
    618     QPainterPath roundedPath;
    619     roundedPath.addRoundedRect(backGroundRect, iRadius, iRadius);
    620     pPainter->setClipPath(roundedPath);
     601    /* Add clipping: */
     602    QPainterPath path;
     603    path.moveTo(iRadius, 0);
     604    path.arcTo(QRectF(path.currentPosition(), QSizeF(2 * iRadius, 2 * iRadius)).translated(-iRadius, 0), 90, 90);
     605    path.lineTo(path.currentPosition().x(), iFullHeight - iRadius);
     606    path.arcTo(QRectF(path.currentPosition(), QSizeF(2 * iRadius, 2 * iRadius)).translated(0, -iRadius), 180, 90);
     607    path.lineTo(rect.width() - iRadius, path.currentPosition().y());
     608    path.arcTo(QRectF(path.currentPosition(), QSizeF(2 * iRadius, 2 * iRadius)).translated(-iRadius, -2 * iRadius), 270, 90);
     609    path.lineTo(path.currentPosition().x(), iRadius);
     610    path.arcTo(QRectF(path.currentPosition(), QSizeF(2 * iRadius, 2 * iRadius)).translated(-2 * iRadius, -iRadius), 0, 90);
     611    path.closeSubpath();
     612    pPainter->setClipPath(path);
    621613
    622614    /* Calculate top rectangle: */
    623     QRect tRect = backGroundRect;
     615    QRect tRect = rect;
    624616    tRect.setBottom(tRect.top() + iHeaderHeight);
    625617    /* Calculate bottom rectangle: */
    626     QRect bRect = backGroundRect;
     618    QRect bRect = rect;
    627619    bRect.setTop(tRect.bottom());
    628620
     
    633625
    634626    /* Paint all the stuff: */
    635     pPainter->fillRect(bRect, windowColor.darker(99));
    636627    pPainter->fillRect(tRect, tGradient);
     628    pPainter->fillRect(bRect, windowColor.darker(97));
     629
     630    /* Stroke path: */
     631    pPainter->setClipping(false);
     632    pPainter->strokePath(path, windowColor.darker(130));
    637633
    638634    /* Restore painter: */
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsGroup.cpp

    r42608 r42678  
    122122    {
    123123        /* Layout hints: */
    124         case GroupData_Margin: return 1;
     124        case GroupData_Margin: return 2;
    125125        case GroupData_Spacing: return 10;
    126126        /* Default: */
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsSet.cpp

    r42626 r42678  
    106106        /* Layout hints: */
    107107        case SetData_Margin: return 0;
    108         case SetData_Spacing: return 1;
     108        case SetData_Spacing: return 3;
    109109        /* Default: */
    110110        default: break;
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.cpp

    r42526 r42678  
    2020/* Qt includes: */
    2121#include <QPainter>
     22#include <QGraphicsSceneMouseEvent>
    2223
    2324/* GUI includes: */
     
    4344    switch (iKey)
    4445    {
    45         case GraphicsButton_Margin: return 3;
     46        case GraphicsButton_Margin: return 0;
    4647        case GraphicsButton_IconSize: return m_icon.isNull() ? QSize(16, 16) : m_icon.availableSizes().first();
    4748        case GraphicsButton_Icon: return m_icon;
     
    8485void UIGraphicsButton::mousePressEvent(QGraphicsSceneMouseEvent *pEvent)
    8586{
     87    /* Accepting this event allows to get release-event: */
     88    pEvent->accept();
     89}
     90
     91void UIGraphicsButton::mouseReleaseEvent(QGraphicsSceneMouseEvent *pEvent)
     92{
     93    /* Call to base-class: */
     94    QIGraphicsWidget::mouseReleaseEvent(pEvent);
    8695    /* Notify listeners about button click: */
    8796    emit sigButtonClicked();
    88     /* Propagate to parent: */
    89     QIGraphicsWidget::mousePressEvent(pEvent);
    9097}
    9198
  • trunk/src/VBox/Frontends/VirtualBox/src/widgets/graphics/UIGraphicsButton.h

    r42526 r42678  
    6666    virtual void paint(QPainter *pPainter, const QStyleOptionGraphicsItem *pOption, QWidget *pWidget = 0);
    6767
    68     /* Mouse-press handler: */
     68    /* Mouse handlers: */
    6969    virtual void mousePressEvent(QGraphicsSceneMouseEvent *pEvent);
     70    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *pEvent);
    7071
    7172    /* Helpers: Update stuff: */
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