mirror of https://github.com/qt/qtbase.git
QMacStyle: Use NSView rendering for some inactive widgets on 10.10
Right now, we use them for inactive non-editable combo box, check box, and radio button only on Yosemite. We keep as much as possible the previous behavior on older versions. In addition, we add a way for QQuickStyleItem to specify the window the item is on. This is currently without effect, since we don't seem to take the inactive window state into account. Task-number: QTBUG-40833 Change-Id: I2fb2a99e6adf1972f881195b79b07ce85a960273 Reviewed-by: Morten Johan Sørvig <morten.sorvig@digia.com>
This commit is contained in:
parent
c1b46b98ed
commit
982b9b7ec2
|
@ -1702,7 +1702,7 @@ void QMacStylePrivate::setAutoDefaultButton(QObject *button) const
|
|||
}
|
||||
|
||||
QMacStylePrivate::QMacStylePrivate()
|
||||
: mouseDown(false)
|
||||
: mouseDown(false), backingStoreNSView(nil)
|
||||
{
|
||||
defaultButtonStart = CFAbsoluteTimeGetCurrent();
|
||||
memset(&buttonState, 0, sizeof(ButtonState));
|
||||
|
@ -1715,6 +1715,12 @@ QMacStylePrivate::QMacStylePrivate()
|
|||
|
||||
}
|
||||
|
||||
QMacStylePrivate::~QMacStylePrivate()
|
||||
{
|
||||
Q_FOREACH (NSView *b, buttons)
|
||||
[b release];
|
||||
}
|
||||
|
||||
ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
|
||||
{
|
||||
ThemeDrawState tds = kThemeStateActive;
|
||||
|
@ -1732,6 +1738,97 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
|
|||
return tds;
|
||||
}
|
||||
|
||||
NSView *QMacStylePrivate::buttonOfKind(ThemeButtonKind kind) const
|
||||
{
|
||||
NSView *bv = buttons[kind];
|
||||
if (!bv) {
|
||||
if (kind == kThemePopupButton)
|
||||
bv = [[NSPopUpButton alloc] init];
|
||||
else if (kind == kThemeComboBox)
|
||||
bv = [[NSComboBox alloc] init];
|
||||
else
|
||||
bv = [[NSButton alloc] init];
|
||||
|
||||
switch (kind) {
|
||||
case kThemeArrowButton: {
|
||||
NSButton *bc = (NSButton *)bv;
|
||||
bc.buttonType = NSOnOffButton;
|
||||
bc.bezelStyle = NSDisclosureBezelStyle;
|
||||
break;
|
||||
}
|
||||
case kThemeCheckBox:
|
||||
case kThemeCheckBoxSmall:
|
||||
case kThemeCheckBoxMini: {
|
||||
NSButton *bc = (NSButton *)bv;
|
||||
bc.buttonType = NSSwitchButton;
|
||||
break;
|
||||
}
|
||||
case kThemeRadioButton:
|
||||
case kThemeRadioButtonSmall:
|
||||
case kThemeRadioButtonMini: {
|
||||
NSButton *bc = (NSButton *)bv;
|
||||
bc.buttonType = NSRadioButton;
|
||||
break;
|
||||
}
|
||||
case kThemePushButton:
|
||||
case kThemePushButtonSmall:
|
||||
case kThemePushButtonMini: {
|
||||
NSButton *bc = (NSButton *)bv;
|
||||
bc.buttonType = NSMomentaryPushButton;
|
||||
bc.bezelStyle = NSRoundedBezelStyle;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// if (kind == kThemePushButtonSmall
|
||||
// || kind == kThemePopupButtonSmall
|
||||
// || kind == kThemeCheckBoxSmall
|
||||
// || kind == kThemeRadioButtonSmall)
|
||||
// bc.controlSize = NSSmallControlSize;
|
||||
// else if (kind == kThemePushButtonMini
|
||||
// || kind == kThemePopupButtonMini
|
||||
// || kind == kThemeCheckBoxMini
|
||||
// || kind == kThemeRadioButtonMini)
|
||||
// bc.controlSize = NSMiniControlSize;
|
||||
|
||||
if ([bv isKindOfClass:[NSButton class]]) {
|
||||
NSButton *bc = (NSButton *)bv;
|
||||
bc.title = nil;
|
||||
}
|
||||
|
||||
const_cast<QMacStylePrivate *>(this)->buttons.insert(kind, bv);
|
||||
}
|
||||
|
||||
return bv;
|
||||
}
|
||||
|
||||
void QMacStylePrivate::drawNSViewInRect(NSView *view, const QRect &qtRect, QPainter *p) const
|
||||
{
|
||||
QMacCGContext ctx(p);
|
||||
CGContextSaveGState(ctx);
|
||||
|
||||
[NSGraphicsContext saveGraphicsState];
|
||||
[NSGraphicsContext setCurrentContext:[NSGraphicsContext
|
||||
graphicsContextWithGraphicsPort:ctx flipped:YES]];
|
||||
|
||||
CGRect rect = CGRectMake(qtRect.x() + 1, qtRect.y(), qtRect.width(), qtRect.height());
|
||||
|
||||
[backingStoreNSView addSubview:view];
|
||||
view.frame = rect;
|
||||
[view drawRect:rect];
|
||||
[view removeFromSuperviewWithoutNeedingDisplay];
|
||||
|
||||
[NSGraphicsContext restoreGraphicsState];
|
||||
CGContextRestoreGState(ctx);
|
||||
}
|
||||
|
||||
void QMacStylePrivate::resolveCurrentNSView(QWindow *window)
|
||||
{
|
||||
backingStoreNSView = window ? (NSView *)window->winId() : nil;
|
||||
}
|
||||
|
||||
void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
|
||||
QPainter *p, const QStyleOption *opt) const
|
||||
{
|
||||
|
@ -1742,6 +1839,9 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
|
|||
finalyoff = 0;
|
||||
|
||||
const bool combo = opt->type == QStyleOption::SO_ComboBox;
|
||||
const bool editableCombo = bdi->kind == kThemeComboBox
|
||||
|| bdi->kind == kThemeComboBoxSmall
|
||||
|| bdi->kind == kThemeComboBoxMini;
|
||||
const bool button = opt->type == QStyleOption::SO_Button;
|
||||
const bool pressed = bdi->state == kThemeStatePressed;
|
||||
const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
|
||||
|
@ -1789,7 +1889,7 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
|
|||
|
||||
if (!combo && !button && bdi->value == kThemeButtonOff) {
|
||||
pm = activePixmap;
|
||||
} else if ((combo && !usingYosemiteOrLater) || button) {
|
||||
} else if (!usingYosemiteOrLater && (combo || button)) {
|
||||
QImage image = activePixmap.toImage();
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
|
@ -1816,7 +1916,17 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
|
|||
}
|
||||
}
|
||||
pm = QPixmap::fromImage(image);
|
||||
} else if (combo && usingYosemiteOrLater) {
|
||||
} else if ((usingYosemiteOrLater && combo && !editableCombo) || button) {
|
||||
NSButton *bc = (NSButton *)buttonOfKind(bdi->kind);
|
||||
[bc highlight:pressed];
|
||||
bc.enabled = bdi->state != kThemeStateUnavailable && bdi->state != kThemeStateUnavailableInactive;
|
||||
bc.state = bdi->value == kThemeButtonOn ? NSOnState :
|
||||
bdi->value == kThemeButtonMixed ? NSMixedState : NSOffState;
|
||||
p->translate(0, 1);
|
||||
drawNSViewInRect(bc, opt->rect, p);
|
||||
p->translate(0, -1);
|
||||
return;
|
||||
} else if (usingYosemiteOrLater && editableCombo) {
|
||||
QImage image = activePixmap.toImage();
|
||||
|
||||
for (int y = 0; y < height; ++y) {
|
||||
|
@ -2944,6 +3054,9 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
|||
Q_D(const QMacStyle);
|
||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||
QMacCGContext cg(p);
|
||||
QWindow *window = w && w->window() ? w->window()->windowHandle() :
|
||||
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||
switch (pe) {
|
||||
case PE_IndicatorArrowUp:
|
||||
case PE_IndicatorArrowDown:
|
||||
|
@ -3358,6 +3471,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
|||
Q_D(const QMacStyle);
|
||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||
QMacCGContext cg(p);
|
||||
QWindow *window = w && w->window() ? w->window()->windowHandle() :
|
||||
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||
switch (ce) {
|
||||
case CE_HeaderSection:
|
||||
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
|
||||
|
@ -5075,6 +5191,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
|||
Q_D(const QMacStyle);
|
||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||
QMacCGContext cg(p);
|
||||
QWindow *window = widget && widget->window() ? widget->window()->windowHandle() :
|
||||
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||
switch (cc) {
|
||||
case CC_Slider:
|
||||
case CC_ScrollBar:
|
||||
|
|
|
@ -145,6 +145,7 @@ class QMacStylePrivate : public QCommonStylePrivate
|
|||
Q_DECLARE_PUBLIC(QMacStyle)
|
||||
public:
|
||||
QMacStylePrivate();
|
||||
~QMacStylePrivate();
|
||||
|
||||
// Ideally these wouldn't exist, but since they already exist we need some accessors.
|
||||
static const int PushButtonLeftOffset;
|
||||
|
@ -194,6 +195,11 @@ public:
|
|||
|
||||
void setAutoDefaultButton(QObject *button) const;
|
||||
|
||||
NSView *buttonOfKind(ThemeButtonKind kind) const;
|
||||
|
||||
void drawNSViewInRect(NSView *view, const QRect &rect, QPainter *p) const;
|
||||
void resolveCurrentNSView(QWindow *window);
|
||||
|
||||
public:
|
||||
mutable QPointer<QObject> pressedButton;
|
||||
mutable QPointer<QObject> defaultButton;
|
||||
|
@ -212,6 +218,8 @@ public:
|
|||
void *nsscroller;
|
||||
#endif
|
||||
void *indicatorBranchButtonCell;
|
||||
NSView *backingStoreNSView;
|
||||
QHash<ThemeButtonKind , NSView *> buttons;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <qmath.h>
|
||||
#include <qscrollbar.h>
|
||||
#include <qabstractscrollarea.h>
|
||||
#include <qwindow.h>
|
||||
|
||||
#include "qstylehelper_p.h"
|
||||
#include <qstringbuilder.h>
|
||||
|
@ -397,5 +398,14 @@ QColor backgroundColor(const QPalette &pal, const QWidget* widget)
|
|||
return widget->parentWidget()->parentWidget()->palette().color(QPalette::Base);
|
||||
return pal.color(QPalette::Base);
|
||||
}
|
||||
|
||||
QWindow *styleObjectWindow(QObject *so)
|
||||
{
|
||||
if (so)
|
||||
return so->property("_q_styleObjectWindow").value<QWindow *>();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
@ -68,6 +68,7 @@ class QPainter;
|
|||
class QPixmap;
|
||||
class QStyleOptionSlider;
|
||||
class QStyleOption;
|
||||
class QWindow;
|
||||
|
||||
namespace QStyleHelper
|
||||
{
|
||||
|
@ -87,6 +88,7 @@ namespace QStyleHelper
|
|||
bool hasAncestor(QObject *obj, QAccessible::Role role);
|
||||
#endif
|
||||
QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
|
||||
QWindow *styleObjectWindow(QObject *so);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue