Exemple #1
0
void QGraphicsWidgetPrivate::initStyleOptionTitleBar(QStyleOptionTitleBar *option)
{
    Q_Q(QGraphicsWidget);
    q->initStyleOption(option);
    option->rect.setHeight(titleBarHeight(*option));
    option->titleBarFlags = windowFlags;
    option->subControls = QStyle::SC_TitleBarCloseButton | QStyle::SC_TitleBarLabel | QStyle::SC_TitleBarSysMenu;
    option->activeSubControls = hoveredSubControl;
    bool isActive = q->isActiveWindow();
    if (isActive) {
        option->state |= QStyle::State_Active;
        option->titleBarState = Qt::WindowActive;
        option->titleBarState |= QStyle::State_Active;
    } else {
        option->state &= ~QStyle::State_Active;
        option->titleBarState = Qt::WindowNoState;
    }
    QFont windowTitleFont = QApplication::font("QWorkspaceTitleBar");
    QRect textRect = q->style()->subControlRect(QStyle::CC_TitleBar, option, QStyle::SC_TitleBarLabel, 0);
    option->text = QFontMetrics(windowTitleFont).elidedText(windowTitle, Qt::ElideRight, textRect.width());
}
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));
}
Exemple #4
0
/*!
  Returns the region specified by \a decorationRegion for the
  top-level \a widget. \a rect specifies the rectangle the decoration
  wraps. The value of \a decorationRegion is a combination of the
  bitmask values of enum DecorationRegion.
 */
QRegion QDecorationDefault::region(const QWidget *widget,
                                   const QRect &rect,
                                   int decorationRegion)
{
    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;
    int state = widget->windowState();
    bool isMinimized = state & Qt::WindowMinimized;
    bool isMaximized = state & Qt::WindowMaximized;

    int titleHeight = hasTitle ? titleBarHeight(widget) : 0;
    int bw = hasBorder ? BORDER_WIDTH : 0;
    int bbw = hasBorder ? BOTTOM_BORDER_WIDTH : 0;

    QRegion region;
    switch (decorationRegion) {
        case All: {
                QRect r(rect.left() - bw,
                        rect.top() - titleHeight - bw,
                        rect.width() + 2 * bw,
                        rect.height() + titleHeight + bw + bbw);
                region = r;
                region -= rect;
            }
            break;

        case Title: {
                QRect r(rect.left()
                        + (hasSysMenu ? menu_width : 0),
                        rect.top() - titleHeight,
                        rect.width()
                        - (hasSysMenu ? menu_width : 0)
                        - close_width
                        - (hasMaximize ? maximize_width : 0)
                        - (hasMinimize ? minimize_width : 0)
                        - (hasContextHelp ? help_width : 0),

                        titleHeight);
                if (r.width() > 0)
                    region = r;
            }
            break;

        case Top: {
                QRect r(rect.left() + CORNER_GRAB,
                        rect.top() - titleHeight - bw,
                        rect.width() - 2 * CORNER_GRAB,
                        bw);
                region = r;
            }
            break;

        case Left: {
                QRect r(rect.left() - bw,
                        rect.top() - titleHeight + CORNER_GRAB,
                        bw,
                        rect.height() + titleHeight - 2 * CORNER_GRAB);
                region = r;
            }
            break;

        case Right: {
                QRect r(rect.right() + 1,
                        rect.top() - titleHeight + CORNER_GRAB,
                        bw,
                        rect.height() + titleHeight - 2 * CORNER_GRAB);
                region = r;
            }
            break;

        case Bottom: {
                QRect r(rect.left() + CORNER_GRAB,
                        rect.bottom() + 1,
                        rect.width() - 2 * CORNER_GRAB,
                        bw);
                region = r;
            }
            break;

        case TopLeft: {
                QRect r1(rect.left() - bw,
                        rect.top() - bw - titleHeight,
                        CORNER_GRAB + bw,
                        bw);

                QRect r2(rect.left() - bw,
                        rect.top() - bw - titleHeight,
                        bw,
                        CORNER_GRAB + bw);

                region = QRegion(r1) + r2;
            }
            break;

        case TopRight: {
                QRect r1(rect.right() - CORNER_GRAB,
                        rect.top() - bw - titleHeight,
                        CORNER_GRAB + bw,
                        bw);

                QRect r2(rect.right() + 1,
                        rect.top() - bw - titleHeight,
                        bw,
                        CORNER_GRAB + bw);

                region = QRegion(r1) + r2;
            }
            break;

        case BottomLeft: {
                QRect r1(rect.left() - bw,
                        rect.bottom() + 1,
                        CORNER_GRAB + bw,
                        bw);

                QRect r2(rect.left() - bw,
                        rect.bottom() - CORNER_GRAB,
                        bw,
                        CORNER_GRAB + bw);
                region = QRegion(r1) + r2;
            }
            break;

        case BottomRight: {
                QRect r1(rect.right() - CORNER_GRAB,
                        rect.bottom() + 1,
                        CORNER_GRAB + bw,
                        bw);

                QRect r2(rect.right() + 1,
                        rect.bottom() - CORNER_GRAB,
                        bw,
                        CORNER_GRAB + bw);
                region = QRegion(r1) + r2;
            }
            break;

        case Menu: {
                if (hasSysMenu) {
                    region = QRect(rect.left(), rect.top() - titleHeight,
                                   menu_width, titleHeight);
                }
            }
            break;

        case Help: {
                if (hasContextHelp) {
                    QRect r(rect.right()
                            - close_width
                            - (hasMaximize ? maximize_width : 0)
                            - (hasMinimize ? minimize_width : 0)
                            - help_width + 1, rect.top() - titleHeight,
                            help_width, titleHeight);
                    if (r.left() > rect.left() + titleHeight)
                        region = r;
                }
            }
            break;


        case Minimize: {
                if (hasMinimize && !isMinimized) {
                    QRect r(rect.right() - close_width
                            - (hasMaximize ? maximize_width : 0)
                            - minimize_width + 1, rect.top() - titleHeight,
                            minimize_width, titleHeight);
                    if (r.left() > rect.left() + titleHeight)
                        region = r;
                }
            }
            break;

        case Maximize: {
                if (hasMaximize && !isMaximized) {
                    QRect r(rect.right() - close_width - maximize_width + 1,
                            rect.top() - titleHeight, maximize_width, titleHeight);
                    if (r.left() > rect.left() + titleHeight)
                        region = r;
                }
            }
            break;

        case Normalize: {
                if (hasMinimize && isMinimized) {
                    QRect r(rect.right() - close_width
                            - (hasMaximize ? maximize_width : 0)
                            - minimize_width + 1, rect.top() - titleHeight,
                            minimize_width, titleHeight);
                    if (r.left() > rect.left() + titleHeight)
                        region = r;
                } else if (hasMaximize && isMaximized) {
                    QRect r(rect.right() - close_width - maximize_width + 1,
                            rect.top() - titleHeight, maximize_width, titleHeight);
                    if (r.left() > rect.left() + titleHeight)
                        region = r;
                }
            }
            break;

        case Close: {
                QRect r(rect.right() - close_width + 1, rect.top() - titleHeight,
                        close_width, titleHeight);
                if (r.left() > rect.left() + titleHeight)
                    region = r;
            }
            break;

    default: {
        int i = 1;
        while (i) {
            if (i & decorationRegion)
                region += this->region(widget, rect, i);
            i <<= 1;
        }
    }
            break;
    }

    return region;
}
void QGraphicsWidgetPrivate::windowFrameHoverMoveEvent(QGraphicsSceneHoverEvent *event)
{
    Q_Q(QGraphicsWidget);
    if (!hasDecoration())
        return;

    ensureWindowData();

    if (q->rect().contains(event->pos())) {
        if (windowData->buttonMouseOver || windowData->hoveredSubControl != QStyle::SC_None)
            windowFrameHoverLeaveEvent(event);
        return;
    }

    bool wasMouseOver = windowData->buttonMouseOver;
    QRect oldButtonRect = windowData->buttonRect;
    windowData->buttonRect = QRect();
    windowData->buttonMouseOver = false;
    QPointF pos = event->pos();
    QStyleOptionTitleBar bar;
    // make sure that the coordinates (rect and pos) we send to the style are positive.
    if (windowFrameMargins) {
        pos.rx() += windowFrameMargins[Left];
        pos.ry() += windowFrameMargins[Top];
    }
    initStyleOptionTitleBar(&bar);
    bar.rect = q->windowFrameRect().toRect();
    bar.rect.moveTo(0,0);
    bar.rect.setHeight(int(titleBarHeight(bar)));

    Qt::CursorShape cursorShape = Qt::ArrowCursor;
    bool needsSetCursorCall = true;
    switch (q->windowFrameSectionAt(event->pos())) {
        case Qt::TopLeftSection:
        case Qt::BottomRightSection:
            cursorShape = Qt::SizeFDiagCursor;
            break;
        case Qt::TopRightSection:
        case Qt::BottomLeftSection:
            cursorShape = Qt::SizeBDiagCursor;
            break;
        case Qt::LeftSection:
        case Qt::RightSection:
            cursorShape = Qt::SizeHorCursor;
            break;
        case Qt::TopSection:
        case Qt::BottomSection:
            cursorShape = Qt::SizeVerCursor;
            break;
        case Qt::TitleBarArea:
            windowData->buttonRect = q->style()->subControlRect(
                QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarCloseButton, 0);
#ifdef Q_WS_MAC
            // On mac we should hover if we are in the 'area' of the buttons
            windowData->buttonRect |= q->style()->subControlRect(
                QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMinButton, 0);
            windowData->buttonRect |= q->style()->subControlRect(
                QStyle::CC_TitleBar, &bar, QStyle::SC_TitleBarMaxButton, 0);
#endif
            if (windowData->buttonRect.contains(pos.toPoint()))
                windowData->buttonMouseOver = true;
            event->ignore();
            break;
        default:
            needsSetCursorCall = false;
            event->ignore();
        }
#ifndef QT_NO_CURSOR
    if (needsSetCursorCall)
        q->setCursor(cursorShape);
#endif
    // update buttons if we hover over them
    windowData->hoveredSubControl = q->style()->hitTestComplexControl(QStyle::CC_TitleBar, &bar, pos.toPoint(), 0);
    if (windowData->hoveredSubControl != QStyle::SC_TitleBarCloseButton)
        windowData->hoveredSubControl = QStyle::SC_TitleBarLabel;

    if (windowData->buttonMouseOver != wasMouseOver) {
        if (!oldButtonRect.isNull())
            q->update(QRectF(oldButtonRect).translated(q->windowFrameRect().topLeft()));
        if (!windowData->buttonRect.isNull())
            q->update(QRectF(windowData->buttonRect).translated(q->windowFrameRect().topLeft()));
    }
}