summaryrefslogtreecommitdiffstats
path: root/src/plugins/styles
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-05-15 13:29:07 -0700
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2017-05-15 22:40:18 +0000
commit6f3b59bfe4d22f8c717f1727816d3f8e775996be (patch)
treefb767cf4cdd2dd56da99ce4867d46ab6c1c446e9 /src/plugins/styles
parentee1868df2b6b60d59dff1a14fa2c16a9e759ef19 (diff)
QMacStyle: Use NSStepperCell for QSpinBox buttons
Includes painting and subcontrol rectangles. Change-Id: I9a4c704bdea4f20f8dca94de24063f3e14dbaf91 Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Diffstat (limited to 'src/plugins/styles')
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm130
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac_p_p.h6
2 files changed, 71 insertions, 65 deletions
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index 43806381cc..003d050448 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -1785,8 +1785,10 @@ QMacStylePrivate::QMacStylePrivate()
QMacStylePrivate::~QMacStylePrivate()
{
QMacAutoReleasePool pool;
- Q_FOREACH (NSView *b, cocoaControls)
+ for (NSView *b : cocoaControls)
[b release];
+ for (NSCell *cell : cocoaCells)
+ [cell release];
}
ThemeDrawState QMacStylePrivate::getDrawState(QStyle::State flags)
@@ -1944,6 +1946,35 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const
return bv;
}
+NSCell *QMacStylePrivate::cocoaCell(QCocoaWidget widget) const
+{
+ NSCell *cell = cocoaCells[widget];
+ if (!cell) {
+ switch (widget.first) {
+ case QCocoaStepper:
+ cell = [[NSStepperCell alloc] init];
+ break;
+ default:
+ break;
+ }
+
+ switch (widget.second) {
+ case QStyleHelper::SizeSmall:
+ cell.controlSize = NSSmallControlSize;
+ break;
+ case QStyleHelper::SizeMini:
+ cell.controlSize = NSMiniControlSize;
+ break;
+ default:
+ break;
+ }
+
+ const_cast<QMacStylePrivate *>(this)->cocoaCells.insert(widget, cell);
+ }
+
+ return cell;
+}
+
void QMacStylePrivate::drawNSViewInRect(QCocoaWidget widget, NSView *view, const QRect &qtRect, QPainter *p, bool isQWidget, QCocoaDrawRectBlock drawRectBlock) const
{
QPoint offset;
@@ -5584,7 +5615,6 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
#ifndef QT_NO_SPINBOX
case CC_SpinBox:
if (const QStyleOptionSpinBox *sb = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleOptionSpinBox newSB = *sb;
if (sb->frame && (sb->subControls & SC_SpinBoxFrame)) {
SInt32 frame_size;
frame_size = qt_mac_aqua_get_metric(EditTextFrameOutset);
@@ -5601,53 +5631,32 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
HIThemeDrawFrame(&cgRect, &fdi, cg, kHIThemeOrientationNormal);
}
if (sb->subControls & (SC_SpinBoxUp | SC_SpinBoxDown)) {
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- QStyleHelper::WidgetSizePolicy aquaSize = d->aquaSizeConstrain(opt, widget);
- switch (aquaSize) {
- case QStyleHelper::SizeDefault:
- case QStyleHelper::SizeLarge:
- bdi.kind = kThemeIncDecButton;
- break;
- case QStyleHelper::SizeMini:
- bdi.kind = kThemeIncDecButtonMini;
- break;
- case QStyleHelper::SizeSmall:
- bdi.kind = kThemeIncDecButtonSmall;
- break;
- }
- if (!(sb->stepEnabled & (QAbstractSpinBox::StepUpEnabled
- | QAbstractSpinBox::StepDownEnabled)))
- tds = kThemeStateUnavailable;
- if (sb->activeSubControls == SC_SpinBoxDown
- && (sb->state & State_Sunken))
- tds = kThemeStatePressedDown;
- else if (sb->activeSubControls == SC_SpinBoxUp
- && (sb->state & State_Sunken))
- tds = kThemeStatePressedUp;
- if (tds == kThemeStateInactive)
- bdi.state = kThemeStateActive;
- else
- bdi.state = tds;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
-
- QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget);
-
- updown |= proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
- CGRect newRect = updown.toCGRect();
- CGRect outRect;
- HIThemeGetButtonBackgroundBounds(&newRect, &bdi, &outRect);
-
- const auto offMargins = QMargins(int(newRect.origin.x - outRect.origin.x),
- int(newRect.origin.y - outRect.origin.y),
- int(outRect.size.width - newRect.size.width),
- int(outRect.size.height - newRect.size.height));
- newRect = updown.marginsRemoved(offMargins).toCGRect();
- if (tds == kThemeStateInactive)
- d->drawColorlessButton(newRect, &bdi, p, sb);
- else
- HIThemeDrawButton(&newRect, &bdi, cg, kHIThemeOrientationNormal, 0);
+ const QRect updown = proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxUp, widget)
+ | proxy()->subControlRect(CC_SpinBox, sb, SC_SpinBoxDown, widget);
+
+ d->setupNSGraphicsContext(cg, NO);
+
+ const auto aquaSize = d->effectiveAquaSizeConstrain(opt, widget);
+ NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize)));
+ cell.enabled = (sb->state & State_Enabled);
+
+ const CGRect newRect = [cell drawingRectForBounds:updown.toCGRect()];
+
+ const bool upPressed = sb->activeSubControls == SC_SpinBoxUp && (sb->state & State_Sunken);
+ const bool downPressed = sb->activeSubControls == SC_SpinBoxDown && (sb->state & State_Sunken);
+ const CGFloat x = CGRectGetMidX(newRect);
+ const CGFloat y = upPressed ? -3 : 3; // FIXME Weird coordinate shift going on
+ // Pretend we're pressing the mouse on the right button. Unfortunately, NSStepperCell has no
+ // API to highlight a specific button. The highlighted property works only on the down button.
+ if (upPressed || downPressed)
+ [cell startTrackingAt:CGPointMake(x, y) inView:d->backingStoreNSView];
+
+ [cell drawWithFrame:newRect inView:d->backingStoreNSView];
+
+ if (upPressed || downPressed)
+ [cell stopTracking:CGPointMake(x, y) at:CGPointMake(x, y) inView:d->backingStoreNSView mouseIsUp:NO];
+
+ d->restoreNSGraphicsContext(cg);
}
}
break;
@@ -6334,12 +6343,11 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
#ifndef QT_NO_SPINBOX
case CC_SpinBox:
if (const QStyleOptionSpinBox *spin = qstyleoption_cast<const QStyleOptionSpinBox *>(opt)) {
- QStyleHelper::WidgetSizePolicy aquaSize = d->aquaSizeConstrain(spin, widget);
+ QStyleHelper::WidgetSizePolicy aquaSize = d->effectiveAquaSizeConstrain(spin, widget);
int spinner_w;
int spinBoxSep;
int fw = proxy()->pixelMetric(PM_SpinBoxFrameWidth, spin, widget);
switch (aquaSize) {
- case QStyleHelper::SizeDefault:
case QStyleHelper::SizeLarge:
spinner_w = 14;
spinBoxSep = 2;
@@ -6352,6 +6360,8 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
spinner_w = 10;
spinBoxSep = 1;
break;
+ default:
+ Q_UNREACHABLE();
}
switch (sc) {
@@ -6363,33 +6373,25 @@ QRect QMacStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex *op
const int y = fw;
const int x = spin->rect.width() - spinner_w;
ret.setRect(x + spin->rect.x(), y + spin->rect.y(), spinner_w, spin->rect.height() - y * 2);
- HIThemeButtonDrawInfo bdi;
- bdi.version = qt_mac_hitheme_version;
- bdi.kind = kThemeIncDecButton;
int hackTranslateX;
switch (aquaSize) {
- case QStyleHelper::SizeDefault:
case QStyleHelper::SizeLarge:
- bdi.kind = kThemeIncDecButton;
hackTranslateX = 0;
break;
case QStyleHelper::SizeSmall:
- bdi.kind = kThemeIncDecButtonSmall;
hackTranslateX = -2;
break;
case QStyleHelper::SizeMini:
- bdi.kind = kThemeIncDecButtonMini;
hackTranslateX = -1;
break;
+ default:
+ Q_UNREACHABLE();
}
- bdi.state = kThemeStateActive;
- bdi.value = kThemeButtonOff;
- bdi.adornment = kThemeAdornmentNone;
- CGRect cgRect = ret.toCGRect();
- CGRect outRect;
- HIThemeGetButtonBackgroundBounds(&cgRect, &bdi, &outRect);
+ NSStepperCell *cell = static_cast<NSStepperCell *>(d->cocoaCell(QCocoaWidget(QCocoaStepper, aquaSize)));
+ const CGRect outRect = [cell drawingRectForBounds:ret.toCGRect()];
ret = QRectF::fromCGRect(outRect).toRect();
+
switch (sc) {
case SC_SpinBoxUp:
ret.setHeight(ret.height() / 2);
diff --git a/src/plugins/styles/mac/qmacstyle_mac_p_p.h b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
index f312adac52..3aacd14e60 100644
--- a/src/plugins/styles/mac/qmacstyle_mac_p_p.h
+++ b/src/plugins/styles/mac/qmacstyle_mac_p_p.h
@@ -118,6 +118,7 @@
Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGContext);
Q_FORWARD_DECLARE_OBJC_CLASS(NSView);
+Q_FORWARD_DECLARE_OBJC_CLASS(NSCell);
Q_FORWARD_DECLARE_OBJC_CLASS(NSButtonCell);
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(NotificationReceiver));
@@ -147,7 +148,8 @@ enum QCocoaWidgetKind {
QCocoaHorizontalScroller,
QCocoaVerticalScroller,
QCocoaHorizontalSlider,
- QCocoaVerticalSlider
+ QCocoaVerticalSlider,
+ QCocoaStepper // QSpinBox buttons
};
typedef QPair<QCocoaWidgetKind, QStyleHelper::WidgetSizePolicy> QCocoaWidget;
@@ -227,6 +229,7 @@ public:
void setAutoDefaultButton(QObject *button) const;
NSView *cocoaControl(QCocoaWidget widget) const;
+ NSCell *cocoaCell(QCocoaWidget widget) const;
void setupNSGraphicsContext(CGContextRef cg, bool flipped) const;
void restoreNSGraphicsContext(CGContextRef cg) const;
@@ -252,6 +255,7 @@ public:
NSButtonCell *indicatorBranchButtonCell;
NSView *backingStoreNSView;
QHash<QCocoaWidget, NSView *> cocoaControls;
+ QHash<QCocoaWidget, NSCell *> cocoaCells;
};
QT_END_NAMESPACE