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()
|
QMacStylePrivate::QMacStylePrivate()
|
||||||
: mouseDown(false)
|
: mouseDown(false), backingStoreNSView(nil)
|
||||||
{
|
{
|
||||||
defaultButtonStart = CFAbsoluteTimeGetCurrent();
|
defaultButtonStart = CFAbsoluteTimeGetCurrent();
|
||||||
memset(&buttonState, 0, sizeof(ButtonState));
|
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 QMacStylePrivate::getDrawState(QStyle::State flags)
|
||||||
{
|
{
|
||||||
ThemeDrawState tds = kThemeStateActive;
|
ThemeDrawState tds = kThemeStateActive;
|
||||||
|
@ -1732,6 +1738,97 @@ ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
|
||||||
return tds;
|
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,
|
void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonDrawInfo *bdi,
|
||||||
QPainter *p, const QStyleOption *opt) const
|
QPainter *p, const QStyleOption *opt) const
|
||||||
{
|
{
|
||||||
|
@ -1742,6 +1839,9 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
|
||||||
finalyoff = 0;
|
finalyoff = 0;
|
||||||
|
|
||||||
const bool combo = opt->type == QStyleOption::SO_ComboBox;
|
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 button = opt->type == QStyleOption::SO_Button;
|
||||||
const bool pressed = bdi->state == kThemeStatePressed;
|
const bool pressed = bdi->state == kThemeStatePressed;
|
||||||
const bool usingYosemiteOrLater = QSysInfo::MacintoshVersion > QSysInfo::MV_10_9;
|
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) {
|
if (!combo && !button && bdi->value == kThemeButtonOff) {
|
||||||
pm = activePixmap;
|
pm = activePixmap;
|
||||||
} else if ((combo && !usingYosemiteOrLater) || button) {
|
} else if (!usingYosemiteOrLater && (combo || button)) {
|
||||||
QImage image = activePixmap.toImage();
|
QImage image = activePixmap.toImage();
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
|
@ -1816,7 +1916,17 @@ void QMacStylePrivate::drawColorlessButton(const HIRect &macRect, HIThemeButtonD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pm = QPixmap::fromImage(image);
|
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();
|
QImage image = activePixmap.toImage();
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y) {
|
for (int y = 0; y < height; ++y) {
|
||||||
|
@ -2944,6 +3054,9 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
|
||||||
Q_D(const QMacStyle);
|
Q_D(const QMacStyle);
|
||||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||||
QMacCGContext cg(p);
|
QMacCGContext cg(p);
|
||||||
|
QWindow *window = w && w->window() ? w->window()->windowHandle() :
|
||||||
|
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||||
|
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||||
switch (pe) {
|
switch (pe) {
|
||||||
case PE_IndicatorArrowUp:
|
case PE_IndicatorArrowUp:
|
||||||
case PE_IndicatorArrowDown:
|
case PE_IndicatorArrowDown:
|
||||||
|
@ -3358,6 +3471,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
|
||||||
Q_D(const QMacStyle);
|
Q_D(const QMacStyle);
|
||||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||||
QMacCGContext cg(p);
|
QMacCGContext cg(p);
|
||||||
|
QWindow *window = w && w->window() ? w->window()->windowHandle() :
|
||||||
|
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||||
|
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||||
switch (ce) {
|
switch (ce) {
|
||||||
case CE_HeaderSection:
|
case CE_HeaderSection:
|
||||||
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
|
if (const QStyleOptionHeader *header = qstyleoption_cast<const QStyleOptionHeader *>(opt)) {
|
||||||
|
@ -5075,6 +5191,9 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
|
||||||
Q_D(const QMacStyle);
|
Q_D(const QMacStyle);
|
||||||
ThemeDrawState tds = d->getDrawState(opt->state);
|
ThemeDrawState tds = d->getDrawState(opt->state);
|
||||||
QMacCGContext cg(p);
|
QMacCGContext cg(p);
|
||||||
|
QWindow *window = widget && widget->window() ? widget->window()->windowHandle() :
|
||||||
|
QStyleHelper::styleObjectWindow(opt->styleObject);
|
||||||
|
const_cast<QMacStylePrivate *>(d)->resolveCurrentNSView(window);
|
||||||
switch (cc) {
|
switch (cc) {
|
||||||
case CC_Slider:
|
case CC_Slider:
|
||||||
case CC_ScrollBar:
|
case CC_ScrollBar:
|
||||||
|
|
|
@ -145,6 +145,7 @@ class QMacStylePrivate : public QCommonStylePrivate
|
||||||
Q_DECLARE_PUBLIC(QMacStyle)
|
Q_DECLARE_PUBLIC(QMacStyle)
|
||||||
public:
|
public:
|
||||||
QMacStylePrivate();
|
QMacStylePrivate();
|
||||||
|
~QMacStylePrivate();
|
||||||
|
|
||||||
// Ideally these wouldn't exist, but since they already exist we need some accessors.
|
// Ideally these wouldn't exist, but since they already exist we need some accessors.
|
||||||
static const int PushButtonLeftOffset;
|
static const int PushButtonLeftOffset;
|
||||||
|
@ -194,6 +195,11 @@ public:
|
||||||
|
|
||||||
void setAutoDefaultButton(QObject *button) const;
|
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:
|
public:
|
||||||
mutable QPointer<QObject> pressedButton;
|
mutable QPointer<QObject> pressedButton;
|
||||||
mutable QPointer<QObject> defaultButton;
|
mutable QPointer<QObject> defaultButton;
|
||||||
|
@ -212,6 +218,8 @@ public:
|
||||||
void *nsscroller;
|
void *nsscroller;
|
||||||
#endif
|
#endif
|
||||||
void *indicatorBranchButtonCell;
|
void *indicatorBranchButtonCell;
|
||||||
|
NSView *backingStoreNSView;
|
||||||
|
QHash<ThemeButtonKind , NSView *> buttons;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include <qmath.h>
|
#include <qmath.h>
|
||||||
#include <qscrollbar.h>
|
#include <qscrollbar.h>
|
||||||
#include <qabstractscrollarea.h>
|
#include <qabstractscrollarea.h>
|
||||||
|
#include <qwindow.h>
|
||||||
|
|
||||||
#include "qstylehelper_p.h"
|
#include "qstylehelper_p.h"
|
||||||
#include <qstringbuilder.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 widget->parentWidget()->parentWidget()->palette().color(QPalette::Base);
|
||||||
return pal.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
|
QT_END_NAMESPACE
|
||||||
|
|
|
@ -68,6 +68,7 @@ class QPainter;
|
||||||
class QPixmap;
|
class QPixmap;
|
||||||
class QStyleOptionSlider;
|
class QStyleOptionSlider;
|
||||||
class QStyleOption;
|
class QStyleOption;
|
||||||
|
class QWindow;
|
||||||
|
|
||||||
namespace QStyleHelper
|
namespace QStyleHelper
|
||||||
{
|
{
|
||||||
|
@ -87,6 +88,7 @@ namespace QStyleHelper
|
||||||
bool hasAncestor(QObject *obj, QAccessible::Role role);
|
bool hasAncestor(QObject *obj, QAccessible::Role role);
|
||||||
#endif
|
#endif
|
||||||
QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
|
QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
|
||||||
|
QWindow *styleObjectWindow(QObject *so);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue