Bug 1421088 - Don't pass an nsIFrame* to DrawCheckboxOrRadio. r?spohl
MozReview-Commit-ID: 6LGIVGJAQ6W
--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -48,16 +48,22 @@ public:
enum class MenuIcon : uint8_t {
eCheckmark,
eMenuArrow,
eMenuDownScrollArrow,
eMenuUpScrollArrow
};
+ enum class CheckboxOrRadioState : uint8_t {
+ eOff,
+ eOn,
+ eIndeterminate
+ };
+
enum class ButtonType : uint8_t {
eRegularPushButton,
eDefaultPushButton,
eRegularBevelButton,
eDefaultBevelButton,
eRoundedBezelPushButton,
eSquareBezelPushButton,
eArrowButton,
@@ -101,16 +107,22 @@ public:
struct MenuItemParams {
mozilla::Maybe<mozilla::gfx::Color> vibrancyColor;
bool checked = false;
bool disabled = false;
bool selected = false;
bool rtl = false;
};
+ struct CheckboxOrRadioParams {
+ ControlParams controlParams;
+ CheckboxOrRadioState state = CheckboxOrRadioState::eOff;
+ float verticalAlignFactor = 0.5f;
+ };
+
struct ButtonParams {
ControlParams controlParams;
ButtonType button = ButtonType::eRegularPushButton;
};
struct TreeHeaderCellParams {
ControlParams controlParams;
TreeSortDirection sortDirection = eTreeSortDirection_Natural;
@@ -203,18 +215,18 @@ protected:
mozilla::EventStates inState, nsIFrame* aFrame,
const SegmentedControlRenderSettings& aSettings);
void DrawTabPanel(CGContextRef context, const HIRect& inBoxRect, nsIFrame* aFrame);
void DrawScale(CGContextRef context, const HIRect& inBoxRect,
mozilla::EventStates inState, bool inDirection,
bool inIsReverse, int32_t inCurrentValue, int32_t inMinValue,
int32_t inMaxValue, nsIFrame* aFrame);
void DrawCheckboxOrRadio(CGContextRef cgContext, bool inCheckbox,
- const HIRect& inBoxRect, bool inSelected,
- mozilla::EventStates inState, nsIFrame* aFrame);
+ const HIRect& inBoxRect,
+ const CheckboxOrRadioParams& aParams);
void DrawSearchField(CGContextRef cgContext, const HIRect& inBoxRect,
nsIFrame* aFrame, mozilla::EventStates inState);
void DrawRoundedBezelPushButton(CGContextRef cgContext,
const HIRect& inBoxRect,
ControlParams aControlParams);
void DrawSquareBezelPushButton(CGContextRef cgContext,
const HIRect& inBoxRect,
ControlParams aControlParams);
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -993,45 +993,51 @@ static const CellRenderSettings checkbox
{ // Yosemite
{0, 1, 0, 0}, // mini
{0, 1, 0, 1}, // small
{0, 1, 0, 1} // regular
}
}
};
+static NSCellStateValue
+CellStateForCheckboxOrRadioState(nsNativeThemeCocoa::CheckboxOrRadioState aState)
+{
+ switch (aState) {
+ case nsNativeThemeCocoa::CheckboxOrRadioState::eOff:
+ return NSOffState;
+ case nsNativeThemeCocoa::CheckboxOrRadioState::eOn:
+ return NSOnState;
+ case nsNativeThemeCocoa::CheckboxOrRadioState::eIndeterminate:
+ return NSMixedState;
+ }
+}
+
void
nsNativeThemeCocoa::DrawCheckboxOrRadio(CGContextRef cgContext, bool inCheckbox,
- const HIRect& inBoxRect, bool inSelected,
- EventStates inState, nsIFrame* aFrame)
+ const HIRect& inBoxRect,
+ const CheckboxOrRadioParams& aParams)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
NSButtonCell *cell = inCheckbox ? mCheckboxCell : mRadioButtonCell;
- NSCellStateValue state = inSelected ? NSOnState : NSOffState;
-
- // Check if we have an indeterminate checkbox
- if (inCheckbox && GetIndeterminate(aFrame))
- state = NSMixedState;
-
- [cell setEnabled:!IsDisabled(aFrame, inState)];
- [cell setShowsFirstResponder:inState.HasState(NS_EVENT_STATE_FOCUS)];
- [cell setState:state];
- [cell setHighlighted:inState.HasAllStates(NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_HOVER)];
- [cell setControlTint:(FrameIsInActiveWindow(aFrame) ? [NSColor currentControlTint] : NSClearControlTint)];
+ ApplyControlParamsToNSCell(aParams.controlParams, cell);
+
+ [cell setState:CellStateForCheckboxOrRadioState(aParams.state)];
+ [cell setControlTint:(aParams.controlParams.insideActiveWindow ? [NSColor currentControlTint] : NSClearControlTint)];
// Ensure that the control is square.
float length = std::min(inBoxRect.size.width, inBoxRect.size.height);
HIRect drawRect = CGRectMake(inBoxRect.origin.x + (int)((inBoxRect.size.width - length) / 2.0f),
inBoxRect.origin.y + (int)((inBoxRect.size.height - length) / 2.0f),
length, length);
DrawCellWithSnapping(cell, cgContext, drawRect,
inCheckbox ? checkboxSettings : radioSettings,
- VerticalAlignFactor(aFrame), mCellDrawView, NO);
+ aParams.verticalAlignFactor, mCellDrawView, NO);
NS_OBJC_END_TRY_ABORT_BLOCK;
}
static const CellRenderSettings searchFieldSettings = {
{
NSMakeSize(0, 16), // mini
NSMakeSize(0, 19), // small
@@ -2716,18 +2722,27 @@ nsNativeThemeCocoa::DrawWidgetBackground
SetCGContextFillColor(cgContext, kTooltipBackgroundColor);
CGContextFillRect(cgContext, macRect);
}
break;
case NS_THEME_CHECKBOX:
case NS_THEME_RADIO: {
bool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
- DrawCheckboxOrRadio(cgContext, isCheckbox, macRect, GetCheckedOrSelected(aFrame, !isCheckbox),
- eventState, aFrame);
+
+ CheckboxOrRadioParams params;
+ params.state = CheckboxOrRadioState::eOff;
+ if (isCheckbox && GetIndeterminate(aFrame)) {
+ params.state = CheckboxOrRadioState::eIndeterminate;
+ } else if (GetCheckedOrSelected(aFrame, !isCheckbox)) {
+ params.state = CheckboxOrRadioState::eOn;
+ }
+ params.controlParams = ComputeControlParams(aFrame, eventState);
+ params.verticalAlignFactor = VerticalAlignFactor(aFrame);
+ DrawCheckboxOrRadio(cgContext, isCheckbox, macRect, params);
}
break;
case NS_THEME_BUTTON:
if (IsDefaultButton(aFrame)) {
// Check whether the default button is in a document that does not
// match the :-moz-window-inactive pseudoclass. This activeness check
// is different from the other "active window" checks in this file