VirtualBox

Changeset 2524 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
May 7, 2007 3:40:21 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20957
Message:

FE/Qt: Improved QIStateIndicator so that it is properly drawn over a pixmap-based widget background (as on Mac) and picks up dynamic widget style changes.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/include/QIStateIndicator.h

    r382 r2524  
    3535public:
    3636
    37     QIStateIndicator (
    38         int state,
    39         QWidget *parent, const char *name = 0, WFlags f = 0
    40     );
     37    QIStateIndicator (int aState,
     38                      QWidget *aParent, const char *aName = 0,
     39                      WFlags aFlags = 0);
    4140
    4241    virtual QSize sizeHint() const;
    4342
    44     int state () const { return st; }
     43    int state () const { return mState; }
    4544
    46     QPixmap stateIcon (int st) const;
    47     void setStateIcon (int st, const QPixmap &pm);
     45    QPixmap stateIcon (int aState) const;
     46    void setStateIcon (int aState, const QPixmap &aPixmap);
    4847
    4948public slots:
    5049
    51     void setState (int s);
    52     void setState (bool s) { setState ((int) s); }
     50    void setState (int aState);
     51    void setState (bool aState) { setState ((int) aState); }
    5352
    5453signals:
    5554
    56     void mouseDoubleClicked (QIStateIndicator *indicator, QMouseEvent *e);
    57     void contextMenuRequested (QIStateIndicator *indicator, QContextMenuEvent *e);
     55    void mouseDoubleClicked (QIStateIndicator *aIndicator,
     56                             QMouseEvent *aEv);
     57    void contextMenuRequested (QIStateIndicator *aIndicator,
     58                               QContextMenuEvent *aEv);
    5859
    5960protected:
    6061
    61     virtual void drawContents (QPainter *p);
     62    virtual void drawContents (QPainter *aPainter);
    6263
    63     virtual void mouseDoubleClickEvent (QMouseEvent * e);
    64     virtual void contextMenuEvent (QContextMenuEvent * e);
     64    virtual void mouseDoubleClickEvent (QMouseEvent *aEv);
     65    virtual void contextMenuEvent (QContextMenuEvent *aEv);
    6566
    6667private:
    6768
    68     int st;
    69     QSize sz;
     69    int mState;
     70    QSize mSize;
    7071
    71     QIntDict <QPixmap> state_icons;
     72    struct Icon
     73    {
     74        Icon (const QPixmap &aPixmap)
     75            : pixmap (aPixmap)
     76            , bgPixmap (NULL) {}
     77
     78        QPixmap pixmap;
     79        QPixmap cached;
     80        QColor bgColor;
     81        const QPixmap *bgPixmap;
     82        QPoint bgOff;
     83    };
     84
     85    QIntDict <Icon> mStateIcons;
    7286};
    7387
  • trunk/src/VBox/Frontends/VirtualBox/src/QIStateIndicator.cpp

    r2316 r2524  
    3535 *  until icons are specified for necessary states.
    3636 *
    37  *  @param state
     37 *  @param aState
    3838 *      the initial indicator state
    3939 */
    40 QIStateIndicator::QIStateIndicator (
    41     int state,
    42     QWidget *parent, const char *name, WFlags f
    43 ) :
    44     QFrame (parent, name, f | WStaticContents | WMouseNoMask)
     40QIStateIndicator::QIStateIndicator (int aState,
     41                                    QWidget *aParent, const char *aName,
     42                                    WFlags aFlags)
     43    : QFrame (aParent, aName, aFlags | WStaticContents | WMouseNoMask)
    4544{
    46     st = state;
    47     sz = QSize (0, 0);
    48     state_icons.setAutoDelete (true);
     45    mState = aState;
     46    mSize = QSize (0, 0);
     47    mStateIcons.setAutoDelete (true);
    4948
    5049    setSizePolicy (QSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed));
     50
     51    /* we will precompose the pixmap background using the widget bacground in
     52     * drawContents(), so try to set the correct bacground origin for the
     53     * case when a pixmap is used as a widget background. */
     54    if (aParent)
     55        setBackgroundOrigin (aParent->backgroundOrigin());
    5156}
    5257
    5358QSize QIStateIndicator::sizeHint() const
    5459{
    55     return sz;
     60    return mSize;
    5661}
    5762
    58 QPixmap QIStateIndicator::stateIcon (int s) const
     63QPixmap QIStateIndicator::stateIcon (int aState) const
    5964{
    60     QPixmap *pm = state_icons [s];
    61     return pm ? QPixmap (*pm) : QPixmap();
     65    Icon *icon = mStateIcons [aState];
     66    return icon ? icon->pixmap : QPixmap();
    6267}
    6368
     
    6772 *  scaled to fit this size.
    6873 *
    69  *  @note
    70  *      If this widget was constructed with the WNoAutoErase flag, then all
    71  *      transparent areas of the new state icon are filled with the widget
    72  *      background color (taken from its palette) to provide flicker free
    73  *      state redraws (which is useful for indicators that frequently
    74  *      change their state).
     74 *  @note If this widget is constructed with the WNoAutoErase flag, then all
     75 *  transparent areas of the new state icon are filled with the widget
     76 *  background color or pixmap (as taken from the widget palette), to provide
     77 *  flicker free state redraws in one single operation (which is useful for
     78 *  indicators that frequently change their state).
    7579 */
    76 void QIStateIndicator::setStateIcon (int s, const QPixmap &pm)
     80void QIStateIndicator::setStateIcon (int aState, const QPixmap &aPixmap)
    7781{
    78     QPixmap *icon;
    79     if (testWFlags (WNoAutoErase)) {
    80         icon = new QPixmap (pm.size());
    81 #ifdef Q_WS_MAC /* the background color isn't the pattern used for the console window frame */
    82         const QPixmap *back = backgroundPixmap();
    83         if (back) /* Is ClearROP right? I've no clue about raster operations... */
    84             bitBlt (icon, 0, 0, back, 0, 0, pm.width(), pm.height(), ClearROP, false);
    85         else
    86 #endif
    87             icon->fill (paletteBackgroundColor());
    88         bitBlt (icon, 0, 0, &pm, 0, 0, pm.width(), pm.height(), CopyROP, false);
    89     } else {
    90         icon = new QPixmap (pm);
    91     }
     82    /* Here we just set the original pixmap. All actual work from the @note
     83     * above takes place in #drawContents(). */
     84    mStateIcons.insert (aState, new Icon (aPixmap));
    9285
    93     state_icons.insert (s, icon);
    94     if (sz.isNull()) {
    95         sz = pm.size();
    96     }
     86    if (mSize.isNull())
     87        mSize = aPixmap.size();
    9788}
    9889
    99 void QIStateIndicator::setState (int s)
     90void QIStateIndicator::setState (int aState)
    10091{
    101     st = s;
     92    mState = aState;
    10293    repaint (false);
    10394}
    10495
    105 void QIStateIndicator::drawContents (QPainter *p)
     96void QIStateIndicator::drawContents (QPainter *aPainter)
    10697{
    107     QPixmap *pm = state_icons [st];
    108     if (!pm)
     98    Icon *icon = mStateIcons [mState];
     99    if (!icon)
     100    {
    109101        erase();
     102    }
    110103    else
    111         p->drawPixmap (contentsRect(), *pm);
     104    {
     105        if (testWFlags (WNoAutoErase))
     106        {
     107            QColor bgColor = paletteBackgroundColor();
     108            const QPixmap *bgPixmap = paletteBackgroundPixmap();
     109            QPoint bgOff = backgroundOffset();
     110
     111            bool bgOffChanged = icon->bgOff != bgOff;
     112            bool bgPixmapChanged = icon->bgPixmap != bgPixmap ||
     113                (icon->bgPixmap != NULL &&
     114                 icon->bgPixmap->serialNumber() != bgPixmap->serialNumber());
     115            bool bgColorChanged = icon->bgColor != bgColor;
     116
     117            /* re-precompose the pixmap if any of these have changed */
     118            if (icon->cached.isNull() ||
     119                bgOffChanged || bgPixmapChanged || bgColorChanged)
     120            {
     121                int w = icon->pixmap.width();
     122                int h = icon->pixmap.height();
     123                if (icon->cached.isNull())
     124                    icon->cached = QPixmap (w, h);
     125
     126                if (bgPixmap || bgOffChanged || bgPixmapChanged)
     127                {
     128                    QPainter p (&icon->cached);
     129                    p.drawTiledPixmap (QRect (0, 0, w, h), *bgPixmap, bgOff);
     130                }
     131                else
     132                {
     133                    icon->cached.fill (bgColor);
     134                }
     135                /* paint the icon on top of the widget background sample */
     136                bitBlt (&icon->cached, 0, 0, &icon->pixmap,
     137                        0, 0, w, h, CopyROP, false);
     138                /* store the new values */
     139                icon->bgColor = bgColor;
     140                icon->bgPixmap = bgPixmap;
     141                icon->bgOff = bgOff;
     142            }
     143            /* draw the precomposed pixmap */
     144            aPainter->drawPixmap (contentsRect(), icon->cached);
     145        }
     146        else
     147        {
     148            aPainter->drawPixmap (contentsRect(), icon->pixmap);
     149        }
     150    }
    112151}
    113152
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette