QMacStyle: smooth QMenu corners for real
It's been for years that QMenu's rounded corners in qmacstyle_mac were done via QWidget::setMask(QRegion). Unfortunately, QRegion mask does not work well with retina displays and also does not support translucency. That's why in this change we explicitly make QMenu's background transparent and then draw a rectangle with rounded corners in QMacStyle::drawPrimitive(PE_PanelMenu). This not only gives much better result than the mask-based approach, but also de-HIThemes QMenu. As a consequence, QComboBoxPrivateContainer doesn't get any mask from QMacStyle anymore. Therefore, when the mask is empty, we need to paint PE_PanelMenu before invoking QFrame's paint event handler. Made-with: Gabriel de Dietrich <gabriel.dedietrich@qt.io> Change-Id: Ia9236176113f23b86e45507fa6ddf77236084ce3 Reviewed-by: Oleg Yadrov <oleg.yadrov@qt.io> Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>bb10
parent
08e083e682
commit
5ff9d6a470
|
|
@ -144,7 +144,6 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
|
|||
}
|
||||
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette
|
||||
|| mac_widget_colors[i].paletteRole == QPlatformTheme::MenuBarPalette) {
|
||||
pal.setBrush(QPalette::Background, qt_mac_toQColor([NSColor windowBackgroundColor]));
|
||||
pal.setBrush(QPalette::Highlight, qt_mac_toQColor([NSColor selectedMenuItemColor]));
|
||||
qc = qt_mac_toQColor([NSColor labelColor]);
|
||||
pal.setBrush(QPalette::ButtonText, qc);
|
||||
|
|
|
|||
|
|
@ -663,14 +663,6 @@ HIMutableShapeRef qt_mac_toHIMutableShape(const QRegion ®ion)
|
|||
return shape;
|
||||
}
|
||||
|
||||
QRegion qt_mac_fromHIShapeRef(HIShapeRef shape)
|
||||
{
|
||||
QRegion returnRegion;
|
||||
//returnRegion.detach();
|
||||
HIShapeEnumerate(shape, kHIShapeParseFromTopLeft, qt_mac_shape2QRegionHelper, &returnRegion);
|
||||
return returnRegion;
|
||||
}
|
||||
|
||||
bool qt_macWindowIsTextured(const QWidget *window)
|
||||
{
|
||||
if (QWindow *w = window->windowHandle())
|
||||
|
|
@ -2291,24 +2283,7 @@ void QMacStyle::polish(QWidget* w)
|
|||
|| qobject_cast<QComboBoxPrivateContainer *>(w)
|
||||
#endif
|
||||
) {
|
||||
w->setWindowOpacity(0.985);
|
||||
if (!w->testAttribute(Qt::WA_SetPalette)) {
|
||||
QPixmap px(64, 64);
|
||||
px.fill(Qt::white);
|
||||
HIThemeMenuDrawInfo mtinfo;
|
||||
mtinfo.version = qt_mac_hitheme_version;
|
||||
mtinfo.menuType = kThemeMenuTypePopUp;
|
||||
// HIRect rect = CGRectMake(0, 0, px.width(), px.height());
|
||||
// ###
|
||||
//HIThemeDrawMenuBackground(&rect, &mtinfo, QMacCGContext(&px)),
|
||||
// kHIThemeOrientationNormal);
|
||||
QPalette pal = w->palette();
|
||||
QBrush background(px);
|
||||
pal.setBrush(QPalette::All, QPalette::Window, background);
|
||||
pal.setBrush(QPalette::All, QPalette::Button, background);
|
||||
w->setPalette(pal);
|
||||
w->setAttribute(Qt::WA_SetPalette, false);
|
||||
}
|
||||
w->setAttribute(Qt::WA_TranslucentBackground, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3023,7 +2998,7 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
|
|||
ret = Qt::AlignRight;
|
||||
break;
|
||||
case SH_ComboBox_PopupFrameStyle:
|
||||
ret = QFrame::NoFrame | QFrame::Plain;
|
||||
ret = QFrame::NoFrame;
|
||||
break;
|
||||
case SH_MessageBox_TextInteractionFlags:
|
||||
ret = Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard;
|
||||
|
|
@ -3057,27 +3032,6 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
|
|||
case SH_Menu_FadeOutOnHide:
|
||||
ret = true;
|
||||
break;
|
||||
case SH_Menu_Mask:
|
||||
if (opt) {
|
||||
if (QStyleHintReturnMask *mask = qstyleoption_cast<QStyleHintReturnMask*>(hret)) {
|
||||
ret = true;
|
||||
CGRect menuRect = CGRectMake(opt->rect.x(), opt->rect.y() + 4,
|
||||
opt->rect.width(), opt->rect.height() - 8);
|
||||
HIThemeMenuDrawInfo mdi;
|
||||
mdi.version = 0;
|
||||
#if QT_CONFIG(menu)
|
||||
if (w && qobject_cast<QMenu *>(w->parentWidget()))
|
||||
mdi.menuType = kThemeMenuTypeHierarchical;
|
||||
else
|
||||
#endif
|
||||
mdi.menuType = kThemeMenuTypePopUp;
|
||||
QCFType<HIShapeRef> shape;
|
||||
HIThemeGetMenuBackgroundShape(&menuRect, &mdi, &shape);
|
||||
|
||||
mask->region = qt_mac_fromHIShapeRef(shape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SH_ItemView_PaintAlternatingRowColorsForEmptyArea:
|
||||
ret = true;
|
||||
break;
|
||||
|
|
@ -3587,6 +3541,40 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
|||
|
||||
break;
|
||||
}
|
||||
case PE_PanelMenu: {
|
||||
p->save();
|
||||
p->fillRect(opt->rect, Qt::transparent);
|
||||
p->setPen(Qt::transparent);
|
||||
p->setBrush(opt->palette.window());
|
||||
p->setRenderHint(QPainter::Antialiasing, true);
|
||||
QPainterPath path;
|
||||
static const qreal CornerPointOffset = 5.5;
|
||||
static const qreal CornerControlOffset = 2.1;
|
||||
QRectF r = opt->rect;
|
||||
// Top-left corner
|
||||
path.moveTo(r.left(), r.top() + CornerPointOffset);
|
||||
path.cubicTo(r.left(), r.top() + CornerControlOffset,
|
||||
r.left() + CornerControlOffset, r.top(),
|
||||
r.left() + CornerPointOffset, r.top());
|
||||
// Top-right corner
|
||||
path.lineTo(r.right() - CornerPointOffset, r.top());
|
||||
path.cubicTo(r.right() - CornerControlOffset, r.top(),
|
||||
r.right(), r.top() + CornerControlOffset,
|
||||
r.right(), r.top() + CornerPointOffset);
|
||||
// Bottom-right corner
|
||||
path.lineTo(r.right(), r.bottom() - CornerPointOffset);
|
||||
path.cubicTo(r.right(), r.bottom() - CornerControlOffset,
|
||||
r.right() - CornerControlOffset, r.bottom(),
|
||||
r.right() - CornerPointOffset, r.bottom());
|
||||
// Bottom-right corner
|
||||
path.lineTo(r.left() + CornerPointOffset, r.bottom());
|
||||
path.cubicTo(r.left() + CornerControlOffset, r.bottom(),
|
||||
r.left(), r.bottom() - CornerControlOffset,
|
||||
r.left(), r.bottom() - CornerPointOffset);
|
||||
path.lineTo(r.left(), r.top() + CornerPointOffset);
|
||||
p->drawPath(path);
|
||||
p->restore();
|
||||
} break;
|
||||
|
||||
default:
|
||||
QCommonStyle::drawPrimitive(pe, opt, p, w);
|
||||
|
|
@ -4269,16 +4257,18 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
|||
const int vMargin = proxy()->pixelMetric(QStyle::PM_FocusFrameVMargin, opt, w);
|
||||
d->drawFocusRing(p, opt->rect, hMargin, vMargin);
|
||||
break; }
|
||||
case CE_MenuEmptyArea:
|
||||
// Skip: PE_PanelMenu fills in everything
|
||||
break;
|
||||
case CE_MenuItem:
|
||||
case CE_MenuHMargin:
|
||||
case CE_MenuVMargin:
|
||||
case CE_MenuEmptyArea:
|
||||
case CE_MenuTearoff:
|
||||
case CE_MenuScroller:
|
||||
if (const QStyleOptionMenuItem *mi = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
|
||||
const bool active = mi->state & State_Selected;
|
||||
const QBrush bg = active ? mi->palette.highlight() : mi->palette.background();
|
||||
p->fillRect(mi->rect, bg);
|
||||
if (active)
|
||||
p->fillRect(mi->rect, mi->palette.highlight());
|
||||
|
||||
const QStyleHelper::WidgetSizePolicy widgetSize = d->aquaSizeConstrain(opt, w);
|
||||
|
||||
|
|
|
|||
|
|
@ -428,6 +428,20 @@ void QComboBoxPrivateContainer::resizeEvent(QResizeEvent *e)
|
|||
QFrame::resizeEvent(e);
|
||||
}
|
||||
|
||||
void QComboBoxPrivateContainer::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QStyleOptionComboBox cbOpt = comboStyleOption();
|
||||
if (combo->style()->styleHint(QStyle::SH_ComboBox_Popup, &cbOpt, combo)
|
||||
&& mask().isEmpty()) {
|
||||
QStyleOption opt;
|
||||
opt.initFrom(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_PanelMenu, &opt, &p, this);
|
||||
}
|
||||
|
||||
QFrame::paintEvent(e);
|
||||
}
|
||||
|
||||
void QComboBoxPrivateContainer::leaveEvent(QEvent *)
|
||||
{
|
||||
// On Mac using the Mac style we want to clear the selection
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ protected:
|
|||
void timerEvent(QTimerEvent *timerEvent) override;
|
||||
void leaveEvent(QEvent *e) override;
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
void paintEvent(QPaintEvent *e) override;
|
||||
QStyleOptionComboBox comboStyleOption() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
|
|
|||
Loading…
Reference in New Issue