VirtualBox

Ignore:
Timestamp:
Aug 5, 2012 9:52:41 PM (13 years ago)
Author:
vboxsync
Message:

FE/Qt: 6234: Support for VM groups: Details-view layout fix and word-wrapping support.

Location:
trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.cpp

    r42593 r42608  
    9494int UIGDetailsElement::minimumWidthHint() const
    9595{
    96     /* First of all, we have to prepare few variables: */
     96    /* Prepare variables: */
    9797    int iMargin = data(ElementData_Margin).toInt();
    9898    int iHeaderWidth = data(ElementData_HeaderSize).toSize().width();
    99     int iTextWidth = data(ElementData_TextSize).toSize().width();
     99    int iTextWidth = data(ElementData_TextWidth).toInt();
    100100
    101101    /* Calculating proposed width: */
     
    210210            return QSize(iHeaderWidth, iHeaderHeight);
    211211        }
    212         case ElementData_TextSize:
    213         {
     212        case ElementData_TextWidth:
     213        {
     214            /* Prepare variables: */
    214215            int iSpacing = data(ElementData_Spacing).toInt();
     216            int iMinimumTextColumnWidth = data(ElementData_MinimumTextColumnWidth).toInt();
    215217            QFontMetrics fm(data(ElementData_TextFont).value<QFont>());
    216             int iLongestFirst = 0;
    217             int iLongestSecond = 0;
    218             foreach (const UITextTableLine &line, m_text)
     218
     219            /* Search for the maximum line widths: */
     220            int iMaximumFirstLineWidth = 0;
     221            int iMaximumSecondLineWidth = 0;
     222            foreach (const UITextTableLine line, m_text)
    219223            {
    220                 iLongestFirst = qMax(iLongestFirst, fm.width(line.first));
    221                 iLongestSecond = qMax(iLongestSecond, fm.width(line.second));
     224                bool fKeyValueRow = !line.second.isEmpty();
     225                QString strFirstLine = fKeyValueRow ? line.first + ":" : line.first;
     226                QString strSecondLine = line.second;
     227                iMaximumFirstLineWidth = qMax(iMaximumFirstLineWidth, fm.width(strFirstLine));
     228                iMaximumSecondLineWidth = qMax(iMaximumSecondLineWidth, fm.width(strSecondLine));
    222229            }
    223             int iLongestLine = iLongestFirst + iSpacing + iLongestSecond;
    224             int iSummaryHeight = fm.height() * m_text.size();
    225             return QSize(iLongestLine, iSummaryHeight);
    226         }
     230
     231            /* Calculate minimum text width: */
     232            int iMinimumFirstLineWidth = qMin(iMaximumFirstLineWidth, iMinimumTextColumnWidth);
     233            int iMinimumSecondLineWidth = qMin(iMaximumSecondLineWidth, iMinimumTextColumnWidth);
     234            int iMinimumTextWidth = iMinimumFirstLineWidth + iSpacing + iMinimumSecondLineWidth;
     235
     236            /* Return result: */
     237            return iMinimumTextWidth;
     238        }
     239        case ElementData_TextHeight:
     240        {
     241            /* Prepare variables: */
     242            int iMargin = data(ElementData_Margin).toInt();
     243            int iSpacing = data(ElementData_Spacing).toInt();
     244            int iMinimumTextColumnWidth = data(ElementData_MinimumTextColumnWidth).toInt();
     245            int iMaximumTextWidth = (int)geometry().width() - 3 * iMargin - iSpacing;
     246            QFont textFont = data(ElementData_TextFont).value<QFont>();
     247            QFontMetrics fm(textFont);
     248
     249            /* Search for maximum line widths: */
     250            int iMaximumFirstLineWidth = 0;
     251            int iMaximumSecondLineWidth = 0;
     252            foreach (const UITextTableLine line, m_text)
     253            {
     254                bool fKeyValueRow = !line.second.isEmpty();
     255                QString strFirstLine = fKeyValueRow ? line.first + ":" : line.first;
     256                QString strSecondLine = line.second;
     257                iMaximumFirstLineWidth = qMax(iMaximumFirstLineWidth, fm.width(strFirstLine));
     258                iMaximumSecondLineWidth = qMax(iMaximumSecondLineWidth, fm.width(strSecondLine));
     259            }
     260
     261            /* Calculate column widths: */
     262            int iFirstColumnWidth = iMaximumTextWidth / 2;
     263            int iSecondColumnWidth = iMaximumTextWidth / 2;
     264            if (iMaximumFirstLineWidth < iMinimumTextColumnWidth)
     265            {
     266                iFirstColumnWidth = iMaximumFirstLineWidth;
     267                iSecondColumnWidth = iMaximumTextWidth - iFirstColumnWidth;
     268            }
     269            else if (iMaximumSecondLineWidth < iMinimumTextColumnWidth)
     270            {
     271                iSecondColumnWidth = iMaximumSecondLineWidth;
     272                iFirstColumnWidth = iMaximumTextWidth - iSecondColumnWidth;
     273            }
     274
     275            /* For each the line: */
     276            int iSummaryTextHeight = 0;
     277            foreach (const UITextTableLine line, m_text)
     278            {
     279                /* First layout: */
     280                int iFirstColumnHeight = 0;
     281                if (!line.first.isEmpty())
     282                {
     283                    bool fKeyValueRow = !line.second.isEmpty();
     284                    QTextLayout *pTextLayout = prepareTextLayout(textFont,
     285                                                                 fKeyValueRow ? line.first + ":" : line.first,
     286                                                                 iFirstColumnWidth, iFirstColumnHeight);
     287                    delete pTextLayout;
     288                }
     289
     290                /* Second layout: */
     291                int iSecondColumnHeight = 0;
     292                if (!line.second.isEmpty())
     293                {
     294                    QTextLayout *pTextLayout = prepareTextLayout(textFont, line.second,
     295                                                                 iSecondColumnWidth, iSecondColumnHeight);
     296                    delete pTextLayout;
     297                }
     298
     299                /* Append summary text height: */
     300                iSummaryTextHeight += qMax(iFirstColumnHeight, iSecondColumnHeight);
     301            }
     302
     303            /* Return result: */
     304            return iSummaryTextHeight;
     305        }
     306        case ElementData_MinimumTextColumnWidth: return 100;
    227307        /* Default: */
    228308        default: break;
     
    301381}
    302382
    303 void UIGDetailsElement::updateSizeHint()
    304 {
    305     updateGeometry();
    306 }
    307 
    308383void UIGDetailsElement::updateLayout()
    309384{
     385    /* Update size-hint: */
     386    updateSizeHint();
     387
    310388    /* Prepare variables: */
    311389    QSize size = geometry().size().toSize();
     
    341419int UIGDetailsElement::minimumHeightHint(bool fClosed) const
    342420{
    343     /* First of all, we have to prepare few variables: */
     421    /* Prepare variables: */
    344422    int iMargin = data(ElementData_Margin).toInt();
    345423    int iHeaderHeight = data(ElementData_HeaderSize).toSize().height();
    346     int iTextHeight = data(ElementData_TextSize).toSize().height();
     424    int iTextHeight = data(ElementData_TextHeight).toInt();
    347425
    348426    /* Calculating proposed height: */
     
    472550    if (!m_fClosed && !m_text.isEmpty())
    473551    {
     552        /* Prepare variables: */
     553        int iMinimumTextColumnWidth = data(ElementData_MinimumTextColumnWidth).toInt();
     554        int iMaximumTextWidth = geometry().width() - 3 * iMargin - iSpacing;
     555        QFont textFont = data(ElementData_TextFont).value<QFont>();
     556        QFontMetrics fm(textFont);
     557
     558        /* Search for maximum line widths: */
     559        int iMaximumFirstLineWidth = 0;
     560        int iMaximumSecondLineWidth = 0;
     561        foreach (const UITextTableLine line, m_text)
     562        {
     563            bool fKeyValueRow = !line.second.isEmpty();
     564            QString strFirstLine = fKeyValueRow ? line.first + ":" : line.first;
     565            QString strSecondLine = line.second;
     566            iMaximumFirstLineWidth = qMax(iMaximumFirstLineWidth, fm.width(strFirstLine));
     567            iMaximumSecondLineWidth = qMax(iMaximumSecondLineWidth, fm.width(strSecondLine));
     568        }
     569
     570        /* Calculate column widths: */
     571        int iFirstColumnWidth = iMaximumTextWidth / 2;
     572        int iSecondColumnWidth = iMaximumTextWidth / 2;
     573        if (iMaximumFirstLineWidth < iMinimumTextColumnWidth)
     574        {
     575            iFirstColumnWidth = iMaximumFirstLineWidth;
     576            iSecondColumnWidth = iMaximumTextWidth - iFirstColumnWidth;
     577        }
     578        else if (iMaximumSecondLineWidth < iMinimumTextColumnWidth)
     579        {
     580            iSecondColumnWidth = iMaximumSecondLineWidth;
     581            iFirstColumnWidth = iMaximumTextWidth - iSecondColumnWidth;
     582        }
     583
    474584        /* Where to paint? */
    475585        int iMachineTextX = iMachinePixmapX;
    476586        int iMachineTextY = iMachinePixmapY + iHeaderHeight + iMargin;
    477587
    478         /* Font metrics: */
    479         QFontMetrics fm(data(ElementData_TextFont).value<QFont>());
    480 
    481         /* For each the line, get longest 'first': */
    482         int iLongestFirst = 0;
    483         foreach (const UITextTableLine line, m_text)
    484             iLongestFirst = qMax(iLongestFirst, fm.width(line.first));
    485 
    486588        /* For each the line: */
    487589        foreach (const UITextTableLine line, m_text)
    488590        {
    489             /* Do we have a key-value pair? */
    490             bool fKeyValueRow = !line.second.isEmpty();
    491 
    492591            /* First layout: */
    493             QTextLayout keyLayout(fKeyValueRow ? line.first + ":" : line.first);
    494             keyLayout.beginLayout();
    495             keyLayout.createLine();
    496             keyLayout.endLayout();
    497             keyLayout.draw(pPainter, QPointF(iMachineTextX, iMachineTextY));
     592            int iFirstColumnHeight = 0;
     593            if (!line.first.isEmpty())
     594            {
     595                bool fKeyValueRow = !line.second.isEmpty();
     596                QTextLayout *pTextLayout = prepareTextLayout(textFont,
     597                                                             fKeyValueRow ? line.first + ":" : line.first,
     598                                                             iFirstColumnWidth, iFirstColumnHeight);
     599                pTextLayout->draw(pPainter, QPointF(iMachineTextX, iMachineTextY));
     600                delete pTextLayout;
     601            }
    498602
    499603            /* Second layout: */
     604            int iSecondColumnHeight = 0;
    500605            if (!line.second.isEmpty())
    501606            {
    502                 QTextLayout valueLayout(line.second);
    503                 valueLayout.beginLayout();
    504                 valueLayout.createLine();
    505                 valueLayout.endLayout();
    506                 valueLayout.draw(pPainter, QPointF(iMachineTextX + iLongestFirst + iSpacing, iMachineTextY));
     607                QTextLayout *pTextLayout = prepareTextLayout(textFont, line.second,
     608                                                             iSecondColumnWidth, iSecondColumnHeight);
     609                pTextLayout->draw(pPainter, QPointF(iMachineTextX + iMaximumFirstLineWidth + iSpacing, iMachineTextY));
     610                delete pTextLayout;
    507611            }
    508612
    509             /* Append the Y: */
    510             iMachineTextY += fm.height();
     613            /* Indent Y: */
     614            iMachineTextY += qMax(iFirstColumnHeight, iSecondColumnHeight);
    511615        }
    512616    }
     
    649753}
    650754
     755/* static  */
     756QTextLayout* UIGDetailsElement::prepareTextLayout(const QFont &font, const QString &strText, int iWidth, int &iHeight)
     757{
     758    /* Prepare variables: */
     759    QFontMetrics fm(font);
     760    int iLeading = fm.leading();
     761
     762    /* Create layout; */
     763    QTextLayout *pTextLayout = new QTextLayout(strText, font);
     764
     765    /* Configure layout: */
     766    QTextOption textOption;
     767    textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
     768    pTextLayout->setTextOption(textOption);
     769
     770    /* Build layout: */
     771    pTextLayout->beginLayout();
     772    while (1)
     773    {
     774        QTextLine line = pTextLayout->createLine();
     775        if (!line.isValid())
     776            break;
     777
     778        line.setLineWidth(iWidth);
     779        iHeight += iLeading;
     780        line.setPosition(QPointF(0, iHeight));
     781        iHeight += line.height();
     782    }
     783    pTextLayout->endLayout();
     784
     785    /* Return layout: */
     786    return pTextLayout;
     787}
     788
    651789void UIGDetailsElement::updateAnimationParameters()
    652790{
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsElement.h

    r42529 r42608  
    3131class CMachine;
    3232class UIGraphicsRotatorButton;
     33class QTextLayout;
    3334
    3435/* Typedefs: */
     
    99100        ElementData_ButtonSize,
    100101        ElementData_HeaderSize,
    101         ElementData_TextSize
     102        ElementData_TextWidth,
     103        ElementData_TextHeight,
     104        ElementData_MinimumTextColumnWidth
    102105    };
    103106
     
    118121
    119122    /* Helpers: Layout stuff: */
    120     void updateSizeHint();
    121123    void updateLayout();
    122124
     
    170172    void updateNameHoverRepresentation(QGraphicsSceneHoverEvent *pEvent);
    171173
     174    /* Helper: Layout stuff: */
     175    static QTextLayout* prepareTextLayout(const QFont &font, const QString &strText, int iWidth, int &iHeight);
     176
    172177    /* Helper: Animation stuff: */
    173178    void updateAnimationParameters();
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsGroup.cpp

    r42600 r42608  
    130130}
    131131
    132 void UIGDetailsGroup::updateSizeHint()
     132void UIGDetailsGroup::updateLayout()
    133133{
    134134    /* Update size-hints for all the items: */
     
    136136        pItem->updateSizeHint();
    137137    /* Update size-hint for this item: */
    138     updateGeometry();
    139 }
    140 
    141 void UIGDetailsGroup::updateLayout()
    142 {
     138    updateSizeHint();
     139
     140    /* Update layout finally: */
    143141    m_pMainLayout->activate();
    144142    m_pLayout->activate();
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsGroup.h

    r42600 r42608  
    6161
    6262    /* API: Layout stuff: */
    63     void updateSizeHint();
    6463    void updateLayout();
    6564
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsItem.cpp

    r42600 r42608  
    8181}
    8282
     83void UIGDetailsItem::updateSizeHint()
     84{
     85    updateGeometry();
     86}
     87
    8388#if 0
    8489void UIGDetailsItem::hoverEnterEvent(QGraphicsSceneHoverEvent*)
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsItem.h

    r42600 r42608  
    7171
    7272    /* API: Layout stuff: */
    73     virtual void updateSizeHint() = 0;
     73    void updateSizeHint();
    7474    virtual void updateLayout() = 0;
    7575
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsModel.cpp

    r42600 r42608  
    7979    int iViewportWidth = viewportSize.width() - 2 * iSceneMargin;
    8080    int iViewportHeight = viewportSize.height() - 2 * iSceneMargin;
    81     /* Update all the size-hints recursively: */
    82     m_pRoot->updateSizeHint();
    8381    /* Set root item position: */
    8482    m_pRoot->setPos(iSceneMargin, iSceneMargin);
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsSet.cpp

    r42600 r42608  
    207207}
    208208
    209 void UIGDetailsSet::updateSizeHint()
     209void UIGDetailsSet::updateLayout()
    210210{
    211211    /* Update size-hints for all the items: */
     
    213213        pItem->updateSizeHint();
    214214    /* Update size-hint for this item: */
    215     updateGeometry();
    216 }
    217 
    218 void UIGDetailsSet::updateLayout()
    219 {
     215    updateSizeHint();
     216
    220217    /* Prepare variables: */
    221218    int iMargin = data(SetData_Margin).toInt();
     
    242239                int iWidth = iPreviewWidth == 0 ? iMaximumWidth - 2 * iMargin :
    243240                                                  iMaximumWidth - 2 * iMargin - iSpacing - iPreviewWidth;
     241                pElement->setPos(iMargin, iVerticalIndent);
     242                /* Resize to required width: */
    244243                int iHeight = pElement->minimumHeightHint();
    245                 pElement->setPos(iMargin, iVerticalIndent);
     244                pElement->resize(iWidth, iHeight);
     245                /* Update minimum height hint: */
     246                pItem->updateSizeHint();
     247                /* Resize to required height: */
     248                iHeight = pElement->minimumHeightHint();
    246249                pElement->resize(iWidth, iHeight);
    247250                pItem->updateLayout();
     
    272275            {
    273276                int iWidth = iMaximumWidth - 2 * iMargin;
     277                pElement->setPos(iMargin, iVerticalIndent);
     278                /* Resize to required width: */
    274279                int iHeight = pElement->minimumHeightHint();
    275                 pElement->setPos(iMargin, iVerticalIndent);
    276280                pElement->resize(iWidth, iHeight);
     281                /* Update minimum height hint: */
     282                pItem->updateSizeHint();
     283                /* Resize to required height: */
     284                iHeight = pElement->minimumHeightHint();
     285                pElement->resize(iWidth, iHeight);
     286                pItem->updateLayout();
    277287                iVerticalIndent += (iHeight + iSpacing);
    278                 pItem->updateLayout();
    279288                break;
    280289            }
  • trunk/src/VBox/Frontends/VirtualBox/src/selector/graphics/details/UIGDetailsSet.h

    r42600 r42608  
    9090
    9191    /* Helpers: Layout stuff: */
    92     void updateSizeHint();
    9392    void updateLayout();
    9493    int minimumWidthHint() const;
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