diff options
author | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2017-05-15 13:29:07 -0700 |
---|---|---|
committer | Gabriel de Dietrich <gabriel.dedietrich@qt.io> | 2017-05-15 22:40:18 +0000 |
commit | 6f3b59bfe4d22f8c717f1727816d3f8e775996be (patch) | |
tree | fb767cf4cdd2dd56da99ce4867d46ab6c1c446e9 /src/plugins/styles | |
parent | ee1868df2b6b60d59dff1a14fa2c16a9e759ef19 (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.mm | 130 | ||||
-rw-r--r-- | src/plugins/styles/mac/qmacstyle_mac_p_p.h | 6 |
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 |