示例#1
0
bool QDecorationWindows::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
                               DecorationState state)
{
    if (decorationRegion == None)
        return false;

    const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
    const QPalette pal = QApplication::palette();
    QRegion oldClipRegion = painter->clipRegion();

    bool paintAll = (decorationRegion == int(All));
    if ((paintAll || decorationRegion & Title && titleRect.width() > 0) && state == Normal
        && (widget->windowFlags() & Qt::WindowTitleHint) ) {
        painter->setClipRegion(oldClipRegion);
        QColor fromBrush, toBrush;
        QPen   titlePen;

        if (widget == qApp->activeWindow() || qApp->activeWindow() == qApp->activePopupWidget()) {
            fromBrush = pal.color(QPalette::Highlight);
            titlePen  = pal.color(QPalette::HighlightedText);
        } else {
            fromBrush = pal.color(QPalette::Window);
            titlePen  = pal.color(QPalette::Text);
        }
        toBrush = fromBrush.lighter(300);

        painter->setPen(Qt::NoPen);
        QPoint p1(titleRect.x(), titleRect.y() + titleRect.height()/2);
        QPoint p2(titleRect.right(), titleRect.y() + titleRect.height()/2);
        QLinearGradient lg(p1, p2);
        lg.setColorAt(0, fromBrush);
        lg.setColorAt(1, toBrush);
        painter->fillRect(titleRect, lg);

        painter->setPen(titlePen);
        painter->drawText(titleRect, Qt::AlignVCenter, windowTitleFor(widget));
        decorationRegion ^= Title;
    }

    return QDecorationDefault::paint(painter, widget, decorationRegion, state);
}
int QDecorationStyled::titleBarHeight(const QWidget *widget)
{
    QStyleOptionTitleBar opt;
    opt.subControls = QStyle::SC_TitleBarLabel
                      | QStyle::SC_TitleBarSysMenu
                      | QStyle::SC_TitleBarNormalButton
                      | QStyle::SC_TitleBarContextHelpButton
                      | QStyle::SC_TitleBarMinButton
                      | QStyle::SC_TitleBarMaxButton
                      | QStyle::SC_TitleBarCloseButton;
    opt.titleBarFlags = widget->windowFlags();
    opt.direction = QApplication::layoutDirection();
    opt.text = windowTitleFor(widget);
    opt.icon = widget->windowIcon();
    opt.rect = widget->rect();

    QStyle *style = QApplication::style();
    if (!style)
        return 18;

    return style->pixelMetric(QStyle::PM_TitleBarHeight, &opt, 0);
}
bool QDecorationStyled::paint(QPainter *painter, const QWidget *widget, int decorationRegion,
                            DecorationState state)
{
    if (decorationRegion == None)
        return false;

    bool isActive = (widget == qApp->activeWindow());
    QPalette pal = qApp->palette();
    //ideally, the difference between Active and Inactive should be enough, so we shouldn't need to test this
    if (!isActive) {
        //pal.setCurrentColorGroup(QPalette::Disabled); //Can't do this either, because of palette limitations
        //copied from Q3TitleBar:
	pal.setColor(QPalette::Inactive, QPalette::Highlight,
		     pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::Base,
                      pal.color(QPalette::Inactive, QPalette::Dark));
        pal.setColor(QPalette::Inactive, QPalette::HighlightedText,
                      pal.color(QPalette::Inactive, QPalette::Window));
    }

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasBorder = !widget->isMaximized();
    bool hasTitle = flags & Qt::WindowTitleHint;
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    bool paintAll = (DecorationRegion(decorationRegion) == All);
    bool handled = false;

    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
        QRegion newClip = painter->clipRegion();
        if (hasTitle) { // reduce flicker
            QRect rect(widget->rect());
            QRect r(rect.left() - titleExtra, rect.top() - titleHeight,
                    rect.width() + 2 * titleExtra, titleHeight);
            newClip -= r;
        }
        if (!newClip.isEmpty()) {
            QRect br = QDecoration::region(widget).boundingRect();
            painter->save();
            painter->setClipRegion(newClip);

            QStyleOptionFrame opt;
            opt.palette = pal;
            opt.rect = br;
            opt.lineWidth = borderWidth;

            if (isActive)
                opt.state |= QStyle::State_Active;
            bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_Source);
            painter->fillRect(br, pal.window());
            if (porterDuff)
                painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
            style->drawPrimitive(QStyle::PE_FrameWindow, &opt, painter, 0);
            painter->restore();

            decorationRegion &= (~Borders);
            handled |= true;
        }
    }

    if (hasTitle) {
        painter->save();

        QStyleOptionTitleBar opt;
        opt.subControls = (decorationRegion & Title
                              ? QStyle::SC_TitleBarLabel : QStyle::SubControl(0))
                          | (decorationRegion & Menu
                              ? QStyle::SC_TitleBarSysMenu : QStyle::SubControl(0))
                          | (decorationRegion & Help
                              ? QStyle::SC_TitleBarContextHelpButton : QStyle::SubControl(0))
                          | (decorationRegion & Minimize
                              ? QStyle::SC_TitleBarMinButton : QStyle::SubControl(0))
                          | (decorationRegion & Maximize
                              ? QStyle::SC_TitleBarMaxButton : QStyle::SubControl(0))
                          | (decorationRegion & (Minimize | Maximize)
                              ? QStyle::SC_TitleBarNormalButton : QStyle::SubControl(0))
                          | (decorationRegion & Close
                              ? QStyle::SC_TitleBarCloseButton : QStyle::SubControl(0));
        opt.titleBarFlags = widget->windowFlags();
        opt.titleBarState = widget->windowState();
        if (isActive)
            opt.titleBarState |= QStyle::State_Active;
        opt.text = windowTitleFor(widget);
        opt.icon = widget->windowIcon();
        opt.palette = pal;
        opt.rect = QRect(widget->rect().x() - titleExtra, -titleHeight,
                         widget->rect().width() + 2 * titleExtra, titleHeight);

        if (paintAll) {
            painter->setClipRegion(opt.rect);
        } else {
            const QRect widgetRect = widget->rect();
            QRegion newClip = opt.rect;
            if (!(decorationRegion & Menu) && hasSysMenu)
                newClip -= region(widget, widgetRect, Menu);
            if (!(decorationRegion & Title) && hasTitle)
                newClip -= region(widget, widgetRect, Title);
            if (!(decorationRegion & Help) && hasContextHelp)
                newClip -= region(widget, widgetRect, Help);
            if (!(decorationRegion & Minimize) && hasMinimize)
                newClip -= region(widget, widgetRect, Minimize);
            if (!(decorationRegion & Maximize) && hasMaximize)
                newClip -= region(widget, widgetRect, Maximize);
            if (!(decorationRegion & (Minimize | Maximize)) && (hasMaximize | hasMinimize))
                newClip -= region(widget, widgetRect, Normal);
            if (!(decorationRegion & Close))
                newClip -= region(widget, widgetRect, Close);
            painter->setClipRegion(newClip);
        }

        if (state == Pressed)
            opt.activeSubControls = opt.subControls;

        style->drawComplexControl(QStyle::CC_TitleBar, &opt, painter, 0);
        painter->restore();

        decorationRegion &= ~(Title | Menu | Help | Normalize | Minimize | Maximize | Close);
        handled |= true;
    }

    return handled;
}
QRegion QDecorationStyled::region(const QWidget *widget, const QRect &rect, int decorationRegion)
{
    QStyle *style = QApplication::style();

    // In the case of a borderless title bar, the title bar must be expanded one
    // borderWidth to the left, right and up.
    bool noTitleBorder = style->styleHint(QStyle::SH_TitleBar_NoBorder, 0, widget);
    int borderWidth = style->pixelMetric(QStyle::PM_MDIFrameWidth, 0, 0);
    int titleHeight = titleBarHeight(widget) + (noTitleBorder ? borderWidth : 0);
    int titleExtra = noTitleBorder ? borderWidth : 0;

    QRect inside = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra, titleHeight);

    Qt::WindowFlags flags = widget->windowFlags();
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    QStyleOptionTitleBar opt;
    opt.subControls = QStyle::SC_TitleBarLabel
                      | QStyle::SC_TitleBarSysMenu
                      | QStyle::SC_TitleBarNormalButton
                      | QStyle::SC_TitleBarMinButton
                      | QStyle::SC_TitleBarMaxButton
                      | QStyle::SC_TitleBarCloseButton;
    opt.titleBarFlags = widget->windowFlags();
    opt.direction = QApplication::layoutDirection();
    opt.text = windowTitleFor(widget);
    opt.icon = widget->windowIcon();
    opt.rect = inside;

    QRegion region;
    switch (decorationRegion) {
    case Title:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarLabel, 0);
        break;
    case Menu:
        if (hasSysMenu)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarSysMenu, 0);
        break;
    case Help:
        if (hasContextHelp)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarContextHelpButton,
                                           0);
        break;
    case Normalize:
        if (hasMaximize | hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarNormalButton,
                                           0);
        break;
    case Minimize:
        if (hasMinimize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMinButton,
                                           0);
        break;
    case Maximize:
        if (hasMaximize)
            region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                           QStyle::SC_TitleBarMaxButton,
                                           0);
        break;
    case Close:
        region = style->subControlRect(QStyle::CC_TitleBar, &opt,
                                       QStyle::SC_TitleBarCloseButton, 0);
        break;

    default:
        region = QDecorationDefault::region(widget, rect, decorationRegion);
    }

    opt.rect = QRect(rect.x() - titleExtra, rect.top() - titleHeight,
                         rect.width() + 2 * titleExtra,
                         rect.height() + titleHeight + titleExtra);

    QStyleHintReturnMask mask;
    style->styleHint(QStyle::SH_WindowFrame_Mask, &opt, 0, &mask);

    return (mask.region.isEmpty() ? region : (region & mask.region));
}
示例#5
0
/*!
  Paints the border and title decoration for the top-level \a widget
  using the \a painter provided and the decoration \a state. The value
  of \a decorationRegion is a combination of the bitmask values of
  enum DecorationRegion.

  Note that Qt for Embedded Linux expects this function to return true if any of
  the widget's decorations are repainted; otherwise it returns false.
 */
bool QDecorationDefault::paint(QPainter *painter,
                               const QWidget *widget,
                               int decorationRegion,
                               DecorationState state)
{
    if (decorationRegion == None)
        return false;

    const QRect titleRect = QDecoration::region(widget, Title).boundingRect();
    const QPalette pal = QApplication::palette();
    int titleHeight = titleRect.height();
    int titleWidth = titleRect.width();
    QRegion oldClipRegion = painter->clipRegion();


    Qt::WindowFlags flags = widget->windowFlags();
    bool hasBorder = !widget->isMaximized();
    bool hasTitle = flags & Qt::WindowTitleHint;
    bool hasSysMenu = flags & Qt::WindowSystemMenuHint;
    bool hasContextHelp = flags & Qt::WindowContextHelpButtonHint;
    bool hasMinimize = flags & Qt::WindowMinimizeButtonHint;
    bool hasMaximize = flags & Qt::WindowMaximizeButtonHint;

    bool paintAll = (decorationRegion == int(All));
    bool handled = false;

    bool porterDuff = painter->paintEngine()->hasFeature(QPaintEngine::PorterDuff);

    if ((paintAll || decorationRegion & Borders) && state == Normal && hasBorder) {
        if (hasTitle) { // reduce flicker
            QRect rect(widget->rect());
            QRect r(rect.left(), rect.top() - titleHeight,
                    rect.width(), titleHeight);
            painter->setClipRegion(oldClipRegion - r);
        }
        QRect br = QDecoration::region(widget).boundingRect();
        if (porterDuff)
            painter->setCompositionMode(QPainter::CompositionMode_Source);
        qDrawWinPanel(painter, br.x(), br.y(), br.width(),
                    br.height(), pal, false,
                    &pal.brush(QPalette::Window));
        if (porterDuff)
            painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
        handled |= true;
    }

    if ((paintAll || decorationRegion & Title && titleWidth > 0) && state == Normal && hasTitle) {
        painter->setClipRegion(oldClipRegion);
        QBrush titleBrush;
        QPen   titlePen;

        if (widget == qApp->activeWindow()) {
            titleBrush = pal.brush(QPalette::Highlight);
            titlePen   = pal.color(QPalette::HighlightedText);
        } else {
            titleBrush = pal.brush(QPalette::Window);
            titlePen   = pal.color(QPalette::Text);
        }

        if (porterDuff)
            painter->setCompositionMode(QPainter::CompositionMode_Source);
        qDrawShadePanel(painter,
                        titleRect.x(), titleRect.y(), titleRect.width(), titleRect.height(),
                        pal, true, 1, &titleBrush);
        if (porterDuff)
            painter->setCompositionMode(QPainter::CompositionMode_SourceOver);

        painter->setPen(titlePen);
        painter->drawText(titleRect.x() + 4, titleRect.y(),
                          titleRect.width() - 8, titleRect.height(),
                          Qt::AlignVCenter, windowTitleFor(widget));
        handled |= true;
    }

    if (state != Hover) {
        painter->setClipRegion(oldClipRegion);
        if ((paintAll || decorationRegion & Menu) && hasSysMenu) {
            paintButton(painter, widget, Menu, state, pal);
            handled |= true;
        }

        if ((paintAll || decorationRegion & Help) && hasContextHelp) {
            paintButton(painter, widget, Help, state, pal);
            handled |= true;
        }

        if ((paintAll || decorationRegion & Minimize) && hasMinimize) {
            paintButton(painter, widget, Minimize, state, pal);
            handled |= true;
        }

        if ((paintAll || decorationRegion & Maximize) && hasMaximize) {
            paintButton(painter, widget,
                        ((widget->windowState() & Qt::WindowMaximized)? Normalize : Maximize),
                        state, pal);
            handled |= true;
        }

        if (paintAll || decorationRegion & Close) {
            paintButton(painter, widget, Close, state, pal);
            handled |= true;
        }
    }
    return handled;
}