--- a/widget/cocoa/nsNativeThemeCocoa.h
+++ b/widget/cocoa/nsNativeThemeCocoa.h
@@ -4,16 +4,18 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsNativeThemeCocoa_h_
#define nsNativeThemeCocoa_h_
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
+#include "mozilla/Variant.h"
+
#include "nsITheme.h"
#include "nsCOMPtr.h"
#include "nsAtom.h"
#include "nsNativeTheme.h"
@class CellDrawView;
@class NSProgressBarCell;
class nsDeviceContext;
@@ -232,16 +234,136 @@ public:
bool overlay : 1;
bool rolledOver : 1;
bool small : 1;
bool horizontal : 1;
bool rtl : 1;
bool onDarkBackground : 1;
};
+ enum Widget : uint8_t {
+ eColorFill, // mozilla::gfx::Color
+ eSheetBackground,
+ eDialogBackground,
+ eMenuBackground, // MenuBackgroundParams
+ eMenuIcon, // MenuIconParams
+ eMenuItem, // MenuItemParams
+ eMenuSeparator, // MenuItemParams
+ eTooltip,
+ eCheckbox, // CheckboxOrRadioParams
+ eRadio, // CheckboxOrRadioParams
+ eButton, // ButtonParams
+ eDropdown, // DropdownParams
+ eFocusOutline,
+ eSpinButtons, // SpinButtonParams
+ eSpinButtonUp, // SpinButtonParams
+ eSpinButtonDown, // SpinButtonParams
+ eSegment, // SegmentParams
+ eSeparator,
+ eUnifiedToolbar, // UnifiedToolbarParams
+ eToolbar, // bool
+ eNativeTitlebar, // UnifiedToolbarParams
+ eStatusBar, // bool
+ eGroupBox,
+ eTextBox, // TextBoxParams
+ eSearchField, // SearchFieldParams
+ eProgressBar, // ProgressParams
+ eMeter, // MeterParams
+ eTreeHeaderCell, // TreeHeaderCellParams
+ eScale, // ScaleParams
+ eScrollbarThumb, // ScrollbarParams
+ eScrollbarTrack, // ScrollbarParams
+ eMultilineTextField, // bool
+ eListBox,
+ eSourceList, // bool
+ eActiveSourceListSelection, // bool
+ eInactiveSourceListSelection, // bool
+ eTabPanel,
+ eResizer
+ };
+
+ struct WidgetInfo {
+ static WidgetInfo ColorFill(const mozilla::gfx::Color& aParams) { return WidgetInfo(Widget::eColorFill, aParams); }
+ static WidgetInfo SheetBackground() { return WidgetInfo(Widget::eSheetBackground, false); }
+ static WidgetInfo DialogBackground() { return WidgetInfo(Widget::eDialogBackground, false); }
+ static WidgetInfo MenuBackground(const MenuBackgroundParams& aParams) { return WidgetInfo(Widget::eMenuBackground, aParams); }
+ static WidgetInfo MenuIcon(const MenuIconParams& aParams) { return WidgetInfo(Widget::eMenuIcon, aParams); }
+ static WidgetInfo MenuItem(const MenuItemParams& aParams) { return WidgetInfo(Widget::eMenuItem, aParams); }
+ static WidgetInfo MenuSeparator(const MenuItemParams& aParams) { return WidgetInfo(Widget::eMenuSeparator, aParams); }
+ static WidgetInfo Tooltip() { return WidgetInfo(Widget::eTooltip, false); }
+ static WidgetInfo Checkbox(const CheckboxOrRadioParams& aParams) { return WidgetInfo(Widget::eCheckbox, aParams); }
+ static WidgetInfo Radio(const CheckboxOrRadioParams& aParams) { return WidgetInfo(Widget::eRadio, aParams); }
+ static WidgetInfo Button(const ButtonParams& aParams) { return WidgetInfo(Widget::eButton, aParams); }
+ static WidgetInfo Dropdown(const DropdownParams& aParams) { return WidgetInfo(Widget::eDropdown, aParams); }
+ static WidgetInfo FocusOutline() { return WidgetInfo(Widget::eFocusOutline, false); }
+ static WidgetInfo SpinButtons(const SpinButtonParams& aParams) { return WidgetInfo(Widget::eSpinButtons, aParams); }
+ static WidgetInfo SpinButtonUp(const SpinButtonParams& aParams) { return WidgetInfo(Widget::eSpinButtonUp, aParams); }
+ static WidgetInfo SpinButtonDown(const SpinButtonParams& aParams) { return WidgetInfo(Widget::eSpinButtonDown, aParams); }
+ static WidgetInfo Segment(const SegmentParams& aParams) { return WidgetInfo(Widget::eSegment, aParams); }
+ static WidgetInfo Separator() { return WidgetInfo(Widget::eSeparator, false); }
+ static WidgetInfo UnifiedToolbar(const UnifiedToolbarParams& aParams) { return WidgetInfo(Widget::eUnifiedToolbar, aParams); }
+ static WidgetInfo Toolbar(bool aParams) { return WidgetInfo(Widget::eToolbar, aParams); }
+ static WidgetInfo NativeTitlebar(const UnifiedToolbarParams& aParams) { return WidgetInfo(Widget::eNativeTitlebar, aParams); }
+ static WidgetInfo StatusBar(bool aParams) { return WidgetInfo(Widget::eStatusBar, aParams); }
+ static WidgetInfo GroupBox() { return WidgetInfo(Widget::eGroupBox, false); }
+ static WidgetInfo TextBox(const TextBoxParams& aParams) { return WidgetInfo(Widget::eTextBox, aParams); }
+ static WidgetInfo SearchField(const SearchFieldParams& aParams) { return WidgetInfo(Widget::eSearchField, aParams); }
+ static WidgetInfo ProgressBar(const ProgressParams& aParams) { return WidgetInfo(Widget::eProgressBar, aParams); }
+ static WidgetInfo Meter(const MeterParams& aParams) { return WidgetInfo(Widget::eMeter, aParams); }
+ static WidgetInfo TreeHeaderCell(const TreeHeaderCellParams& aParams) { return WidgetInfo(Widget::eTreeHeaderCell, aParams); }
+ static WidgetInfo Scale(const ScaleParams& aParams) { return WidgetInfo(Widget::eScale, aParams); }
+ static WidgetInfo ScrollbarThumb(const ScrollbarParams& aParams) { return WidgetInfo(Widget::eScrollbarThumb, aParams); }
+ static WidgetInfo ScrollbarTrack(const ScrollbarParams& aParams) { return WidgetInfo(Widget::eScrollbarTrack, aParams); }
+ static WidgetInfo MultilineTextField(bool aParams) { return WidgetInfo(Widget::eMultilineTextField, aParams); }
+ static WidgetInfo ListBox() { return WidgetInfo(Widget::eListBox, false); }
+ static WidgetInfo SourceList(bool aParams) { return WidgetInfo(Widget::eSourceList, aParams); }
+ static WidgetInfo ActiveSourceListSelection(bool aParams) { return WidgetInfo(Widget::eActiveSourceListSelection, aParams); }
+ static WidgetInfo InactiveSourceListSelection(bool aParams) { return WidgetInfo(Widget::eInactiveSourceListSelection, aParams); }
+ static WidgetInfo TabPanel(bool aParams) { return WidgetInfo(Widget::eTabPanel, aParams); }
+ static WidgetInfo Resizer(bool aParams) { return WidgetInfo(Widget::eResizer, aParams); }
+
+ template<typename T>
+ T Params() const
+ {
+ MOZ_RELEASE_ASSERT(mVariant.is<T>());
+ return mVariant.as<T>();
+ }
+
+ enum Widget Widget() const { return mWidget; }
+
+ private:
+ template<typename T> WidgetInfo(enum Widget aWidget, const T& aParams)
+ : mVariant(aParams)
+ , mWidget(aWidget)
+ {}
+
+ mozilla::Variant<
+ mozilla::gfx::Color,
+ MenuBackgroundParams,
+ MenuIconParams,
+ MenuItemParams,
+ CheckboxOrRadioParams,
+ ButtonParams,
+ DropdownParams,
+ SpinButtonParams,
+ SegmentParams,
+ UnifiedToolbarParams,
+ TextBoxParams,
+ SearchFieldParams,
+ ProgressParams,
+ MeterParams,
+ TreeHeaderCellParams,
+ ScaleParams,
+ ScrollbarParams,
+ bool
+ > mVariant;
+
+ enum Widget mWidget;
+ };
+
nsNativeThemeCocoa();
NS_DECL_ISUPPORTS_INHERITED
// The nsITheme interface.
NS_IMETHOD DrawWidgetBackground(gfxContext* aContext,
nsIFrame* aFrame,
uint8_t aWidgetType,
--- a/widget/cocoa/nsNativeThemeCocoa.mm
+++ b/widget/cocoa/nsNativeThemeCocoa.mm
@@ -2821,24 +2821,16 @@ nsNativeThemeCocoa::DrawSourceList(CGCon
backgroundGradient =
CGGradientCreateWithColorComponents(rgb, aIsActive ? activeGradientColors
: inactiveGradientColors, NULL, 2);
CGContextDrawLinearGradient(cgContext, backgroundGradient, start, end, 0);
CGGradientRelease(backgroundGradient);
CGColorSpaceRelease(rgb);
}
-static void
-DrawVibrancyBackground(CGContextRef cgContext, CGRect inBoxRect,
- nsIFrame* aFrame, nsITheme::ThemeGeometryType aThemeGeometryType)
-{
- DrawVibrancyBackground(cgContext, inBoxRect,
- VibrancyFillColor(aFrame, aThemeGeometryType), 0);
-}
-
bool
nsNativeThemeCocoa::IsParentScrollbarRolledOver(nsIFrame* aFrame)
{
nsIFrame* scrollbarFrame = GetParentScrollbarFrame(aFrame);
return nsLookAndFeel::UseOverlayScrollbars()
? CheckBooleanAttr(scrollbarFrame, nsGkAtoms::hover)
: GetContentState(scrollbarFrame, NS_THEME_NONE).HasState(NS_EVENT_STATE_HOVER);
}
@@ -2922,92 +2914,94 @@ nsNativeThemeCocoa::DrawWidgetBackground
CGRect bounds = CGContextGetClipBoundingBox(cgContext);
fprintf(stderr, " --> clip bounds: %f %f %f %f\n",
bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
//CGContextSetRGBFillColor(cgContext, 0.0, 0.0, 1.0, 0.1);
//CGContextFillRect(cgContext, bounds);
#endif
+ Maybe<WidgetInfo> widgetInfo;
+
EventStates eventState = GetContentState(aFrame, aWidgetType);
switch (aWidgetType) {
- case NS_THEME_DIALOG: {
+ case NS_THEME_DIALOG:
if (IsWindowSheet(aFrame)) {
if (VibrancyManager::SystemSupportsVibrancy()) {
ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
- DrawVibrancyBackground(cgContext, macRect, aFrame, type);
+ widgetInfo = Some(WidgetInfo::ColorFill(VibrancyFillColor(aFrame, type)));
} else {
- HIThemeSetFill(kThemeBrushSheetBackgroundTransparent, NULL, cgContext, HITHEME_ORIENTATION);
- CGContextFillRect(cgContext, macRect);
+ widgetInfo = Some(WidgetInfo::SheetBackground());
}
} else {
- HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION);
- CGContextFillRect(cgContext, macRect);
+ widgetInfo = Some(WidgetInfo::DialogBackground());
}
-
- }
break;
case NS_THEME_MENUPOPUP:
- DrawMenuBackground(cgContext, macRect,
- ComputeMenuBackgroundParams(aFrame, eventState));
+ widgetInfo = Some(WidgetInfo::MenuBackground(
+ ComputeMenuBackgroundParams(aFrame, eventState)));
break;
case NS_THEME_MENUARROW:
- DrawMenuIcon(cgContext, macRect,
- ComputeMenuIconParams(aFrame, eventState,
- MenuIcon::eMenuArrow));
+ widgetInfo = Some(WidgetInfo::MenuIcon(
+ ComputeMenuIconParams(aFrame, eventState,
+ MenuIcon::eMenuArrow)));
break;
case NS_THEME_MENUITEM:
case NS_THEME_CHECKMENUITEM:
- DrawMenuItem(cgContext, macRect,
- ComputeMenuItemParams(aFrame, eventState,
- aWidgetType == NS_THEME_CHECKMENUITEM));
+ widgetInfo = Some(WidgetInfo::MenuItem(
+ ComputeMenuItemParams(aFrame, eventState,
+ aWidgetType == NS_THEME_CHECKMENUITEM)));
break;
case NS_THEME_MENUSEPARATOR:
- DrawMenuSeparator(cgContext, macRect,
- ComputeMenuItemParams(aFrame, eventState, false));
+ widgetInfo = Some(WidgetInfo::MenuSeparator(
+ ComputeMenuItemParams(aFrame, eventState, false)));
break;
case NS_THEME_BUTTON_ARROW_UP:
case NS_THEME_BUTTON_ARROW_DOWN: {
MenuIcon icon =
aWidgetType == NS_THEME_BUTTON_ARROW_UP ? MenuIcon::eMenuUpScrollArrow
: MenuIcon::eMenuDownScrollArrow;
- DrawMenuIcon(cgContext, macRect,
- ComputeMenuIconParams(aFrame, eventState, icon));
+ widgetInfo = Some(WidgetInfo::MenuIcon(
+ ComputeMenuIconParams(aFrame, eventState, icon)));
}
break;
case NS_THEME_TOOLTIP:
if (VibrancyManager::SystemSupportsVibrancy()) {
- DrawVibrancyBackground(cgContext, macRect, aFrame, ThemeGeometryTypeForWidget(aFrame, aWidgetType));
+ ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
+ widgetInfo = Some(WidgetInfo::ColorFill(VibrancyFillColor(aFrame, type)));
} else {
- SetCGContextFillColor(cgContext, kTooltipBackgroundColor);
- CGContextFillRect(cgContext, macRect);
+ widgetInfo = Some(WidgetInfo::Tooltip());
}
break;
case NS_THEME_CHECKBOX:
case NS_THEME_RADIO: {
bool isCheckbox = (aWidgetType == NS_THEME_CHECKBOX);
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);
+ if (isCheckbox) {
+ widgetInfo = Some(WidgetInfo::Checkbox(params));
+ } else {
+ widgetInfo = Some(WidgetInfo::Radio(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
@@ -3025,71 +3019,71 @@ nsNativeThemeCocoa::DrawWidgetBackground
}
bool hasDefaultButtonLook =
isInActiveWindow && !eventState.HasState(NS_EVENT_STATE_ACTIVE);
ButtonType buttonType =
hasDefaultButtonLook ? ButtonType::eDefaultPushButton
: ButtonType::eRegularPushButton;
ControlParams params = ComputeControlParams(aFrame, eventState);
params.insideActiveWindow = isInActiveWindow;
- DrawButton(cgContext, macRect, ButtonParams{params, buttonType});
+ widgetInfo = Some(WidgetInfo::Button(ButtonParams{params, buttonType}));
} else if (IsButtonTypeMenu(aFrame)) {
ControlParams controlParams = ComputeControlParams(aFrame, eventState);
controlParams.focused = controlParams.focused || IsFocused(aFrame);
controlParams.pressed = IsOpenButton(aFrame);
DropdownParams params;
params.controlParams = controlParams;
params.pullsDown = true;
params.editable = false;
- DrawDropdown(cgContext, macRect, params);
+ widgetInfo = Some(WidgetInfo::Dropdown(params));
} else if (nativeWidgetHeight > DO_SQUARE_BUTTON_HEIGHT) {
// If the button is tall enough, draw the square button style so that
// buttons with non-standard content look good. Otherwise draw normal
// rounded aqua buttons.
// This comparison is done based on the height that is calculated without
// the top, because the snapped height can be affected by the top of the
// rect and that may result in different height depending on the top value.
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eSquareBezelPushButton});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eSquareBezelPushButton}));
} else {
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eRoundedBezelPushButton});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eRoundedBezelPushButton}));
}
break;
case NS_THEME_FOCUS_OUTLINE:
- DrawFocusOutline(cgContext, macRect);
+ widgetInfo = Some(WidgetInfo::FocusOutline());
break;
case NS_THEME_MAC_HELP_BUTTON:
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eHelpButton});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eHelpButton}));
break;
case NS_THEME_MAC_DISCLOSURE_BUTTON_OPEN:
case NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED: {
ButtonType buttonType = (aWidgetType == NS_THEME_MAC_DISCLOSURE_BUTTON_CLOSED)
? ButtonType::eDisclosureButtonClosed : ButtonType::eDisclosureButtonOpen;
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- buttonType});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ buttonType}));
}
break;
case NS_THEME_BUTTON_BEVEL: {
bool isDefaultButton = IsDefaultButton(aFrame);
ButtonType buttonType =
isDefaultButton ? ButtonType::eDefaultBevelButton
: ButtonType::eRegularBevelButton;
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- buttonType});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ buttonType}));
}
break;
case NS_THEME_INNER_SPIN_BUTTON: {
case NS_THEME_SPINNER:
bool isSpinner = (aWidgetType == NS_THEME_SPINNER);
nsIContent* content = aFrame->GetContent();
if (isSpinner && content->IsHTMLElement()) {
@@ -3106,17 +3100,17 @@ nsNativeThemeCocoa::DrawWidgetBackground
} else if (content->AsElement()->AttrValueIs(kNameSpaceID_None, nsGkAtoms::state,
NS_LITERAL_STRING("down"), eCaseMatters)) {
params.pressedButton = Some(SpinButton::eDown);
}
}
params.disabled = IsDisabled(aFrame, eventState);
params.insideActiveWindow = FrameIsInActiveWindow(aFrame);
- DrawSpinButtons(cgContext, macRect, params);
+ widgetInfo = Some(WidgetInfo::SpinButtons(params));
}
break;
case NS_THEME_SPINNER_UPBUTTON:
case NS_THEME_SPINNER_DOWNBUTTON: {
nsNumberControlFrame* numberControlFrame =
nsNumberControlFrame::GetNumberControlFrameForSpinButton(aFrame);
if (numberControlFrame) {
@@ -3124,310 +3118,488 @@ nsNativeThemeCocoa::DrawWidgetBackground
if (numberControlFrame->SpinnerUpButtonIsDepressed()) {
params.pressedButton = Some(SpinButton::eUp);
} else if (numberControlFrame->SpinnerDownButtonIsDepressed()) {
params.pressedButton = Some(SpinButton::eDown);
}
params.disabled = IsDisabled(aFrame, eventState);
params.insideActiveWindow = FrameIsInActiveWindow(aFrame);
if (aWidgetType == NS_THEME_SPINNER_UPBUTTON) {
- DrawSpinButton(cgContext, macRect, SpinButton::eUp, params);
+ widgetInfo = Some(WidgetInfo::SpinButtonUp(params));
} else {
- DrawSpinButton(cgContext, macRect, SpinButton::eDown, params);
+ widgetInfo = Some(WidgetInfo::SpinButtonDown(params));
}
}
}
break;
case NS_THEME_TOOLBARBUTTON: {
SegmentParams params =
ComputeSegmentParams(aFrame, eventState, SegmentType::eToolbarButton);
params.insideActiveWindow = [NativeWindowForFrame(aFrame) isMainWindow];
- DrawSegment(cgContext, macRect, params);
+ widgetInfo = Some(WidgetInfo::Segment(params));
}
break;
- case NS_THEME_SEPARATOR: {
- HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive };
- HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
- }
+ case NS_THEME_SEPARATOR:
+ widgetInfo = Some(WidgetInfo::Separator());
break;
case NS_THEME_TOOLBAR: {
NSWindow* win = NativeWindowForFrame(aFrame);
bool isMain = [win isMainWindow];
if (ToolbarCanBeUnified(macRect, win)) {
- float unifiedHeight =
- std::max([(ToolbarWindow*)win unifiedToolbarHeight],
- macRect.size.height);
- DrawUnifiedToolbar(cgContext, macRect,
- UnifiedToolbarParams{unifiedHeight, isMain});
- break;
+ float unifiedHeight = std::max([(ToolbarWindow*)win unifiedToolbarHeight],
+ macRect.size.height);
+ widgetInfo = Some(WidgetInfo::UnifiedToolbar(
+ UnifiedToolbarParams{unifiedHeight, isMain}));
+ } else {
+ widgetInfo = Some(WidgetInfo::Toolbar(isMain));
}
- DrawToolbar(cgContext, macRect, isMain);
}
break;
case NS_THEME_WINDOW_TITLEBAR: {
NSWindow* win = NativeWindowForFrame(aFrame);
bool isMain = [win isMainWindow];
float unifiedToolbarHeight = [win isKindOfClass:[ToolbarWindow class]] ?
[(ToolbarWindow*)win unifiedToolbarHeight] : macRect.size.height;
- DrawNativeTitlebar(cgContext, macRect,
- UnifiedToolbarParams{unifiedToolbarHeight, isMain});
+ widgetInfo = Some(WidgetInfo::NativeTitlebar(
+ UnifiedToolbarParams{unifiedToolbarHeight, isMain}));
}
break;
case NS_THEME_STATUSBAR:
- DrawStatusBar(cgContext, macRect, IsActive(aFrame, YES));
+ widgetInfo = Some(WidgetInfo::StatusBar(IsActive(aFrame, YES)));
break;
case NS_THEME_MENULIST:
case NS_THEME_MENULIST_TEXTFIELD: {
ControlParams controlParams = ComputeControlParams(aFrame, eventState);
controlParams.focused = controlParams.focused || IsFocused(aFrame);
controlParams.pressed = IsOpenButton(aFrame);
DropdownParams params;
params.controlParams = controlParams;
params.pullsDown = false;
params.editable = aWidgetType == NS_THEME_MENULIST_TEXTFIELD;
- DrawDropdown(cgContext, macRect, params);
+ widgetInfo = Some(WidgetInfo::Dropdown(params));
}
break;
case NS_THEME_MENULIST_BUTTON:
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eArrowButton});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eArrowButton}));
break;
- case NS_THEME_GROUPBOX: {
- HIThemeGroupBoxDrawInfo gdi = { 0, kThemeStateActive, kHIThemeGroupBoxKindPrimary };
- HIThemeDrawGroupBox(&macRect, &gdi, cgContext, HITHEME_ORIENTATION);
+ case NS_THEME_GROUPBOX:
+ widgetInfo = Some(WidgetInfo::GroupBox());
break;
- }
case NS_THEME_TEXTFIELD:
case NS_THEME_NUMBER_INPUT: {
bool isFocused = eventState.HasState(NS_EVENT_STATE_FOCUS);
// XUL textboxes set the native appearance on the containing box, while
// concrete focus is set on the html:input element within it. We can
// though, check the focused attribute of xul textboxes in this case.
// On Mac, focus rings are always shown for textboxes, so we do not need
// to check the window's focus ring state here
if (aFrame->GetContent()->IsXULElement() && IsFocused(aFrame)) {
isFocused = true;
}
bool isDisabled = IsDisabled(aFrame, eventState) || IsReadOnly(aFrame);
- DrawTextBox(cgContext, macRect, TextBoxParams{isDisabled, isFocused});
+ widgetInfo = Some(WidgetInfo::TextBox(TextBoxParams{isDisabled, isFocused}));
break;
}
case NS_THEME_SEARCHFIELD:
- DrawSearchField(cgContext, macRect,
- ComputeSearchFieldParams(aFrame, eventState));
+ widgetInfo = Some(WidgetInfo::SearchField(
+ ComputeSearchFieldParams(aFrame, eventState)));
break;
case NS_THEME_PROGRESSBAR:
{
// Don't request repaints for scrollbars at 100% because those don't animate.
if (GetProgressValue(aFrame) < GetProgressMaxValue(aFrame)) {
if (!QueueAnimatedContentForRefresh(aFrame->GetContent(), 30)) {
NS_WARNING("Unable to animate progressbar!");
}
}
- DrawProgress(cgContext, macRect,
- ComputeProgressParams(aFrame, eventState,
- !IsVerticalProgress(aFrame)));
+ widgetInfo = Some(WidgetInfo::ProgressBar(
+ ComputeProgressParams(aFrame, eventState,
+ !IsVerticalProgress(aFrame))));
break;
}
case NS_THEME_PROGRESSBAR_VERTICAL:
- DrawProgress(cgContext, macRect,
- ComputeProgressParams(aFrame, eventState, false));
+ widgetInfo = Some(WidgetInfo::ProgressBar(
+ ComputeProgressParams(aFrame, eventState, false)));
break;
case NS_THEME_METERBAR:
- DrawMeter(cgContext, macRect, ComputeMeterParams(aFrame));
+ widgetInfo = Some(WidgetInfo::Meter(ComputeMeterParams(aFrame)));
break;
case NS_THEME_PROGRESSCHUNK:
case NS_THEME_PROGRESSCHUNK_VERTICAL:
case NS_THEME_METERCHUNK:
// Do nothing: progress and meter bars cases will draw chunks.
break;
case NS_THEME_TREETWISTY:
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eTreeTwistyPointingRight});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eTreeTwistyPointingRight}));
break;
case NS_THEME_TREETWISTYOPEN:
- DrawButton(cgContext, macRect,
- ButtonParams{ComputeControlParams(aFrame, eventState),
- ButtonType::eTreeTwistyPointingDown});
+ widgetInfo = Some(WidgetInfo::Button(
+ ButtonParams{ComputeControlParams(aFrame, eventState),
+ ButtonType::eTreeTwistyPointingDown}));
break;
case NS_THEME_TREEHEADERCELL:
- DrawTreeHeaderCell(cgContext, macRect,
- ComputeTreeHeaderCellParams(aFrame, eventState));
+ widgetInfo = Some(WidgetInfo::TreeHeaderCell(
+ ComputeTreeHeaderCellParams(aFrame, eventState)));
break;
case NS_THEME_TREEITEM:
case NS_THEME_TREEVIEW:
- // HIThemeSetFill is not available on 10.3
- // HIThemeSetFill(kThemeBrushWhite, NULL, cgContext, HITHEME_ORIENTATION);
- CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
- CGContextFillRect(cgContext, macRect);
+ widgetInfo = Some(WidgetInfo::ColorFill(Color(1.0, 1.0, 1.0, 1.0)));
break;
case NS_THEME_TREEHEADER:
// do nothing, taken care of by individual header cells
case NS_THEME_TREEHEADERSORTARROW:
// do nothing, taken care of by treeview header
case NS_THEME_TREELINE:
// do nothing, these lines don't exist on macos
break;
case NS_THEME_SCALE_HORIZONTAL:
case NS_THEME_SCALE_VERTICAL:
- DrawScale(cgContext, macRect,
- ComputeXULScaleParams(aFrame, eventState,
- aWidgetType == NS_THEME_SCALE_HORIZONTAL));
+ widgetInfo = Some(WidgetInfo::Scale(
+ ComputeXULScaleParams(aFrame, eventState,
+ aWidgetType == NS_THEME_SCALE_HORIZONTAL)));
break;
case NS_THEME_SCALETHUMB_HORIZONTAL:
case NS_THEME_SCALETHUMB_VERTICAL:
// do nothing, drawn by scale
break;
case NS_THEME_RANGE: {
Maybe<ScaleParams> params = ComputeHTMLScaleParams(aFrame, eventState);
if (params) {
- DrawScale(cgContext, macRect, *params);
+ widgetInfo = Some(WidgetInfo::Scale(*params));
}
break;
}
case NS_THEME_SCROLLBAR_SMALL:
case NS_THEME_SCROLLBAR:
break;
case NS_THEME_SCROLLBARTHUMB_VERTICAL:
case NS_THEME_SCROLLBARTHUMB_HORIZONTAL:
- DrawScrollbarThumb(cgContext, macRect,
+ widgetInfo = Some(WidgetInfo::ScrollbarThumb(
ComputeScrollbarParams(
- aFrame, aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL));
+ aFrame, aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL)));
break;
case NS_THEME_SCROLLBARBUTTON_UP:
case NS_THEME_SCROLLBARBUTTON_LEFT:
-#if SCROLLBARS_VISUAL_DEBUG
- CGContextSetRGBFillColor(cgContext, 1.0, 0, 0, 0.6);
- CGContextFillRect(cgContext, macRect);
-#endif
- break;
case NS_THEME_SCROLLBARBUTTON_DOWN:
case NS_THEME_SCROLLBARBUTTON_RIGHT:
-#if SCROLLBARS_VISUAL_DEBUG
- CGContextSetRGBFillColor(cgContext, 0, 1.0, 0, 0.6);
- CGContextFillRect(cgContext, macRect);
-#endif
- break;
+ break;
+
case NS_THEME_SCROLLBARTRACK_HORIZONTAL:
case NS_THEME_SCROLLBARTRACK_VERTICAL:
- DrawScrollbarTrack(cgContext, macRect,
+ widgetInfo = Some(WidgetInfo::ScrollbarTrack(
ComputeScrollbarParams(
- aFrame, aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL));
+ aFrame, aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL)));
break;
case NS_THEME_TEXTFIELD_MULTILINE:
- DrawMultilineTextField(cgContext, macRect,
- eventState.HasState(NS_EVENT_STATE_FOCUS));
+ widgetInfo = Some(WidgetInfo::MultilineTextField(
+ eventState.HasState(NS_EVENT_STATE_FOCUS)));
break;
- case NS_THEME_LISTBOX: {
- // We have to draw this by hand because kHIThemeFrameListBox drawing
- // is buggy on 10.5, see bug 579259.
- CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
- CGContextFillRect(cgContext, macRect);
-
- float x = macRect.origin.x, y = macRect.origin.y;
- float w = macRect.size.width, h = macRect.size.height;
- SetCGContextFillColor(cgContext, kListboxTopBorderColor);
- CGContextFillRect(cgContext, CGRectMake(x, y, w, 1));
- SetCGContextFillColor(cgContext, kListBoxSidesAndBottomBorderColor);
- CGContextFillRect(cgContext, CGRectMake(x, y + 1, 1, h - 1));
- CGContextFillRect(cgContext, CGRectMake(x + w - 1, y + 1, 1, h - 1));
- CGContextFillRect(cgContext, CGRectMake(x + 1, y + h - 1, w - 2, 1));
- }
+ case NS_THEME_LISTBOX:
+ widgetInfo = Some(WidgetInfo::ListBox());
break;
case NS_THEME_MAC_SOURCE_LIST: {
if (VibrancyManager::SystemSupportsVibrancy()) {
ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
- DrawVibrancyBackground(cgContext, macRect, aFrame, type);
+ widgetInfo = Some(WidgetInfo::ColorFill(VibrancyFillColor(aFrame, type)));
} else {
- DrawSourceList(cgContext, macRect, FrameIsInActiveWindow(aFrame));
+ widgetInfo = Some(WidgetInfo::SourceList(FrameIsInActiveWindow(aFrame)));
}
}
break;
case NS_THEME_MAC_SOURCE_LIST_SELECTION:
case NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION: {
// If we're in XUL tree, we need to rely on the source list's clear
// background display item. If we cleared the background behind the
// selections, the source list would not pick up the right font
// smoothing background. So, to simplify a bit, we only support vibrancy
// if we're in a source list.
if (VibrancyManager::SystemSupportsVibrancy() && IsInSourceList(aFrame)) {
ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
- DrawVibrancyBackground(cgContext, macRect, aFrame, type);
+ widgetInfo = Some(WidgetInfo::ColorFill(VibrancyFillColor(aFrame, type)));
} else {
- BOOL isActiveSelection =
- aWidgetType == NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION;
- RenderWithCoreUI(macRect, cgContext,
- [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:isActiveSelection], @"focus",
- [NSNumber numberWithBool:YES], @"is.flipped",
- @"kCUIVariantGradientSideBarSelection", @"kCUIVariantKey",
- (FrameIsInActiveWindow(aFrame) ? @"normal" : @"inactive"), @"state",
- @"gradient", @"widget",
- nil]);
+ bool isInActiveWindow = FrameIsInActiveWindow(aFrame);
+ if (aWidgetType == NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION) {
+ widgetInfo = Some(WidgetInfo::ActiveSourceListSelection(isInActiveWindow));
+ } else {
+ widgetInfo = Some(WidgetInfo::InactiveSourceListSelection(isInActiveWindow));
+ }
}
}
break;
case NS_THEME_TAB: {
SegmentParams params =
ComputeSegmentParams(aFrame, eventState, SegmentType::eTab);
params.pressed = params.pressed && !params.selected;
- DrawSegment(cgContext, macRect, params);
+ widgetInfo = Some(WidgetInfo::Segment(params));
}
break;
case NS_THEME_TABPANELS:
- DrawTabPanel(cgContext, macRect, FrameIsInActiveWindow(aFrame));
+ widgetInfo = Some(WidgetInfo::TabPanel(FrameIsInActiveWindow(aFrame)));
break;
case NS_THEME_RESIZER:
- DrawResizer(cgContext, macRect, IsFrameRTL(aFrame));
+ widgetInfo = Some(WidgetInfo::Resizer(IsFrameRTL(aFrame)));
break;
case NS_THEME_MAC_VIBRANCY_LIGHT:
case NS_THEME_MAC_VIBRANCY_DARK:
case NS_THEME_MAC_VIBRANT_TITLEBAR_LIGHT:
case NS_THEME_MAC_VIBRANT_TITLEBAR_DARK: {
ThemeGeometryType type = ThemeGeometryTypeForWidget(aFrame, aWidgetType);
- DrawVibrancyBackground(cgContext, macRect, aFrame, type);
+ widgetInfo = Some(WidgetInfo::ColorFill(VibrancyFillColor(aFrame, type)));
break;
}
}
+ if (widgetInfo) {
+ switch (widgetInfo->Widget()) {
+ case Widget::eColorFill: {
+ Color params = widgetInfo->Params<Color>();
+ SetCGContextFillColor(cgContext, params);
+ CGContextFillRect(cgContext, macRect);
+ break;
+ }
+ case Widget::eSheetBackground: {
+ HIThemeSetFill(kThemeBrushSheetBackgroundTransparent, NULL, cgContext, HITHEME_ORIENTATION);
+ CGContextFillRect(cgContext, macRect);
+ break;
+ }
+ case Widget::eDialogBackground: {
+ HIThemeSetFill(kThemeBrushDialogBackgroundActive, NULL, cgContext, HITHEME_ORIENTATION);
+ CGContextFillRect(cgContext, macRect);
+ break;
+ }
+ case Widget::eMenuBackground: {
+ MenuBackgroundParams params = widgetInfo->Params<MenuBackgroundParams>();
+ DrawMenuBackground(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eMenuIcon: {
+ MenuIconParams params = widgetInfo->Params<MenuIconParams>();
+ DrawMenuIcon(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eMenuItem: {
+ MenuItemParams params = widgetInfo->Params<MenuItemParams>();
+ DrawMenuItem(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eMenuSeparator: {
+ MenuItemParams params = widgetInfo->Params<MenuItemParams>();
+ DrawMenuSeparator(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eTooltip: {
+ SetCGContextFillColor(cgContext, kTooltipBackgroundColor);
+ CGContextFillRect(cgContext, macRect);
+ break;
+ }
+ case Widget::eCheckbox: {
+ CheckboxOrRadioParams params = widgetInfo->Params<CheckboxOrRadioParams>();
+ DrawCheckboxOrRadio(cgContext, true, macRect, params);
+ break;
+ }
+ case Widget::eRadio: {
+ CheckboxOrRadioParams params = widgetInfo->Params<CheckboxOrRadioParams>();
+ DrawCheckboxOrRadio(cgContext, false, macRect, params);
+ break;
+ }
+ case Widget::eButton: {
+ ButtonParams params = widgetInfo->Params<ButtonParams>();
+ DrawButton(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eDropdown: {
+ DropdownParams params = widgetInfo->Params<DropdownParams>();
+ DrawDropdown(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eFocusOutline: {
+ DrawFocusOutline(cgContext, macRect);
+ break;
+ }
+ case Widget::eSpinButtons: {
+ SpinButtonParams params = widgetInfo->Params<SpinButtonParams>();
+ DrawSpinButtons(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eSpinButtonUp: {
+ SpinButtonParams params = widgetInfo->Params<SpinButtonParams>();
+ DrawSpinButton(cgContext, macRect, SpinButton::eUp, params);
+ break;
+ }
+ case Widget::eSpinButtonDown: {
+ SpinButtonParams params = widgetInfo->Params<SpinButtonParams>();
+ DrawSpinButton(cgContext, macRect, SpinButton::eDown, params);
+ break;
+ }
+ case Widget::eSegment: {
+ SegmentParams params = widgetInfo->Params<SegmentParams>();
+ DrawSegment(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eSeparator: {
+ HIThemeSeparatorDrawInfo sdi = { 0, kThemeStateActive };
+ HIThemeDrawSeparator(&macRect, &sdi, cgContext, HITHEME_ORIENTATION);
+ break;
+ }
+ case Widget::eUnifiedToolbar: {
+ UnifiedToolbarParams params = widgetInfo->Params<UnifiedToolbarParams>();
+ DrawUnifiedToolbar(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eToolbar: {
+ bool isMain = widgetInfo->Params<bool>();
+ DrawToolbar(cgContext, macRect, isMain);
+ break;
+ }
+ case Widget::eNativeTitlebar: {
+ UnifiedToolbarParams params = widgetInfo->Params<UnifiedToolbarParams>();
+ DrawNativeTitlebar(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eStatusBar: {
+ bool isMain = widgetInfo->Params<bool>();
+ DrawStatusBar(cgContext, macRect, isMain);
+ break;
+ }
+ case Widget::eGroupBox: {
+ HIThemeGroupBoxDrawInfo gdi = { 0, kThemeStateActive, kHIThemeGroupBoxKindPrimary };
+ HIThemeDrawGroupBox(&macRect, &gdi, cgContext, HITHEME_ORIENTATION);
+ break;
+ }
+ case Widget::eTextBox: {
+ TextBoxParams params = widgetInfo->Params<TextBoxParams>();
+ DrawTextBox(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eSearchField: {
+ SearchFieldParams params = widgetInfo->Params<SearchFieldParams>();
+ DrawSearchField(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eProgressBar: {
+ ProgressParams params = widgetInfo->Params<ProgressParams>();
+ DrawProgress(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eMeter: {
+ MeterParams params = widgetInfo->Params<MeterParams>();
+ DrawMeter(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eTreeHeaderCell: {
+ TreeHeaderCellParams params = widgetInfo->Params<TreeHeaderCellParams>();
+ DrawTreeHeaderCell(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eScale: {
+ ScaleParams params = widgetInfo->Params<ScaleParams>();
+ DrawScale(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eScrollbarThumb: {
+ ScrollbarParams params = widgetInfo->Params<ScrollbarParams>();
+ DrawScrollbarThumb(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eScrollbarTrack: {
+ ScrollbarParams params = widgetInfo->Params<ScrollbarParams>();
+ DrawScrollbarTrack(cgContext, macRect, params);
+ break;
+ }
+ case Widget::eMultilineTextField: {
+ bool isFocused = widgetInfo->Params<bool>();
+ DrawMultilineTextField(cgContext, macRect, isFocused);
+ break;
+ }
+ case Widget::eListBox: {
+ // We have to draw this by hand because kHIThemeFrameListBox drawing
+ // is buggy on 10.5, see bug 579259.
+ CGContextSetRGBFillColor(cgContext, 1.0, 1.0, 1.0, 1.0);
+ CGContextFillRect(cgContext, macRect);
+
+ float x = macRect.origin.x, y = macRect.origin.y;
+ float w = macRect.size.width, h = macRect.size.height;
+ SetCGContextFillColor(cgContext, kListboxTopBorderColor);
+ CGContextFillRect(cgContext, CGRectMake(x, y, w, 1));
+ SetCGContextFillColor(cgContext, kListBoxSidesAndBottomBorderColor);
+ CGContextFillRect(cgContext, CGRectMake(x, y + 1, 1, h - 1));
+ CGContextFillRect(cgContext, CGRectMake(x + w - 1, y + 1, 1, h - 1));
+ CGContextFillRect(cgContext, CGRectMake(x + 1, y + h - 1, w - 2, 1));
+ break;
+ }
+ case Widget::eSourceList: {
+ bool isInActiveWindow = widgetInfo->Params<bool>();
+ DrawSourceList(cgContext, macRect, isInActiveWindow);
+ break;
+ }
+ case Widget::eActiveSourceListSelection:
+ case Widget::eInactiveSourceListSelection: {
+ bool isInActiveWindow = widgetInfo->Params<bool>();
+ BOOL isActiveSelection =
+ widgetInfo->Widget() == Widget::eActiveSourceListSelection;
+ RenderWithCoreUI(macRect, cgContext,
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithBool:isActiveSelection], @"focus",
+ [NSNumber numberWithBool:YES], @"is.flipped",
+ @"kCUIVariantGradientSideBarSelection", @"kCUIVariantKey",
+ (isInActiveWindow ? @"normal" : @"inactive"), @"state",
+ @"gradient", @"widget",
+ nil]);
+ break;
+ }
+ case Widget::eTabPanel: {
+ bool isInsideActiveWindow = widgetInfo->Params<bool>();
+ DrawTabPanel(cgContext, macRect, isInsideActiveWindow);
+ break;
+ }
+ case Widget::eResizer: {
+ bool isRTL = widgetInfo->Params<bool>();
+ DrawResizer(cgContext, macRect, isRTL);
+ break;
+ }
+ }
+ }
+
if (hidpi) {
// Reset the base CTM.
CGContextSetBaseCTM(cgContext, CGAffineTransformIdentity);
}
nativeDrawing.EndNativeDrawing();
return NS_OK;