Commit 8afd43ee authored by Mason Freed's avatar Mason Freed Committed by Commit Bot

Remove LayoutThemeMac and ThemePainterMac

These two were used only for pre-FormControlsRefresh, and are no
longer needed. This CL renames the prior LayoutThemeMacRefresh,
which is the replacement, over to LayoutThemeMac.

This CL removes ~2700 lines of dead code. :-)

Fixed: 846357
Change-Id: If8f463c66c4366b66334ed0a7cb7660395139fb7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2360314
Auto-Submit: Mason Freed <masonfreed@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Commit-Queue: Mason Freed <masonfreed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799191}
parent d5699bb4
...@@ -24,21 +24,18 @@ ...@@ -24,21 +24,18 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_MAC_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_MAC_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_MAC_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_THEME_MAC_H_
#import <AppKit/AppKit.h>
#include "base/mac/scoped_nsobject.h"
#import "third_party/blink/renderer/core/layout/layout_theme.h" #import "third_party/blink/renderer/core/layout/layout_theme.h"
#import "third_party/blink/renderer/core/paint/theme_painter_mac.h" #import "third_party/blink/renderer/core/layout/layout_theme_default.h"
@class BlinkLayoutThemeNotificationObserver;
namespace blink { namespace blink {
class LayoutThemeMac final : public LayoutTheme { class File;
public:
static scoped_refptr<LayoutTheme> Create();
bool IsControlStyled(ControlPart part, const ComputedStyle&) const override; class LayoutThemeMac final : public LayoutThemeDefault {
public:
static scoped_refptr<LayoutTheme> Create() {
return base::AdoptRef(new LayoutThemeMac());
}
Color PlatformActiveSelectionBackgroundColor( Color PlatformActiveSelectionBackgroundColor(
WebColorScheme color_scheme) const override; WebColorScheme color_scheme) const override;
...@@ -46,237 +43,18 @@ class LayoutThemeMac final : public LayoutTheme { ...@@ -46,237 +43,18 @@ class LayoutThemeMac final : public LayoutTheme {
WebColorScheme color_scheme) const override; WebColorScheme color_scheme) const override;
Color PlatformActiveSelectionForegroundColor( Color PlatformActiveSelectionForegroundColor(
WebColorScheme color_scheme) const override; WebColorScheme color_scheme) const override;
Color PlatformActiveListBoxSelectionBackgroundColor(
WebColorScheme color_scheme) const override;
Color PlatformActiveListBoxSelectionForegroundColor(
WebColorScheme color_scheme) const override;
Color PlatformInactiveListBoxSelectionBackgroundColor(
WebColorScheme color_scheme) const override;
Color PlatformInactiveListBoxSelectionForegroundColor(
WebColorScheme color_scheme) const override;
Color PlatformSpellingMarkerUnderlineColor() const override; Color PlatformSpellingMarkerUnderlineColor() const override;
Color PlatformGrammarMarkerUnderlineColor() const override; Color PlatformGrammarMarkerUnderlineColor() const override;
Color PlatformFocusRingColor() const override; Color FocusRingColor() const override;
String DisplayNameForFile(const File& file) const override;
// System fonts. bool PopsMenuByArrowKeys() const override;
void SystemFont(CSSValueID system_font_id, bool PopsMenuByReturnKey() const override;
FontSelectionValue& font_slope,
FontSelectionValue& font_weight,
float& font_size,
AtomicString& font_family) const override;
int MinimumMenuListSize(const ComputedStyle&) const override;
void AdjustSliderThumbSize(ComputedStyle&) const override;
IntSize SliderTickSize() const override;
int SliderTickOffsetFromTrackCenter() const override;
int PopupInternalPaddingStart(const ComputedStyle&) const override;
int PopupInternalPaddingEnd(LocalFrame*, const ComputedStyle&) const override;
int PopupInternalPaddingTop(const ComputedStyle&) const override;
int PopupInternalPaddingBottom(const ComputedStyle&) const override;
bool PopsMenuByArrowKeys() const override { return true; }
bool PopsMenuBySpaceKey() const final { return true; }
// Returns the repeat interval of the animation for the progress bar.
base::TimeDelta AnimationRepeatIntervalForProgressBar() const override;
// Returns the duration of the animation for the progress bar.
base::TimeDelta AnimationDurationForProgressBar() const override;
Color SystemColor(CSSValueID, WebColorScheme color_scheme) const override;
bool SupportsSelectionForegroundColors() const override { return false; } bool SupportsSelectionForegroundColors() const override { return false; }
bool IsModalColorChooser() const override { return false; }
protected: protected:
LayoutThemeMac(); // Controls color values returned from FocusRingColor().
~LayoutThemeMac() override;
void AdjustMenuListStyle(ComputedStyle&, Element*) const override;
void AdjustMenuListButtonStyle(ComputedStyle&, Element*) const override;
void AdjustSearchFieldStyle(ComputedStyle&) const override;
void AdjustSearchFieldCancelButtonStyle(ComputedStyle&) const override;
public:
// Constants and methods shared with ThemePainterMac
// Get the control size based off the font. Used by some of the controls (like
// buttons).
NSControlSize ControlSizeForFont(const ComputedStyle&) const;
NSControlSize ControlSizeForSystemFont(const ComputedStyle&) const;
void SetControlSize(NSCell*,
const IntSize* sizes,
const IntSize& min_size,
float zoom_level = 1.0f);
void SetSizeFromFont(ComputedStyle&, const IntSize* sizes) const;
IntSize SizeForFont(const ComputedStyle&, const IntSize* sizes) const;
IntSize SizeForSystemFont(const ComputedStyle&, const IntSize* sizes) const;
void SetFontFromControlSize(ComputedStyle&, NSControlSize) const;
void UpdateCheckedState(NSCell*, const Node*);
void UpdateEnabledState(NSCell*, const Node*);
void UpdateFocusedState(NSCell*, const Node*, const ComputedStyle&);
void UpdatePressedState(NSCell*, const Node*);
// Helpers for adjusting appearance and for painting
void SetPopupButtonCellState(const Node*,
const ComputedStyle&,
const IntRect&);
const IntSize* PopupButtonSizes() const;
const int* PopupButtonMargins() const;
const int* PopupButtonPadding(NSControlSize) const;
const IntSize* MenuListSizes() const;
const IntSize* SearchFieldSizes() const;
const IntSize* CancelButtonSizes() const;
void SetSearchCellState(const Node*, const ComputedStyle&, const IntRect&);
void SetSearchFieldSize(ComputedStyle&) const;
NSPopUpButtonCell* PopupButton() const;
NSSearchFieldCell* Search() const;
NSTextFieldCell* TextField() const;
// A view associated to the contained document. Subclasses may not have such a
// view and return a fake.
NSView* DocumentView() const;
void UpdateActiveState(NSCell*, const Node*);
// We estimate the animation rate of a Mac OS X progress bar is 33 fps.
// Hard code the value here because we haven't found API for it.
static constexpr base::TimeDelta kProgressAnimationFrameRate =
base::TimeDelta::FromMilliseconds(33);
// Mac OS X progress bar animation seems to have 256 frames.
static constexpr double kProgressAnimationNumFrames = 256;
static constexpr float kBaseFontSize = 11.0f;
static constexpr float kMenuListBaseArrowHeight = 4.0f;
static constexpr float kMenuListBaseArrowWidth = 5.0f;
static constexpr float kMenuListBaseSpaceBetweenArrows = 2.0f;
static const int kMenuListArrowPaddingStart = 4;
static const int kMenuListArrowPaddingEnd = 4;
static const int kSliderThumbWidth = 15;
static const int kSliderThumbHeight = 15;
static const int kSliderThumbShadowBlur = 1;
static const int kSliderThumbBorderWidth = 1;
static const int kSliderTrackWidth = 5;
static const int kSliderTrackBorderWidth = 1;
FontDescription ControlFont(ControlPart,
const FontDescription&,
float zoom_factor) const override;
LengthSize GetControlSize(ControlPart,
const FontDescription&,
const LengthSize&,
float zoom_factor) const override;
LengthSize MinimumControlSize(ControlPart,
const FontDescription&,
float zoom_factor,
const ComputedStyle& style) const override;
LengthBox ControlPadding(ControlPart,
const FontDescription&,
const Length& zoomed_box_top,
const Length& zoomed_box_right,
const Length& zoomed_box_bottom,
const Length& zoomed_box_left,
float zoom_factor) const override;
LengthBox ControlBorder(ControlPart,
const FontDescription&,
const LengthBox& zoomed_box,
float zoom_factor) const override;
bool ControlRequiresPreWhiteSpace(ControlPart part) const override {
return part == kPushButtonPart;
}
// Add visual overflow (e.g., the check on an OS X checkbox). The rect passed
// in is in zoomed coordinates so the inflation should take that into account
// and make sure the inflation amount is also scaled by the zoomFactor.
void AddVisualOverflowHelper(ControlPart,
ControlStates,
float zoom_factor,
IntRect& border_box) const;
// Adjust style as per platform selection.
void AdjustControlPartStyle(ComputedStyle&) override;
// Function for ThemePainter
static CORE_EXPORT IntRect InflateRect(const IntRect&,
const IntSize&,
const int* margins,
float zoom_level = 1.0f);
// Inflate an IntRect to account for its focus ring.
// TODO: Consider using computing the focus ring's bounds with
// -[NSCell focusRingMaskBoundsForFrame:inView:]).
static CORE_EXPORT IntRect InflateRectForFocusRing(const IntRect&);
static CORE_EXPORT LengthSize CheckboxSize(const FontDescription&,
const LengthSize& zoomed_size,
float zoom_factor);
static CORE_EXPORT NSButtonCell* Checkbox(ControlStates,
const IntRect& zoomed_rect,
float zoom_factor);
static CORE_EXPORT const IntSize* CheckboxSizes();
static CORE_EXPORT const int* CheckboxMargins(NSControlSize);
static CORE_EXPORT NSView* EnsuredView(const IntSize&);
static CORE_EXPORT const IntSize* RadioSizes();
static CORE_EXPORT const int* RadioMargins(NSControlSize);
static CORE_EXPORT LengthSize RadioSize(const FontDescription&,
const LengthSize& zoomed_size,
float zoom_factor);
static CORE_EXPORT NSButtonCell* Radio(ControlStates,
const IntRect& zoomed_rect,
float zoom_factor);
static CORE_EXPORT const IntSize* ButtonSizes();
static CORE_EXPORT const int* ButtonMargins(NSControlSize);
static CORE_EXPORT NSButtonCell* Button(ControlPart,
ControlStates,
const IntRect& zoomed_rect,
float zoom_factor);
static CORE_EXPORT NSControlSize
ControlSizeFromPixelSize(const IntSize* sizes,
const IntSize& min_zoomed_size,
float zoom_factor);
static CORE_EXPORT const IntSize* StepperSizes();
protected:
String ExtraFullscreenStyleSheet() override;
// Controls color values returned from platformFocusRingColor(). systemColor()
// will be used when false.
bool UsesTestModeFocusRingColor() const; bool UsesTestModeFocusRingColor() const;
bool IsAccentColorCustomized(WebColorScheme color_scheme) const;
bool ShouldUseFallbackTheme(const ComputedStyle&) const override;
void AdjustProgressBarBounds(ComputedStyle&) const override;
private:
const int* ProgressBarHeights() const;
const int* ProgressBarMargins(NSControlSize) const;
String DisplayNameForFile(const File& file) const override;
String ExtraDefaultStyleSheet() override;
bool ThemeDrawsFocusRing(const ComputedStyle&) const override;
ThemePainter& Painter() override { return painter_; }
mutable base::scoped_nsobject<NSPopUpButtonCell> popup_button_;
mutable base::scoped_nsobject<NSSearchFieldCell> search_;
mutable base::scoped_nsobject<NSTextFieldCell> text_field_;
base::scoped_nsobject<BlinkLayoutThemeNotificationObserver>
notification_observer_;
ThemePainterMac painter_;
}; };
} // namespace blink } // namespace blink
......
...@@ -20,171 +20,20 @@ ...@@ -20,171 +20,20 @@
#import "third_party/blink/renderer/core/layout/layout_theme_mac.h" #import "third_party/blink/renderer/core/layout/layout_theme_mac.h"
#import <AvailabilityMacros.h>
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <math.h>
#import "base/mac/mac_util.h" #import "third_party/blink/public/common/sandbox_support/sandbox_support_mac.h"
#import "third_party/blink/public/platform/mac/web_sandbox_support.h" #import "third_party/blink/public/platform/mac/web_sandbox_support.h"
#import "third_party/blink/public/platform/platform.h" #import "third_party/blink/public/platform/platform.h"
#import "third_party/blink/public/resources/grit/blink_resources.h"
#import "third_party/blink/public/strings/grit/blink_strings.h"
#import "third_party/blink/renderer/core/css_value_keywords.h"
#import "third_party/blink/renderer/core/fileapi/file.h" #import "third_party/blink/renderer/core/fileapi/file.h"
#import "third_party/blink/renderer/core/html_names.h" #import "third_party/blink/renderer/core/style/computed_style.h"
#import "third_party/blink/renderer/core/layout/layout_progress.h"
#import "third_party/blink/renderer/core/layout/layout_theme_default.h"
#import "third_party/blink/renderer/core/layout/layout_view.h"
#import "third_party/blink/renderer/core/style/shadow_list.h"
#import "third_party/blink/renderer/platform/data_resource_helper.h"
#import "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#import "third_party/blink/renderer/platform/mac/block_exceptions.h"
#import "third_party/blink/renderer/platform/mac/color_mac.h"
#import "third_party/blink/renderer/platform/mac/web_core_ns_cell_extras.h"
#import "third_party/blink/renderer/platform/runtime_enabled_features.h"
#import "third_party/blink/renderer/platform/web_test_support.h" #import "third_party/blink/renderer/platform/web_test_support.h"
#include "ui/base/ui_base_features.h" #import "ui/base/ui_base_features.h"
#include "ui/native_theme/native_theme.h" #import "ui/native_theme/native_theme.h"
// This is a view whose sole purpose is to tell AppKit that it's flipped.
@interface BlinkFlippedControl : NSControl
@end
@implementation BlinkFlippedControl
- (BOOL)isFlipped {
return YES;
}
- (NSText*)currentEditor {
return nil;
}
- (BOOL)_automaticFocusRingDisabled {
return YES;
}
@end
// The methods in this file are specific to the Mac OS X platform.
@interface BlinkLayoutThemeNotificationObserver : NSObject {
blink::LayoutTheme* _theme;
}
- (id)initWithTheme:(blink::LayoutTheme*)theme;
- (void)systemColorsDidChange:(NSNotification*)notification;
@end
@implementation BlinkLayoutThemeNotificationObserver
- (id)initWithTheme:(blink::LayoutTheme*)theme {
if (!(self = [super init]))
return nil;
_theme = theme;
return self;
}
- (void)systemColorsDidChange:(NSNotification*)unusedNotification {
DCHECK([[unusedNotification name]
isEqualToString:NSSystemColorsDidChangeNotification]);
_theme->PlatformColorsDidChange();
}
@end
@interface NSTextFieldCell (WKDetails)
- (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame
inView:(NSView*)controlView
includeFocus:(BOOL)includeFocus;
@end
@interface BlinkTextFieldCell : NSTextFieldCell
- (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame
inView:(NSView*)controlView
includeFocus:(BOOL)includeFocus;
@end
@implementation BlinkTextFieldCell
- (CFDictionaryRef)_coreUIDrawOptionsWithFrame:(NSRect)cellFrame
inView:(NSView*)controlView
includeFocus:(BOOL)includeFocus {
// FIXME: This is a post-Lion-only workaround for <rdar://problem/11385461>.
// When that bug is resolved, we should remove this code.
CFMutableDictionaryRef coreUIDrawOptions = CFDictionaryCreateMutableCopy(
NULL, 0, [super _coreUIDrawOptionsWithFrame:cellFrame
inView:controlView
includeFocus:includeFocus]);
CFDictionarySetValue(coreUIDrawOptions, @"borders only", kCFBooleanTrue);
return (CFDictionaryRef)[NSMakeCollectable(coreUIDrawOptions) autorelease];
}
@end
@interface BlinkFlippedView : NSView
@end
@implementation BlinkFlippedView
- (BOOL)isFlipped {
return YES;
}
- (NSText*)currentEditor {
return nil;
}
@end
namespace blink { namespace blink {
namespace { namespace {
class LayoutThemeMacRefresh final : public LayoutThemeDefault {
public:
static scoped_refptr<LayoutTheme> Create() {
return base::AdoptRef(new LayoutThemeMacRefresh());
}
Color PlatformActiveSelectionBackgroundColor(
WebColorScheme color_scheme) const override;
Color PlatformInactiveSelectionBackgroundColor(
WebColorScheme color_scheme) const override;
Color PlatformActiveSelectionForegroundColor(
WebColorScheme color_scheme) const override;
Color PlatformSpellingMarkerUnderlineColor() const override;
Color PlatformGrammarMarkerUnderlineColor() const override;
Color FocusRingColor() const override;
String DisplayNameForFile(const File& file) const override {
if (file.GetUserVisibility() == File::kIsUserVisible)
return [[NSFileManager defaultManager] displayNameAtPath:file.GetPath()];
return file.name();
}
bool PopsMenuByArrowKeys() const override;
bool PopsMenuByReturnKey() const override;
bool SupportsSelectionForegroundColors() const override { return false; }
protected:
// Controls color values returned from FocusRingColor().
bool UsesTestModeFocusRingColor() const;
bool IsAccentColorCustomized(WebColorScheme color_scheme) const;
};
// Inflate an IntRect to account for specific padding around margins.
enum { kTopMargin = 0, kRightMargin = 1, kBottomMargin = 2, kLeftMargin = 3 };
bool FontSizeMatchesToControlSize(const ComputedStyle& style) {
int font_size = style.FontSize();
if (font_size == [NSFont systemFontSizeForControlSize:NSRegularControlSize])
return true;
if (font_size == [NSFont systemFontSizeForControlSize:NSSmallControlSize])
return true;
if (font_size == [NSFont systemFontSizeForControlSize:NSMiniControlSize])
return true;
return false;
}
Color GetSystemColor(MacSystemColorID color_id, WebColorScheme color_scheme) { Color GetSystemColor(MacSystemColorID color_id, WebColorScheme color_scheme) {
// In tests, a WebSandboxSupport may not be set up. Just return a dummy // In tests, a WebSandboxSupport may not be set up. Just return a dummy
// color, in this case, black. // color, in this case, black.
...@@ -193,57 +42,12 @@ Color GetSystemColor(MacSystemColorID color_id, WebColorScheme color_scheme) { ...@@ -193,57 +42,12 @@ Color GetSystemColor(MacSystemColorID color_id, WebColorScheme color_scheme) {
return Color(); return Color();
return sandbox_support->GetSystemColor(color_id, color_scheme); return sandbox_support->GetSystemColor(color_id, color_scheme);
} }
// Helper functions used by a bunch of different control parts.
NSControlSize ControlSizeForFont(const FontDescription& font_description) {
int font_size = font_description.ComputedPixelSize();
if (font_size >= 16)
return NSRegularControlSize;
if (font_size >= 11)
return NSSmallControlSize;
return NSMiniControlSize;
}
LengthSize SizeFromNSControlSize(NSControlSize ns_control_size,
const LengthSize& zoomed_size,
float zoom_factor,
const IntSize* sizes) {
IntSize control_size = sizes[ns_control_size];
if (zoom_factor != 1.0f)
control_size = IntSize(control_size.Width() * zoom_factor,
control_size.Height() * zoom_factor);
LengthSize result = zoomed_size;
if (zoomed_size.Width().IsIntrinsicOrAuto() && control_size.Width() > 0)
result.SetWidth(Length::Fixed(control_size.Width()));
if (zoomed_size.Height().IsIntrinsicOrAuto() && control_size.Height() > 0)
result.SetHeight(Length::Fixed(control_size.Height()));
return result;
}
LengthSize SizeFromFont(const FontDescription& font_description,
const LengthSize& zoomed_size,
float zoom_factor,
const IntSize* sizes) {
return SizeFromNSControlSize(ControlSizeForFont(font_description),
zoomed_size, zoom_factor, sizes);
}
} // namespace
LayoutThemeMac::LayoutThemeMac()
: LayoutTheme(),
notification_observer_(
[[BlinkLayoutThemeNotificationObserver alloc] initWithTheme:this]),
painter_(*this) {
[[NSNotificationCenter defaultCenter]
addObserver:notification_observer_
selector:@selector(systemColorsDidChange:)
name:NSSystemColorsDidChangeNotification
object:nil];
} }
LayoutThemeMac::~LayoutThemeMac() { String LayoutThemeMac::DisplayNameForFile(const File& file) const {
[[NSNotificationCenter defaultCenter] removeObserver:notification_observer_]; if (file.GetUserVisibility() == File::kIsUserVisible)
return [[NSFileManager defaultManager] displayNameAtPath:file.GetPath()];
return file.name();
} }
Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor( Color LayoutThemeMac::PlatformActiveSelectionBackgroundColor(
...@@ -263,22 +67,6 @@ Color LayoutThemeMac::PlatformActiveSelectionForegroundColor( ...@@ -263,22 +67,6 @@ Color LayoutThemeMac::PlatformActiveSelectionForegroundColor(
return Color::kBlack; return Color::kBlack;
} }
Color LayoutThemeMac::PlatformActiveListBoxSelectionBackgroundColor(
WebColorScheme color_scheme) const {
return GetSystemColor(MacSystemColorID::kAlternateSelectedControl,
color_scheme);
}
Color LayoutThemeMac::PlatformActiveListBoxSelectionForegroundColor(
WebColorScheme color_scheme) const {
return Color::kWhite;
}
Color LayoutThemeMac::PlatformInactiveListBoxSelectionForegroundColor(
WebColorScheme color_scheme) const {
return Color::kBlack;
}
Color LayoutThemeMac::PlatformSpellingMarkerUnderlineColor() const { Color LayoutThemeMac::PlatformSpellingMarkerUnderlineColor() const {
return Color(251, 45, 29); return Color(251, 45, 29);
} }
...@@ -287,47 +75,7 @@ Color LayoutThemeMac::PlatformGrammarMarkerUnderlineColor() const { ...@@ -287,47 +75,7 @@ Color LayoutThemeMac::PlatformGrammarMarkerUnderlineColor() const {
return Color(107, 107, 107); return Color(107, 107, 107);
} }
Color LayoutThemeMac::PlatformFocusRingColor() const { bool LayoutThemeMac::IsAccentColorCustomized(
static const RGBA32 kOldAquaFocusRingColor = 0xFF7DADD9;
if (UsesTestModeFocusRingColor())
return kOldAquaFocusRingColor;
// TODO(crbug.com/929098) Need to pass an appropriate color scheme here.
return SystemColor(CSSValueID::kWebkitFocusRingColor,
ComputedStyle::InitialStyle().UsedColorScheme());
}
Color LayoutThemeMac::PlatformInactiveListBoxSelectionBackgroundColor(
WebColorScheme color_scheme) const {
return PlatformInactiveSelectionBackgroundColor(color_scheme);
}
Color LayoutThemeMacRefresh::PlatformActiveSelectionBackgroundColor(
WebColorScheme color_scheme) const {
return GetSystemColor(MacSystemColorID::kSelectedTextBackground,
color_scheme);
}
Color LayoutThemeMacRefresh::PlatformInactiveSelectionBackgroundColor(
WebColorScheme color_scheme) const {
return GetSystemColor(MacSystemColorID::kSecondarySelectedControl,
color_scheme);
}
Color LayoutThemeMacRefresh::PlatformActiveSelectionForegroundColor(
WebColorScheme color_scheme) const {
return Color::kBlack;
}
Color LayoutThemeMacRefresh::PlatformSpellingMarkerUnderlineColor() const {
return Color(251, 45, 29);
}
Color LayoutThemeMacRefresh::PlatformGrammarMarkerUnderlineColor() const {
return Color(107, 107, 107);
}
bool LayoutThemeMacRefresh::IsAccentColorCustomized(
WebColorScheme color_scheme) const { WebColorScheme color_scheme) const {
if (@available(macOS 10.14, *)) { if (@available(macOS 10.14, *)) {
static const Color kControlBlueAccentColor = static const Color kControlBlueAccentColor =
...@@ -347,7 +95,7 @@ bool LayoutThemeMacRefresh::IsAccentColorCustomized( ...@@ -347,7 +95,7 @@ bool LayoutThemeMacRefresh::IsAccentColorCustomized(
return true; return true;
} }
Color LayoutThemeMacRefresh::FocusRingColor() const { Color LayoutThemeMac::FocusRingColor() const {
static const RGBA32 kDefaultFocusRingColor = 0xFF101010; static const RGBA32 kDefaultFocusRingColor = 0xFF101010;
if (UsesTestModeFocusRingColor()) { if (UsesTestModeFocusRingColor()) {
return HasCustomFocusRingColor() ? GetCustomFocusRingColor() return HasCustomFocusRingColor() ? GetCustomFocusRingColor()
...@@ -377,1258 +125,22 @@ Color LayoutThemeMacRefresh::FocusRingColor() const { ...@@ -377,1258 +125,22 @@ Color LayoutThemeMacRefresh::FocusRingColor() const {
return focus_ring; return focus_ring;
} }
bool LayoutThemeMacRefresh::UsesTestModeFocusRingColor() const { bool LayoutThemeMac::UsesTestModeFocusRingColor() const {
return WebTestSupport::IsRunningWebTest(); return WebTestSupport::IsRunningWebTest();
} }
bool LayoutThemeMacRefresh::PopsMenuByArrowKeys() const { bool LayoutThemeMac::PopsMenuByArrowKeys() const {
return true; return true;
} }
bool LayoutThemeMacRefresh::PopsMenuByReturnKey() const { bool LayoutThemeMac::PopsMenuByReturnKey() const {
return false; return false;
} }
static FontSelectionValue ToFontWeight(NSInteger app_kit_font_weight) {
DCHECK_GT(app_kit_font_weight, 0);
DCHECK_LT(app_kit_font_weight, 15);
if (app_kit_font_weight > 14)
app_kit_font_weight = 14;
else if (app_kit_font_weight < 1)
app_kit_font_weight = 1;
static FontSelectionValue font_weights[] = {
FontSelectionValue(100), FontSelectionValue(100), FontSelectionValue(200),
FontSelectionValue(300), FontSelectionValue(400), FontSelectionValue(500),
FontSelectionValue(600), FontSelectionValue(600), FontSelectionValue(700),
FontSelectionValue(800), FontSelectionValue(800), FontSelectionValue(900),
FontSelectionValue(900), FontSelectionValue(900)};
return font_weights[app_kit_font_weight - 1];
}
static inline NSFont* SystemNSFont(CSSValueID system_font_id) {
switch (system_font_id) {
case CSSValueID::kSmallCaption:
return [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
case CSSValueID::kMenu:
return [NSFont menuFontOfSize:[NSFont systemFontSize]];
case CSSValueID::kStatusBar:
return [NSFont labelFontOfSize:[NSFont labelFontSize]];
case CSSValueID::kWebkitMiniControl:
return [NSFont
systemFontOfSize:[NSFont
systemFontSizeForControlSize:NSMiniControlSize]];
case CSSValueID::kWebkitSmallControl:
return [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:
NSSmallControlSize]];
case CSSValueID::kWebkitControl:
return [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:
NSRegularControlSize]];
default:
return [NSFont systemFontOfSize:[NSFont systemFontSize]];
}
}
void LayoutThemeMac::SystemFont(CSSValueID system_font_id,
FontSelectionValue& font_slope,
FontSelectionValue& font_weight,
float& font_size,
AtomicString& font_family) const {
NSFont* font = SystemNSFont(system_font_id);
if (!font)
return;
NSFontManager* font_manager = [NSFontManager sharedFontManager];
font_slope = ([font_manager traitsOfFont:font] & NSItalicFontMask)
? ItalicSlopeValue()
: NormalSlopeValue();
font_weight = ToFontWeight([font_manager weightOfFont:font]);
font_size = [font pointSize];
font_family = font_family_names::kSystemUi;
}
Color LayoutThemeMac::SystemColor(CSSValueID css_value_id,
WebColorScheme color_scheme) const {
if (!Platform::Current()->GetSandboxSupport())
return LayoutTheme::SystemColor(css_value_id, color_scheme);
switch (css_value_id) {
case CSSValueID::kActiveborder:
return GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator,
color_scheme);
case CSSValueID::kActivecaption:
return GetSystemColor(MacSystemColorID::kWindowFrameText, color_scheme);
case CSSValueID::kAppworkspace:
return GetSystemColor(MacSystemColorID::kHeader, color_scheme);
case CSSValueID::kBackground:
// Use theme independent default.
break;
case CSSValueID::kButtonface:
return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kButtonhighlight:
return GetSystemColor(MacSystemColorID::kControlHighlight, color_scheme);
case CSSValueID::kButtonshadow:
return GetSystemColor(MacSystemColorID::kControlShadow, color_scheme);
case CSSValueID::kButtontext:
return GetSystemColor(MacSystemColorID::kControlText, color_scheme);
case CSSValueID::kCaptiontext:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kField:
return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kFieldtext:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kGraytext:
return GetSystemColor(MacSystemColorID::kDisabledControlText,
color_scheme);
case CSSValueID::kHighlight:
return GetSystemColor(MacSystemColorID::kSelectedTextBackground,
color_scheme);
case CSSValueID::kHighlighttext:
return GetSystemColor(MacSystemColorID::kSelectedText, color_scheme);
case CSSValueID::kInactiveborder:
return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kInactivecaption:
return GetSystemColor(MacSystemColorID::kControlBackground, color_scheme);
case CSSValueID::kInactivecaptiontext:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kInfobackground:
// There is no corresponding NSColor for this so we use a hard coded
// value.
return 0xFFFBFCC5;
case CSSValueID::kInfotext:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kMenu:
return GetSystemColor(MacSystemColorID::kMenuBackground, color_scheme);
case CSSValueID::kMenutext:
return GetSystemColor(MacSystemColorID::kSelectedMenuItemText,
color_scheme);
case CSSValueID::kScrollbar:
return GetSystemColor(MacSystemColorID::kScrollBar, color_scheme);
case CSSValueID::kText:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
case CSSValueID::kThreeddarkshadow:
return GetSystemColor(MacSystemColorID::kControlDarkShadow, color_scheme);
case CSSValueID::kThreedshadow:
return GetSystemColor(MacSystemColorID::kShadow, color_scheme);
case CSSValueID::kThreedface:
// We use this value instead of NSColor's controlColor to avoid website
// incompatibilities. We may want to change this to use the NSColor in
// future.
return 0xFFC0C0C0;
case CSSValueID::kThreedhighlight:
return GetSystemColor(MacSystemColorID::kHighlight, color_scheme);
case CSSValueID::kThreedlightshadow:
return GetSystemColor(MacSystemColorID::kControlLightHighlight,
color_scheme);
case CSSValueID::kWebkitFocusRingColor:
return GetSystemColor(MacSystemColorID::kKeyboardFocusIndicator,
color_scheme);
case CSSValueID::kWindow:
case CSSValueID::kCanvas:
return GetSystemColor(MacSystemColorID::kWindowBackground, color_scheme);
case CSSValueID::kWindowframe:
return GetSystemColor(MacSystemColorID::kWindowFrame, color_scheme);
case CSSValueID::kWindowtext:
return GetSystemColor(MacSystemColorID::kWindowFrameText, color_scheme);
case CSSValueID::kCanvastext:
return GetSystemColor(MacSystemColorID::kText, color_scheme);
default:
break;
}
return LayoutTheme::SystemColor(css_value_id, color_scheme);
}
bool LayoutThemeMac::IsControlStyled(ControlPart part,
const ComputedStyle& style) const {
if (part == kTextFieldPart || part == kTextAreaPart)
return style.HasAuthorBorder() || style.BoxShadow();
if (part == kMenulistPart) {
// FIXME: This is horrible, but there is not much else that can be done.
// Menu lists cannot draw properly when scaled. They can't really draw
// properly when transformed either. We can't detect the transform case
// at style adjustment time so that will just have to stay broken. We
// can however detect that we're zooming. If zooming is in effect we
// treat it like the control is styled.
if (style.EffectiveZoom() != 1.0f)
return true;
if (!FontSizeMatchesToControlSize(style))
return true;
if (style.GetFontDescription().Family().Family() !=
font_family_names::kSystemUi)
return true;
if (!style.Height().IsIntrinsicOrAuto())
return true;
}
// Some other cells don't work well when scaled.
if (style.EffectiveZoom() != 1) {
switch (part) {
case kButtonPart:
case kPushButtonPart:
case kSearchFieldPart:
case kSquareButtonPart:
return true;
default:
break;
}
}
return LayoutTheme::IsControlStyled(part, style);
}
void LayoutThemeMac::UpdateCheckedState(NSCell* cell, const Node* node) {
bool old_indeterminate = [cell state] == NSMixedState;
bool indeterminate = IsIndeterminate(node);
bool checked = IsChecked(node);
if (old_indeterminate != indeterminate) {
[cell setState:indeterminate ? NSMixedState
: (checked ? NSOnState : NSOffState)];
return;
}
bool old_checked = [cell state] == NSOnState;
if (checked != old_checked)
[cell setState:checked ? NSOnState : NSOffState];
}
void LayoutThemeMac::UpdateEnabledState(NSCell* cell, const Node* node) {
bool old_enabled = [cell isEnabled];
bool enabled = IsEnabled(node);
if (enabled != old_enabled)
[cell setEnabled:enabled];
}
void LayoutThemeMac::UpdateFocusedState(NSCell* cell,
const Node* node,
const ComputedStyle& style) {
bool old_focused = [cell showsFirstResponder];
bool focused = IsFocused(node) && style.OutlineStyleIsAuto();
if (focused != old_focused)
[cell setShowsFirstResponder:focused];
}
void LayoutThemeMac::UpdatePressedState(NSCell* cell, const Node* node) {
bool old_pressed = [cell isHighlighted];
bool pressed = node && node->IsActive();
if (pressed != old_pressed)
[cell setHighlighted:pressed];
}
NSControlSize LayoutThemeMac::ControlSizeForFont(
const ComputedStyle& style) const {
int font_size = style.FontSize();
if (font_size >= 16)
return NSRegularControlSize;
if (font_size >= 11)
return NSSmallControlSize;
return NSMiniControlSize;
}
void LayoutThemeMac::SetControlSize(NSCell* cell,
const IntSize* sizes,
const IntSize& min_size,
float zoom_level) {
NSControlSize size;
if (min_size.Width() >=
static_cast<int>(sizes[NSRegularControlSize].Width() * zoom_level) &&
min_size.Height() >=
static_cast<int>(sizes[NSRegularControlSize].Height() * zoom_level))
size = NSRegularControlSize;
else if (min_size.Width() >=
static_cast<int>(sizes[NSSmallControlSize].Width() *
zoom_level) &&
min_size.Height() >=
static_cast<int>(sizes[NSSmallControlSize].Height() *
zoom_level))
size = NSSmallControlSize;
else
size = NSMiniControlSize;
// Only update if we have to, since AppKit does work even if the size is the
// same.
if (size != [cell controlSize])
[cell setControlSize:size];
}
IntSize LayoutThemeMac::SizeForFont(const ComputedStyle& style,
const IntSize* sizes) const {
if (style.EffectiveZoom() != 1.0f) {
IntSize result = sizes[ControlSizeForFont(style)];
return IntSize(result.Width() * style.EffectiveZoom(),
result.Height() * style.EffectiveZoom());
}
return sizes[ControlSizeForFont(style)];
}
IntSize LayoutThemeMac::SizeForSystemFont(const ComputedStyle& style,
const IntSize* sizes) const {
if (style.EffectiveZoom() != 1.0f) {
IntSize result = sizes[ControlSizeForSystemFont(style)];
return IntSize(result.Width() * style.EffectiveZoom(),
result.Height() * style.EffectiveZoom());
}
return sizes[ControlSizeForSystemFont(style)];
}
void LayoutThemeMac::SetSizeFromFont(ComputedStyle& style,
const IntSize* sizes) const {
// FIXME: Check is flawed, since it doesn't take min-width/max-width into
// account.
IntSize size = SizeForFont(style, sizes);
if (style.Width().IsIntrinsicOrAuto() && size.Width() > 0)
style.SetWidth(Length::Fixed(size.Width()));
if (style.Height().IsAuto() && size.Height() > 0)
style.SetHeight(Length::Fixed(size.Height()));
}
void LayoutThemeMac::SetFontFromControlSize(ComputedStyle& style,
NSControlSize control_size) const {
FontDescription font_description;
font_description.SetIsAbsoluteSize(true);
font_description.SetGenericFamily(FontDescription::kSerifFamily);
NSFont* font = [NSFont
systemFontOfSize:[NSFont systemFontSizeForControlSize:control_size]];
font_description.FirstFamily().SetFamily(font_family_names::kSystemUi);
font_description.SetComputedSize([font pointSize] * style.EffectiveZoom());
font_description.SetSpecifiedSize([font pointSize] * style.EffectiveZoom());
// Reset line height.
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
style.SetFontDescription(font_description);
}
NSControlSize LayoutThemeMac::ControlSizeForSystemFont(
const ComputedStyle& style) const {
float font_size = style.FontSize();
float zoom_level = style.EffectiveZoom();
if (zoom_level != 1)
font_size /= zoom_level;
if (font_size >= [NSFont systemFontSizeForControlSize:NSRegularControlSize])
return NSRegularControlSize;
if (font_size >= [NSFont systemFontSizeForControlSize:NSSmallControlSize])
return NSSmallControlSize;
return NSMiniControlSize;
}
const int* LayoutThemeMac::PopupButtonMargins() const {
static const int kMargins[3][4] = {{0, 3, 1, 3}, {0, 3, 2, 3}, {0, 1, 0, 1}};
return kMargins[[PopupButton() controlSize]];
}
const IntSize* LayoutThemeMac::PopupButtonSizes() const {
static const IntSize kSizes[3] = {IntSize(0, 21), IntSize(0, 18),
IntSize(0, 15)};
return kSizes;
}
const int* LayoutThemeMac::PopupButtonPadding(NSControlSize size) const {
static const int kPadding[3][4] = {
{2, 26, 3, 8}, {2, 23, 3, 8}, {2, 22, 3, 10}};
return kPadding[size];
}
const int* LayoutThemeMac::ProgressBarHeights() const {
static const int kSizes[3] = {20, 12, 12};
return kSizes;
}
constexpr base::TimeDelta LayoutThemeMac::kProgressAnimationFrameRate;
base::TimeDelta LayoutThemeMac::AnimationRepeatIntervalForProgressBar() const {
return kProgressAnimationFrameRate;
}
base::TimeDelta LayoutThemeMac::AnimationDurationForProgressBar() const {
return kProgressAnimationNumFrames * kProgressAnimationFrameRate;
}
static const IntSize* MenuListButtonSizes() {
static const IntSize kSizes[3] = {IntSize(0, 21), IntSize(0, 18),
IntSize(0, 15)};
return kSizes;
}
void LayoutThemeMac::AdjustMenuListStyle(ComputedStyle& style,
Element* e) const {
LayoutTheme::AdjustMenuListStyle(style, e);
NSControlSize control_size = ControlSizeForFont(style);
style.ResetBorder();
style.ResetPadding();
// Height is locked to auto.
style.SetHeight(Length::Auto());
// White-space is locked to pre.
style.SetWhiteSpace(EWhiteSpace::kPre);
// Set the foreground color to black or gray when we have the aqua look.
StyleColor color(e && !e->IsDisabledFormControl() ? Color::kBlack
: Color::kDarkGray);
style.SetColor(color);
// Set the button's vertical size.
SetSizeFromFont(style, MenuListButtonSizes());
// Our font is locked to the appropriate system font size for the
// control. To clarify, we first use the CSS-specified font to figure out a
// reasonable control size, but once that control size is determined, we
// throw that font away and use the appropriate system font for the control
// size instead.
SetFontFromControlSize(style, control_size);
}
static const int kBaseBorderRadius = 5;
static const int kStyledPopupPaddingStart = 8;
static const int kStyledPopupPaddingTop = 1;
static const int kStyledPopupPaddingBottom = 2;
// These functions are called with MenuListPart or MenulistButtonPart appearance
// by LayoutMenuList.
int LayoutThemeMac::PopupInternalPaddingStart(
const ComputedStyle& style) const {
if (style.EffectiveAppearance() == kMenulistPart)
return PopupButtonPadding(ControlSizeForFont(style))[kLeftMargin] *
style.EffectiveZoom();
if (style.EffectiveAppearance() == kMenulistButtonPart)
return kStyledPopupPaddingStart * style.EffectiveZoom();
return 0;
}
int LayoutThemeMac::PopupInternalPaddingEnd(LocalFrame*,
const ComputedStyle& style) const {
if (style.EffectiveAppearance() == kMenulistPart)
return PopupButtonPadding(ControlSizeForFont(style))[kRightMargin] *
style.EffectiveZoom();
if (style.EffectiveAppearance() != kMenulistButtonPart)
return 0;
float font_scale = style.FontSize() / kBaseFontSize;
float arrow_width = kMenuListBaseArrowWidth * font_scale;
return static_cast<int>(ceilf(
arrow_width + (kMenuListArrowPaddingStart + kMenuListArrowPaddingEnd) *
style.EffectiveZoom()));
}
int LayoutThemeMac::PopupInternalPaddingTop(const ComputedStyle& style) const {
if (style.EffectiveAppearance() == kMenulistPart)
return PopupButtonPadding(ControlSizeForFont(style))[kTopMargin] *
style.EffectiveZoom();
if (style.EffectiveAppearance() == kMenulistButtonPart)
return kStyledPopupPaddingTop * style.EffectiveZoom();
return 0;
}
int LayoutThemeMac::PopupInternalPaddingBottom(
const ComputedStyle& style) const {
if (style.EffectiveAppearance() == kMenulistPart)
return PopupButtonPadding(ControlSizeForFont(style))[kBottomMargin] *
style.EffectiveZoom();
if (style.EffectiveAppearance() == kMenulistButtonPart)
return kStyledPopupPaddingBottom * style.EffectiveZoom();
return 0;
}
void LayoutThemeMac::AdjustMenuListButtonStyle(ComputedStyle& style,
Element*) const {
float font_scale = style.FontSize() / kBaseFontSize;
style.ResetPadding();
style.SetBorderRadius(
IntSize(int(kBaseBorderRadius + font_scale - 1),
int(kBaseBorderRadius + font_scale - 1))); // FIXME: Round up?
const int kMinHeight = 15;
style.SetMinHeight(Length::Fixed(kMinHeight));
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
}
void LayoutThemeMac::SetPopupButtonCellState(const Node* node,
const ComputedStyle& style,
const IntRect& rect) {
NSPopUpButtonCell* popup_button = this->PopupButton();
// Set the control size based off the rectangle we're painting into.
SetControlSize(popup_button, PopupButtonSizes(), rect.Size(),
style.EffectiveZoom());
// Update the various states we respond to.
UpdateActiveState(popup_button, node);
UpdateCheckedState(popup_button, node);
UpdateEnabledState(popup_button, node);
UpdatePressedState(popup_button, node);
popup_button.userInterfaceLayoutDirection =
style.Direction() == TextDirection::kLtr
? NSUserInterfaceLayoutDirectionLeftToRight
: NSUserInterfaceLayoutDirectionRightToLeft;
}
const IntSize* LayoutThemeMac::MenuListSizes() const {
static const IntSize kSizes[3] = {IntSize(9, 0), IntSize(5, 0),
IntSize(0, 0)};
return kSizes;
}
int LayoutThemeMac::MinimumMenuListSize(const ComputedStyle& style) const {
return SizeForSystemFont(style, MenuListSizes()).Width();
}
void LayoutThemeMac::SetSearchCellState(const Node* node,
const ComputedStyle& style,
const IntRect&) {
NSSearchFieldCell* search = this->Search();
// Update the various states we respond to.
UpdateActiveState(search, node);
UpdateEnabledState(search, node);
UpdateFocusedState(search, node, style);
}
const IntSize* LayoutThemeMac::SearchFieldSizes() const {
static const IntSize kSizes[3] = {IntSize(0, 22), IntSize(0, 19),
IntSize(0, 15)};
return kSizes;
}
static const int* SearchFieldHorizontalPaddings() {
static const int kSizes[3] = {3, 2, 1};
return kSizes;
}
void LayoutThemeMac::SetSearchFieldSize(ComputedStyle& style) const {
// If the width and height are both specified, then we have nothing to do.
if (!style.Width().IsIntrinsicOrAuto() && !style.Height().IsAuto())
return;
// Use the font size to determine the intrinsic width of the control.
SetSizeFromFont(style, SearchFieldSizes());
}
const uint8_t kSearchFieldBorderWidth = 2;
void LayoutThemeMac::AdjustSearchFieldStyle(ComputedStyle& style) const {
// Override border.
style.ResetBorder();
const float border_width = kSearchFieldBorderWidth * style.EffectiveZoom();
style.SetBorderLeftWidth(border_width);
style.SetBorderLeftStyle(EBorderStyle::kInset);
style.SetBorderRightWidth(border_width);
style.SetBorderRightStyle(EBorderStyle::kInset);
style.SetBorderBottomWidth(border_width);
style.SetBorderBottomStyle(EBorderStyle::kInset);
style.SetBorderTopWidth(border_width);
style.SetBorderTopStyle(EBorderStyle::kInset);
// Override height.
style.SetHeight(Length::Auto());
SetSearchFieldSize(style);
NSControlSize control_size = ControlSizeForFont(style);
// Override padding size to match AppKit text positioning.
const int vertical_padding = 1 * style.EffectiveZoom();
const int horizontal_padding =
SearchFieldHorizontalPaddings()[control_size] * style.EffectiveZoom();
style.SetPaddingLeft(Length::Fixed(horizontal_padding));
style.SetPaddingRight(Length::Fixed(horizontal_padding));
style.SetPaddingTop(Length::Fixed(vertical_padding));
style.SetPaddingBottom(Length::Fixed(vertical_padding));
SetFontFromControlSize(style, control_size);
style.SetBoxShadow(nullptr);
}
const IntSize* LayoutThemeMac::CancelButtonSizes() const {
static const IntSize kSizes[3] = {IntSize(14, 14), IntSize(11, 11),
IntSize(9, 9)};
return kSizes;
}
void LayoutThemeMac::AdjustSearchFieldCancelButtonStyle(
ComputedStyle& style) const {
IntSize size = SizeForSystemFont(style, CancelButtonSizes());
style.SetWidth(Length::Fixed(size.Width()));
style.SetHeight(Length::Fixed(size.Height()));
style.SetBoxShadow(nullptr);
}
IntSize LayoutThemeMac::SliderTickSize() const {
return IntSize(1, 3);
}
int LayoutThemeMac::SliderTickOffsetFromTrackCenter() const {
return -9;
}
void LayoutThemeMac::AdjustProgressBarBounds(ComputedStyle& style) const {
float zoom_level = style.EffectiveZoom();
NSControlSize control_size = ControlSizeForFont(style);
int height = ProgressBarHeights()[control_size] * zoom_level;
// Now inflate it to account for the shadow.
style.SetMinHeight(Length::Fixed(height + zoom_level));
}
void LayoutThemeMac::AdjustSliderThumbSize(ComputedStyle& style) const {
float zoom_level = style.EffectiveZoom();
if (style.EffectiveAppearance() == kSliderThumbHorizontalPart ||
style.EffectiveAppearance() == kSliderThumbVerticalPart) {
style.SetWidth(
Length::Fixed(static_cast<int>(kSliderThumbWidth * zoom_level)));
style.SetHeight(
Length::Fixed(static_cast<int>(kSliderThumbHeight * zoom_level)));
}
}
NSPopUpButtonCell* LayoutThemeMac::PopupButton() const {
if (!popup_button_) {
popup_button_.reset([[NSPopUpButtonCell alloc] initTextCell:@""
pullsDown:NO]);
[popup_button_ setUsesItemFromMenu:NO];
[popup_button_ setFocusRingType:NSFocusRingTypeExterior];
}
return popup_button_;
}
NSSearchFieldCell* LayoutThemeMac::Search() const {
if (!search_) {
search_.reset([[NSSearchFieldCell alloc] initTextCell:@""]);
[search_ setBezelStyle:NSTextFieldRoundedBezel];
[search_ setBezeled:YES];
[search_ setEditable:YES];
[search_ setFocusRingType:NSFocusRingTypeExterior];
// Suppress NSSearchFieldCell's default placeholder text. Prior to OS10.11,
// this is achieved by calling |setCenteredLook| with NO. In OS10.11 and
// later, instead call |setPlaceholderString| with an empty string.
// See https://crbug.com/752362.
if (base::mac::IsAtMostOS10_10()) {
SEL sel = @selector(setCenteredLook:);
if ([search_ respondsToSelector:sel]) {
BOOL bool_value = NO;
NSMethodSignature* signature =
[NSSearchFieldCell instanceMethodSignatureForSelector:sel];
NSInvocation* invocation =
[NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:search_];
[invocation setSelector:sel];
[invocation setArgument:&bool_value atIndex:2];
[invocation invoke];
}
} else {
[search_ setPlaceholderString:@""];
}
}
return search_;
}
NSTextFieldCell* LayoutThemeMac::TextField() const {
if (!text_field_) {
text_field_.reset([[BlinkTextFieldCell alloc] initTextCell:@""]);
[text_field_ setBezeled:YES];
[text_field_ setEditable:YES];
[text_field_ setFocusRingType:NSFocusRingTypeExterior];
[text_field_ setDrawsBackground:YES];
[text_field_ setBackgroundColor:[NSColor whiteColor]];
}
return text_field_;
}
String LayoutThemeMac::DisplayNameForFile(const File& file) const {
if (file.GetUserVisibility() == File::kIsUserVisible)
return [[NSFileManager defaultManager] displayNameAtPath:file.GetPath()];
return file.name();
}
NSView* FlippedView() {
static NSView* view = [[BlinkFlippedView alloc] init];
return view;
}
LayoutTheme& LayoutTheme::NativeTheme() { LayoutTheme& LayoutTheme::NativeTheme() {
if (features::IsFormControlsRefreshEnabled()) { DCHECK(features::IsFormControlsRefreshEnabled());
DEFINE_STATIC_REF(LayoutTheme, layout_theme, DEFINE_STATIC_REF(LayoutTheme, layout_theme, (LayoutThemeMac::Create()));
(LayoutThemeMacRefresh::Create())); return *layout_theme;
return *layout_theme;
} else {
DEFINE_STATIC_REF(LayoutTheme, layout_theme, (LayoutThemeMac::Create()));
return *layout_theme;
}
}
scoped_refptr<LayoutTheme> LayoutThemeMac::Create() {
return base::AdoptRef(new LayoutThemeMac);
}
bool LayoutThemeMac::UsesTestModeFocusRingColor() const {
return WebTestSupport::IsRunningWebTest() ||
!Platform::Current()->GetSandboxSupport();
}
NSView* LayoutThemeMac::DocumentView() const {
return FlippedView();
}
// Updates the control tint (a.k.a. active state) of |cell| (from |o|). In the
// Chromium port, the layoutObject runs as a background process and controls'
// NSCell(s) lack a parent NSView. Therefore controls don't have their tint
// color updated correctly when the application is activated/deactivated.
// FocusController's setActive() is called when the application is
// activated/deactivated, which causes a paint invalidation at which time this
// code is called.
// This function should be called before drawing any NSCell-derived controls,
// unless you're sure it isn't needed.
void LayoutThemeMac::UpdateActiveState(NSCell* cell, const Node* node) {
NSControlTint old_tint = [cell controlTint];
NSControlTint tint = IsActive(node)
? [NSColor currentControlTint]
: static_cast<NSControlTint>(NSClearControlTint);
if (tint != old_tint)
[cell setControlTint:tint];
}
String LayoutThemeMac::ExtraFullscreenStyleSheet() {
// FIXME: Chromium may wish to style its default media controls differently in
// fullscreen.
return String();
}
String LayoutThemeMac::ExtraDefaultStyleSheet() {
return LayoutTheme::ExtraDefaultStyleSheet() +
UncompressResourceAsASCIIString(
IDR_UASTYLE_THEME_INPUT_MULTIPLE_FIELDS_CSS) +
UncompressResourceAsASCIIString(IDR_UASTYLE_THEME_MAC_CSS);
}
bool LayoutThemeMac::ThemeDrawsFocusRing(const ComputedStyle& style) const {
if (ShouldUseFallbackTheme(style))
return false;
switch (style.EffectiveAppearance()) {
case kCheckboxPart:
case kRadioPart:
case kPushButtonPart:
case kSquareButtonPart:
case kButtonPart:
case kMenulistPart:
case kSliderThumbHorizontalPart:
case kSliderThumbVerticalPart:
return true;
// Actually, they don't support native focus rings, but this function
// returns true for them in order to prevent Blink from drawing focus rings.
// SliderThumb*Part have focus rings, and we don't need to draw two focus
// rings for single slider.
case kSliderHorizontalPart:
case kSliderVerticalPart:
return true;
default:
return false;
}
}
bool LayoutThemeMac::ShouldUseFallbackTheme(const ComputedStyle& style) const {
ControlPart part = style.EffectiveAppearance();
if (part == kCheckboxPart || part == kRadioPart)
return style.EffectiveZoom() != 1;
return false;
}
// We don't use controlSizeForFont() for steppers because the stepper height
// should be equal to or less than the corresponding text field height,
static NSControlSize StepperControlSizeForFont(
const FontDescription& font_description) {
int font_size = font_description.ComputedPixelSize();
if (font_size >= 27)
return NSRegularControlSize;
if (font_size >= 22)
return NSSmallControlSize;
return NSMiniControlSize;
}
NSControlSize LayoutThemeMac::ControlSizeFromPixelSize(
const IntSize* sizes,
const IntSize& min_zoomed_size,
float zoom_factor) {
if (min_zoomed_size.Width() >=
static_cast<int>(sizes[NSRegularControlSize].Width() * zoom_factor) &&
min_zoomed_size.Height() >=
static_cast<int>(sizes[NSRegularControlSize].Height() * zoom_factor))
return NSRegularControlSize;
if (min_zoomed_size.Width() >=
static_cast<int>(sizes[NSSmallControlSize].Width() * zoom_factor) &&
min_zoomed_size.Height() >=
static_cast<int>(sizes[NSSmallControlSize].Height() * zoom_factor))
return NSSmallControlSize;
return NSMiniControlSize;
}
static void SetControlSizeThemeMac(NSCell* cell,
const IntSize* sizes,
const IntSize& min_zoomed_size,
float zoom_factor) {
ControlSize size = LayoutThemeMac::ControlSizeFromPixelSize(
sizes, min_zoomed_size, zoom_factor);
// Only update if we have to, since AppKit does work even if the size is the
// same.
if (size != [cell controlSize])
[cell setControlSize:(NSControlSize)size];
}
static void UpdateStates(NSCell* cell, ControlStates states) {
// Hover state is not supported by Aqua.
// Pressed state
bool old_pressed = [cell isHighlighted];
bool pressed = states & kPressedControlState;
if (pressed != old_pressed)
[cell setHighlighted:pressed];
// Enabled state
bool old_enabled = [cell isEnabled];
bool enabled = states & kEnabledControlState;
if (enabled != old_enabled)
[cell setEnabled:enabled];
// Checked and Indeterminate
bool old_indeterminate = [cell state] == NSMixedState;
bool indeterminate = (states & kIndeterminateControlState);
bool checked = states & kCheckedControlState;
bool old_checked = [cell state] == NSOnState;
if (old_indeterminate != indeterminate || checked != old_checked)
[cell setState:indeterminate ? NSMixedState
: (checked ? NSOnState : NSOffState)];
// Window inactive state does not need to be checked explicitly, since we
// paint parented to a view in a window whose key state can be detected.
}
// Return a fake NSView whose sole purpose is to tell AppKit that it's flipped.
NSView* LayoutThemeMac::EnsuredView(const IntSize& size) {
// Use a fake flipped view.
static NSView* flipped_view = [[BlinkFlippedControl alloc] init];
[flipped_view setFrameSize:NSSizeFromCGSize(CGSize(size))];
return flipped_view;
}
FontDescription LayoutThemeMac::ControlFont(
ControlPart part,
const FontDescription& font_description,
float zoom_factor) const {
using ::blink::ControlSizeForFont;
switch (part) {
case kPushButtonPart: {
FontDescription result;
result.SetIsAbsoluteSize(true);
result.SetGenericFamily(FontDescription::kSerifFamily);
NSFont* ns_font = [NSFont
systemFontOfSize:[NSFont systemFontSizeForControlSize:
ControlSizeForFont(font_description)]];
result.FirstFamily().SetFamily(font_family_names::kSystemUi);
result.SetComputedSize([ns_font pointSize] * zoom_factor);
result.SetSpecifiedSize([ns_font pointSize] * zoom_factor);
return result;
}
default:
return LayoutTheme::ControlFont(part, font_description, zoom_factor);
}
}
LengthSize LayoutThemeMac::GetControlSize(
ControlPart part,
const FontDescription& font_description,
const LengthSize& zoomed_size,
float zoom_factor) const {
switch (part) {
case kCheckboxPart:
return CheckboxSize(font_description, zoomed_size, zoom_factor);
case kRadioPart:
return RadioSize(font_description, zoomed_size, zoom_factor);
case kPushButtonPart:
// Height is reset to auto so that specified heights can be ignored.
return SizeFromFont(font_description,
LengthSize(zoomed_size.Width(), Length()),
zoom_factor, ButtonSizes());
case kInnerSpinButtonPart:
if (!zoomed_size.Width().IsIntrinsicOrAuto() &&
!zoomed_size.Height().IsIntrinsicOrAuto())
return zoomed_size;
return SizeFromNSControlSize(StepperControlSizeForFont(font_description),
zoomed_size, zoom_factor, StepperSizes());
default:
return zoomed_size;
}
}
LengthSize LayoutThemeMac::MinimumControlSize(
ControlPart part,
const FontDescription& font_description,
float zoom_factor,
const ComputedStyle& style) const {
switch (part) {
case kSquareButtonPart:
case kButtonPart:
return LengthSize(style.MinWidth().Zoom(zoom_factor),
Length::Fixed(static_cast<int>(15 * zoom_factor)));
case kInnerSpinButtonPart: {
IntSize base = StepperSizes()[NSMiniControlSize];
return LengthSize(
Length::Fixed(static_cast<int>(base.Width() * zoom_factor)),
Length::Fixed(static_cast<int>(base.Height() * zoom_factor)));
}
default:
return LayoutTheme::MinimumControlSize(part, font_description,
zoom_factor, style);
}
}
LengthBox LayoutThemeMac::ControlPadding(
ControlPart part,
const FontDescription& font_description,
const Length& zoomed_box_top,
const Length& zoomed_box_right,
const Length& zoomed_box_bottom,
const Length& zoomed_box_left,
float zoom_factor) const {
switch (part) {
case kPushButtonPart: {
// Just use 8px. AppKit wants to use 11px for mini buttons, but that
// padding is just too large for real-world Web sites (creating a huge
// necessary minimum width for buttons whose space is by definition
// constrained, since we select mini only for small cramped environments.
// This also guarantees the HTML <button> will match our rendering by
// default, since we're using a consistent padding.
const int padding = 8 * zoom_factor;
return LengthBox(2, padding, 3, padding);
}
default:
return LayoutTheme::ControlPadding(part, font_description, zoomed_box_top,
zoomed_box_right, zoomed_box_bottom,
zoomed_box_left, zoom_factor);
}
}
LengthBox LayoutThemeMac::ControlBorder(ControlPart part,
const FontDescription& font_description,
const LengthBox& zoomed_box,
float zoom_factor) const {
switch (part) {
case kSquareButtonPart:
return LengthBox(0, zoomed_box.Right().Value(), 0,
zoomed_box.Left().Value());
default:
return LayoutTheme::ControlBorder(part, font_description, zoomed_box,
zoom_factor);
}
}
void LayoutThemeMac::AdjustControlPartStyle(ComputedStyle& style) {
ControlPart part = style.EffectiveAppearance();
switch (part) {
case kCheckboxPart:
case kInnerSpinButtonPart:
case kRadioPart:
case kPushButtonPart:
case kSquareButtonPart:
case kButtonPart: {
// Border
LengthBox border_box(style.BorderTopWidth(), style.BorderRightWidth(),
style.BorderBottomWidth(), style.BorderLeftWidth());
border_box = ControlBorder(part, style.GetFont().GetFontDescription(),
border_box, style.EffectiveZoom());
if (border_box.Top().Value() !=
static_cast<int>(style.BorderTopWidth())) {
if (border_box.Top().Value())
style.SetBorderTopWidth(border_box.Top().Value());
else
style.ResetBorderTop();
}
if (border_box.Right().Value() !=
static_cast<int>(style.BorderRightWidth())) {
if (border_box.Right().Value())
style.SetBorderRightWidth(border_box.Right().Value());
else
style.ResetBorderRight();
}
if (border_box.Bottom().Value() !=
static_cast<int>(style.BorderBottomWidth())) {
style.SetBorderBottomWidth(border_box.Bottom().Value());
if (border_box.Bottom().Value())
style.SetBorderBottomWidth(border_box.Bottom().Value());
else
style.ResetBorderBottom();
}
if (border_box.Left().Value() !=
static_cast<int>(style.BorderLeftWidth())) {
style.SetBorderLeftWidth(border_box.Left().Value());
if (border_box.Left().Value())
style.SetBorderLeftWidth(border_box.Left().Value());
else
style.ResetBorderLeft();
}
// Padding
LengthBox padding_box = ControlPadding(
part, style.GetFont().GetFontDescription(), style.PaddingTop(),
style.PaddingRight(), style.PaddingBottom(), style.PaddingLeft(),
style.EffectiveZoom());
if (!style.PaddingEqual(padding_box))
style.SetPadding(padding_box);
// Whitespace
if (ControlRequiresPreWhiteSpace(part))
style.SetWhiteSpace(EWhiteSpace::kPre);
// Width / Height
// The width and height here are affected by the zoom.
LengthSize control_size = GetControlSize(
part, style.GetFont().GetFontDescription(),
LengthSize(style.Width(), style.Height()), style.EffectiveZoom());
LengthSize min_control_size =
MinimumControlSize(part, style.GetFont().GetFontDescription(),
style.EffectiveZoom(), style);
// Only potentially set min-size to |control_size| for these parts.
if (part == kCheckboxPart || part == kRadioPart)
SetMinimumSize(style, &control_size, &min_control_size);
else
SetMinimumSize(style, nullptr, &min_control_size);
if (control_size.Width() != style.Width())
style.SetWidth(control_size.Width());
if (control_size.Height() != style.Height())
style.SetHeight(control_size.Height());
// Font
FontDescription control_font = ControlFont(
part, style.GetFont().GetFontDescription(), style.EffectiveZoom());
if (control_font != style.GetFont().GetFontDescription()) {
// Reset our line-height
style.SetLineHeight(ComputedStyleInitialValues::InitialLineHeight());
// Now update our font.
style.SetFontDescription(control_font);
}
break;
}
case kProgressBarPart:
AdjustProgressBarBounds(style);
break;
default:
break;
}
}
// static
IntRect LayoutThemeMac::InflateRect(const IntRect& zoomed_rect,
const IntSize& zoomed_size,
const int* margins,
float zoom_factor) {
// Only do the inflation if the available width/height are too small.
// Otherwise try to fit the glow/check space into the available box's
// width/height.
int width_delta = zoomed_rect.Width() -
(zoomed_size.Width() + margins[kLeftMargin] * zoom_factor +
margins[kRightMargin] * zoom_factor);
int height_delta = zoomed_rect.Height() -
(zoomed_size.Height() + margins[kTopMargin] * zoom_factor +
margins[kBottomMargin] * zoom_factor);
IntRect result(zoomed_rect);
if (width_delta < 0) {
result.SetX(result.X() - margins[kLeftMargin] * zoom_factor);
result.SetWidth(result.Width() - width_delta);
}
if (height_delta < 0) {
result.SetY(result.Y() - margins[kTopMargin] * zoom_factor);
result.SetHeight(result.Height() - height_delta);
}
return result;
}
// static
IntRect LayoutThemeMac::InflateRectForFocusRing(const IntRect& rect) {
// Just put a margin of 16 units around the rect. The UI elements that use
// this don't appropriately scale their focus rings appropriately (e.g, paint
// pickers), or switch to non-native widgets when scaled (e.g, check boxes
// and radio buttons).
const int kMargin = 16;
IntRect result;
result.SetX(rect.X() - kMargin);
result.SetY(rect.Y() - kMargin);
result.SetWidth(rect.Width() + 2 * kMargin);
result.SetHeight(rect.Height() + 2 * kMargin);
return result;
}
// Checkboxes
const IntSize* LayoutThemeMac::CheckboxSizes() {
static const IntSize kSizes[3] = {IntSize(14, 14), IntSize(12, 12),
IntSize(10, 10)};
return kSizes;
}
const int* LayoutThemeMac::CheckboxMargins(NSControlSize control_size) {
static const int kMargins[3][4] = {
{3, 4, 4, 2},
{4, 3, 3, 3},
{4, 3, 3, 3},
};
return kMargins[control_size];
}
LengthSize LayoutThemeMac::CheckboxSize(const FontDescription& font_description,
const LengthSize& zoomed_size,
float zoom_factor) {
// If the width and height are both specified, then we have nothing to do.
if (!zoomed_size.Width().IsIntrinsicOrAuto() &&
!zoomed_size.Height().IsIntrinsicOrAuto())
return zoomed_size;
// Use the font size to determine the intrinsic width of the control.
return SizeFromFont(font_description, zoomed_size, zoom_factor,
CheckboxSizes());
}
NSButtonCell* LayoutThemeMac::Checkbox(ControlStates states,
const IntRect& zoomed_rect,
float zoom_factor) {
static NSButtonCell* checkbox_cell;
if (!checkbox_cell) {
checkbox_cell = [[NSButtonCell alloc] init];
[checkbox_cell setButtonType:NSSwitchButton];
[checkbox_cell setTitle:nil];
[checkbox_cell setAllowsMixedState:YES];
[checkbox_cell setFocusRingType:NSFocusRingTypeExterior];
}
// Set the control size based off the rectangle we're painting into.
SetControlSizeThemeMac(checkbox_cell, CheckboxSizes(), zoomed_rect.Size(),
zoom_factor);
// Update the various states we respond to.
UpdateStates(checkbox_cell, states);
return checkbox_cell;
}
const IntSize* LayoutThemeMac::RadioSizes() {
static const IntSize kSizes[3] = {IntSize(14, 15), IntSize(12, 13),
IntSize(10, 10)};
return kSizes;
}
const int* LayoutThemeMac::RadioMargins(NSControlSize control_size) {
static const int kMargins[3][4] = {
{2, 2, 4, 2},
{3, 2, 3, 2},
{1, 0, 2, 0},
};
return kMargins[control_size];
}
LengthSize LayoutThemeMac::RadioSize(const FontDescription& font_description,
const LengthSize& zoomed_size,
float zoom_factor) {
// If the width and height are both specified, then we have nothing to do.
if (!zoomed_size.Width().IsIntrinsicOrAuto() &&
!zoomed_size.Height().IsIntrinsicOrAuto())
return zoomed_size;
// Use the font size to determine the intrinsic width of the control.
return SizeFromFont(font_description, zoomed_size, zoom_factor, RadioSizes());
}
NSButtonCell* LayoutThemeMac::Radio(ControlStates states,
const IntRect& zoomed_rect,
float zoom_factor) {
static NSButtonCell* radio_cell;
if (!radio_cell) {
radio_cell = [[NSButtonCell alloc] init];
[radio_cell setButtonType:NSRadioButton];
[radio_cell setTitle:nil];
[radio_cell setFocusRingType:NSFocusRingTypeExterior];
}
// Set the control size based off the rectangle we're painting into.
SetControlSizeThemeMac(radio_cell, RadioSizes(), zoomed_rect.Size(),
zoom_factor);
// Update the various states we respond to.
// Cocoa draws NSMixedState NSRadioButton as NSOnState so we don't want that.
states &= ~kIndeterminateControlState;
UpdateStates(radio_cell, states);
return radio_cell;
}
// Buttons really only constrain height. They respect width.
const IntSize* LayoutThemeMac::ButtonSizes() {
static const IntSize kSizes[3] = {IntSize(0, 21), IntSize(0, 18),
IntSize(0, 15)};
return kSizes;
}
const int* LayoutThemeMac::ButtonMargins(NSControlSize control_size) {
static const int kMargins[3][4] = {
{4, 6, 7, 6},
{4, 5, 6, 5},
{0, 1, 1, 1},
};
return kMargins[control_size];
}
static void SetUpButtonCell(NSButtonCell* cell,
ControlPart part,
ControlStates states,
const IntRect& zoomed_rect,
float zoom_factor) {
// Set the control size based off the rectangle we're painting into.
const IntSize* sizes = LayoutThemeMac::ButtonSizes();
if (part == kSquareButtonPart ||
zoomed_rect.Height() >
LayoutThemeMac::ButtonSizes()[NSRegularControlSize].Height() *
zoom_factor) {
// Use the square button
if ([cell bezelStyle] != NSShadowlessSquareBezelStyle)
[cell setBezelStyle:NSShadowlessSquareBezelStyle];
} else if ([cell bezelStyle] != NSRoundedBezelStyle)
[cell setBezelStyle:NSRoundedBezelStyle];
SetControlSizeThemeMac(cell, sizes, zoomed_rect.Size(), zoom_factor);
// Update the various states we respond to.
UpdateStates(cell, states);
}
NSButtonCell* LayoutThemeMac::Button(ControlPart part,
ControlStates states,
const IntRect& zoomed_rect,
float zoom_factor) {
static NSButtonCell* cell = nil;
if (!cell) {
cell = [[NSButtonCell alloc] init];
[cell setTitle:nil];
[cell setButtonType:NSMomentaryPushInButton];
}
SetUpButtonCell(cell, part, states, zoomed_rect, zoom_factor);
return cell;
}
const IntSize* LayoutThemeMac::StepperSizes() {
static const IntSize kSizes[3] = {IntSize(19, 27), IntSize(15, 22),
IntSize(13, 15)};
return kSizes;
} }
} // namespace blink } // namespace blink
...@@ -260,8 +260,6 @@ blink_core_sources("paint") { ...@@ -260,8 +260,6 @@ blink_core_sources("paint") {
"theme_painter.h", "theme_painter.h",
"theme_painter_default.cc", "theme_painter_default.cc",
"theme_painter_default.h", "theme_painter_default.h",
"theme_painter_mac.h",
"theme_painter_mac.mm",
"url_metadata_utils.cc", "url_metadata_utils.cc",
"url_metadata_utils.h", "url_metadata_utils.h",
"video_painter.cc", "video_painter.cc",
......
/*
* This file is part of the theme implementation for form controls in WebCore.
*
* Copyright (C) 2005 Apple Computer, Inc.
* Copyright (C) 2008, 2009 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_THEME_PAINTER_MAC_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_THEME_PAINTER_MAC_H_
#import "third_party/blink/renderer/core/paint/theme_painter.h"
namespace blink {
class LayoutThemeMac;
class ThemePainterMac final : public ThemePainter {
public:
ThemePainterMac(LayoutThemeMac&);
private:
bool PaintButton(const Node*,
const Document&,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintCheckbox(const Node*,
const Document&,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintCapsLockIndicator(const LayoutObject&,
const PaintInfo&,
const IntRect&) override;
bool PaintInnerSpinButton(const Node*,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintMenuList(const Node*,
const Document&,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintMenuListButton(const Node*,
const Document&,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintProgressBar(const LayoutObject&,
const PaintInfo&,
const IntRect&) override;
bool PaintRadio(const Node*,
const Document&,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintSliderThumb(const Node*,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintSliderTrack(const LayoutObject&,
const PaintInfo&,
const IntRect&) override;
bool PaintSearchField(const Node*,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintSearchFieldCancelButton(const LayoutObject&,
const PaintInfo&,
const IntRect&) override;
bool PaintTextArea(const Node*,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
bool PaintTextField(const Node*,
const ComputedStyle&,
const PaintInfo&,
const IntRect&) override;
LayoutThemeMac& layout_theme_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_PAINT_THEME_PAINTER_MAC_H_
/*
* Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2009 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#import "third_party/blink/renderer/core/paint/theme_painter_mac.h"
#import <AvailabilityMacros.h>
#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>
#import <math.h>
#import "third_party/blink/renderer/core/frame/local_frame_view.h"
#import "third_party/blink/renderer/core/layout/layout_progress.h"
#import "third_party/blink/renderer/core/layout/layout_theme_mac.h"
#import "third_party/blink/renderer/core/layout/layout_view.h"
#import "third_party/blink/renderer/core/paint/paint_info.h"
#import "third_party/blink/renderer/platform/geometry/float_rounded_rect.h"
#import "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#import "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#import "third_party/blink/renderer/platform/graphics/image.h"
#import "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
#import "third_party/blink/renderer/platform/mac/block_exceptions.h"
#import "third_party/blink/renderer/platform/mac/color_mac.h"
#import "third_party/blink/renderer/platform/mac/local_current_graphics_context.h"
#import "third_party/blink/renderer/platform/mac/web_core_ns_cell_extras.h"
// The methods in this file are specific to the Mac OS X platform.
// Forward declare Mac SPIs.
extern "C" {
void _NSDrawCarbonThemeBezel(NSRect frame, BOOL enabled, BOOL flipped);
// Request for public API: rdar://13787640
void _NSDrawCarbonThemeListBox(NSRect frame,
BOOL enabled,
BOOL flipped,
BOOL always_yes);
}
namespace blink {
class ScopedColorSchemeAppearance {
public:
ScopedColorSchemeAppearance(WebColorScheme color_scheme) {
if (@available(macOS 10.14, *)) {
old_appearance = [NSAppearance currentAppearance];
[NSAppearance
setCurrentAppearance:
[NSAppearance
appearanceNamed:color_scheme == WebColorScheme::kDark
? NSAppearanceNameDarkAqua
: NSAppearanceNameAqua]];
}
}
~ScopedColorSchemeAppearance() {
if (@available(macOS 10.14, *))
[NSAppearance setCurrentAppearance:old_appearance];
}
private:
NSAppearance* old_appearance;
};
ThemePainterMac::ThemePainterMac(LayoutThemeMac& layout_theme)
: ThemePainter(), layout_theme_(layout_theme) {}
bool ThemePainterMac::PaintTextField(const Node* node,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);
bool use_ns_text_field_cell =
style.HasEffectiveAppearance() &&
style.VisitedDependentColor(GetCSSPropertyBackgroundColor()) ==
Color::kWhite &&
!style.HasBackgroundImage();
// We do not use NSTextFieldCell to draw styled text fields since it induces a
// behavior change while remaining a fragile solution.
// https://bugs.chromium.org/p/chromium/issues/detail?id=658085#c3
if (!use_ns_text_field_cell) {
_NSDrawCarbonThemeBezel(
CGRect(r),
LayoutTheme::IsEnabled(node) && !LayoutTheme::IsReadOnlyControl(node),
YES);
return false;
}
NSTextFieldCell* text_field = layout_theme_.TextField();
GraphicsContextStateSaver state_saver(paint_info.context);
[text_field setEnabled:(LayoutTheme::IsEnabled(node) &&
!LayoutTheme::IsReadOnlyControl(node))];
[text_field drawWithFrame:NSRect(r) inView:layout_theme_.DocumentView()];
[text_field setControlView:nil];
return false;
}
bool ThemePainterMac::PaintCapsLockIndicator(const LayoutObject& o,
const PaintInfo& paint_info,
const IntRect& r) {
// This draws the caps lock indicator as it was done by
// WKDrawCapsLockIndicator.
ScopedColorSchemeAppearance appearance(o.StyleRef().UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);
CGContextRef c = local_context.CgContext();
CGMutablePathRef shape = CGPathCreateMutable();
// To draw the caps lock indicator, draw the shape into a small
// square that is then scaled to the size of r.
const CGFloat kSquareSize = 17;
// Create a rounted square shape.
CGPathMoveToPoint(shape, NULL, 16.5, 4.5);
CGPathAddArc(shape, NULL, 12.5, 12.5, 4, 0, M_PI_2, false);
CGPathAddArc(shape, NULL, 4.5, 12.5, 4, M_PI_2, M_PI, false);
CGPathAddArc(shape, NULL, 4.5, 4.5, 4, M_PI, 3 * M_PI / 2, false);
CGPathAddArc(shape, NULL, 12.5, 4.5, 4, 3 * M_PI / 2, 0, false);
// Draw the arrow - note this is drawing in a flipped coordinate system, so
// the arrow is pointing down.
CGPathMoveToPoint(shape, NULL, 8.5, 2); // Tip point.
CGPathAddLineToPoint(shape, NULL, 4, 7);
CGPathAddLineToPoint(shape, NULL, 6.25, 7);
CGPathAddLineToPoint(shape, NULL, 6.25, 10.25);
CGPathAddLineToPoint(shape, NULL, 10.75, 10.25);
CGPathAddLineToPoint(shape, NULL, 10.75, 7);
CGPathAddLineToPoint(shape, NULL, 13, 7);
CGPathAddLineToPoint(shape, NULL, 8.5, 2);
// Draw the rectangle that underneath (or above in the flipped system) the
// arrow.
CGPathAddLineToPoint(shape, NULL, 10.75, 12);
CGPathAddLineToPoint(shape, NULL, 6.25, 12);
CGPathAddLineToPoint(shape, NULL, 6.25, 14.25);
CGPathAddLineToPoint(shape, NULL, 10.75, 14.25);
CGPathAddLineToPoint(shape, NULL, 10.75, 12);
// Scale and translate the shape.
CGRect cgr = CGRect(r);
CGFloat max_x = CGRectGetMaxX(cgr);
CGFloat min_x = CGRectGetMinX(cgr);
CGFloat min_y = CGRectGetMinY(cgr);
CGFloat height_scale = r.Height() / kSquareSize;
const bool is_rtl = o.StyleRef().Direction() == TextDirection::kRtl;
CGAffineTransform transform = CGAffineTransformMake(
height_scale, 0, // A B
0, height_scale, // C D
is_rtl ? min_x : max_x - r.Height(), min_y); // Tx Ty
CGMutablePathRef paint_path = CGPathCreateMutable();
CGPathAddPath(paint_path, &transform, shape);
CGPathRelease(shape);
CGContextSetRGBFillColor(c, 0, 0, 0, 0.4);
CGContextBeginPath(c);
CGContextAddPath(c, paint_path);
CGContextFillPath(c);
CGPathRelease(paint_path);
return false;
}
bool ThemePainterMac::PaintTextArea(const Node* node,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);
_NSDrawCarbonThemeListBox(
CGRect(r),
LayoutTheme::IsEnabled(node) && !LayoutTheme::IsReadOnlyControl(node),
YES, YES);
return false;
}
bool ThemePainterMac::PaintMenuList(const Node* node,
const Document&,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
layout_theme_.SetPopupButtonCellState(node, style, r);
NSPopUpButtonCell* popup_button = layout_theme_.PopupButton();
float zoom_level = style.EffectiveZoom();
IntSize size = layout_theme_.PopupButtonSizes()[[popup_button controlSize]];
size.SetHeight(size.Height() * zoom_level);
size.SetWidth(r.Width());
// Now inflate it to account for the shadow.
IntRect inflated_rect = r;
if (r.Width() >= layout_theme_.MinimumMenuListSize(style))
inflated_rect = LayoutThemeMac::InflateRect(
inflated_rect, size, layout_theme_.PopupButtonMargins(), zoom_level);
LocalCurrentGraphicsContext local_context(
paint_info.context,
LayoutThemeMac::InflateRectForFocusRing(inflated_rect));
if (zoom_level != 1.0f) {
inflated_rect.SetWidth(inflated_rect.Width() / zoom_level);
inflated_rect.SetHeight(inflated_rect.Height() / zoom_level);
paint_info.context.Translate(inflated_rect.X(), inflated_rect.Y());
paint_info.context.Scale(zoom_level, zoom_level);
paint_info.context.Translate(-inflated_rect.X(), -inflated_rect.Y());
}
NSView* view = layout_theme_.DocumentView();
[popup_button drawWithFrame:CGRect(inflated_rect) inView:view];
if (LayoutTheme::IsFocused(node) && style.OutlineStyleIsAuto())
[popup_button cr_drawFocusRingWithFrame:CGRect(inflated_rect) inView:view];
[popup_button setControlView:nil];
return false;
}
bool ThemePainterMac::PaintProgressBar(const LayoutObject& layout_object,
const PaintInfo& paint_info,
const IntRect& rect) {
if (!layout_object.IsProgress())
return true;
ScopedColorSchemeAppearance appearance(
layout_object.StyleRef().UsedColorScheme());
const LayoutProgress& layout_progress = ToLayoutProgress(layout_object);
HIThemeTrackDrawInfo track_info;
track_info.version = 0;
NSControlSize control_size =
layout_theme_.ControlSizeForFont(layout_object.StyleRef());
if (control_size == NSRegularControlSize)
track_info.kind = layout_progress.GetPosition() < 0
? kThemeLargeIndeterminateBar
: kThemeLargeProgressBar;
else
track_info.kind = layout_progress.GetPosition() < 0
? kThemeMediumIndeterminateBar
: kThemeMediumProgressBar;
track_info.bounds = CGRect(IntRect(IntPoint(), rect.Size()));
track_info.min = 0;
track_info.max = std::numeric_limits<SInt32>::max();
track_info.value =
lround(layout_progress.GetPosition() * nextafter(track_info.max, 0));
track_info.trackInfo.progress.phase =
lround(layout_progress.AnimationProgress() *
nextafter(LayoutThemeMac::kProgressAnimationNumFrames, 0));
track_info.attributes = kThemeTrackHorizontal;
track_info.enableState = LayoutTheme::IsActive(layout_object.GetNode())
? kThemeTrackActive
: kThemeTrackInactive;
track_info.reserved = 0;
track_info.filler1 = 0;
GraphicsContextStateSaver state_saver(paint_info.context);
paint_info.context.Translate(rect.X(), rect.Y());
if (!layout_progress.StyleRef().IsLeftToRightDirection()) {
paint_info.context.Translate(rect.Width(), 0);
paint_info.context.Scale(-1, 1);
}
IntRect clip_rect = IntRect(IntPoint(), rect.Size());
LocalCurrentGraphicsContext local_context(paint_info.context, clip_rect);
CGContextRef cg_context = local_context.CgContext();
HIThemeDrawTrack(&track_info, 0, cg_context, kHIThemeOrientationNormal);
return false;
}
bool ThemePainterMac::PaintMenuListButton(const Node* node,
const Document&,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
IntRect bounds =
IntRect(r.X() + style.BorderLeftWidth(), r.Y() + style.BorderTopWidth(),
r.Width() - style.BorderLeftWidth() - style.BorderRightWidth(),
r.Height() - style.BorderTopWidth() - style.BorderBottomWidth());
// Since we actually know the size of the control here, we restrict the font
// scale to make sure the arrows will fit vertically in the bounds
float font_scale = std::min(
style.FontSize() / LayoutThemeMac::kBaseFontSize,
bounds.Height() / (LayoutThemeMac::kMenuListBaseArrowHeight * 2 +
LayoutThemeMac::kMenuListBaseSpaceBetweenArrows));
float center_y = bounds.Y() + bounds.Height() / 2.0f;
float arrow_height = LayoutThemeMac::kMenuListBaseArrowHeight * font_scale;
float arrow_width = LayoutThemeMac::kMenuListBaseArrowWidth * font_scale;
float space_between_arrows =
LayoutThemeMac::kMenuListBaseSpaceBetweenArrows * font_scale;
float scaled_padding_end =
LayoutThemeMac::kMenuListArrowPaddingEnd * style.EffectiveZoom();
float left_edge;
if (style.Direction() == TextDirection::kLtr) {
left_edge = bounds.MaxX() - scaled_padding_end - arrow_width;
} else {
left_edge = bounds.X() + scaled_padding_end;
}
if (bounds.Width() < arrow_width + scaled_padding_end)
return false;
Color color = style.VisitedDependentColor(GetCSSPropertyColor());
PaintFlags flags = paint_info.context.FillFlags();
flags.setAntiAlias(true);
flags.setColor(color.Rgb());
SkPath arrow1;
arrow1.moveTo(left_edge, center_y - space_between_arrows / 2.0f);
arrow1.lineTo(left_edge + arrow_width,
center_y - space_between_arrows / 2.0f);
arrow1.lineTo(left_edge + arrow_width / 2.0f,
center_y - space_between_arrows / 2.0f - arrow_height);
// Draw the top arrow.
paint_info.context.DrawPath(arrow1, flags);
SkPath arrow2;
arrow2.moveTo(left_edge, center_y + space_between_arrows / 2.0f);
arrow2.lineTo(left_edge + arrow_width,
center_y + space_between_arrows / 2.0f);
arrow2.lineTo(left_edge + arrow_width / 2.0f,
center_y + space_between_arrows / 2.0f + arrow_height);
// Draw the bottom arrow.
paint_info.context.DrawPath(arrow2, flags);
return false;
}
bool ThemePainterMac::PaintSliderTrack(const LayoutObject& o,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(o.StyleRef().UsedColorScheme());
PaintSliderTicks(o, paint_info, r);
float zoom_level = o.StyleRef().EffectiveZoom();
FloatRect unzoomed_rect(r);
if (o.StyleRef().EffectiveAppearance() == kSliderHorizontalPart ||
o.StyleRef().EffectiveAppearance() == kMediaSliderPart) {
unzoomed_rect.SetY(
ceilf(unzoomed_rect.Y() + unzoomed_rect.Height() / 2 -
zoom_level * LayoutThemeMac::kSliderTrackWidth / 2));
unzoomed_rect.SetHeight(zoom_level * LayoutThemeMac::kSliderTrackWidth);
} else if (o.StyleRef().EffectiveAppearance() == kSliderVerticalPart) {
unzoomed_rect.SetX(
ceilf(unzoomed_rect.X() + unzoomed_rect.Width() / 2 -
zoom_level * LayoutThemeMac::kSliderTrackWidth / 2));
unzoomed_rect.SetWidth(zoom_level * LayoutThemeMac::kSliderTrackWidth);
}
if (zoom_level != 1) {
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / zoom_level);
}
GraphicsContextStateSaver state_saver(paint_info.context);
if (zoom_level != 1) {
paint_info.context.Translate(unzoomed_rect.X(), unzoomed_rect.Y());
paint_info.context.Scale(zoom_level, zoom_level);
paint_info.context.Translate(-unzoomed_rect.X(), -unzoomed_rect.Y());
}
Color fill_color(205, 205, 205);
Color border_gradient_top_color(109, 109, 109);
Color border_gradient_bottom_color(181, 181, 181);
Color shadow_color(0, 0, 0, 118);
if (!LayoutTheme::IsEnabled(o.GetNode())) {
Color tint_color(255, 255, 255, 128);
fill_color = fill_color.Blend(tint_color);
border_gradient_top_color = border_gradient_top_color.Blend(tint_color);
border_gradient_bottom_color =
border_gradient_bottom_color.Blend(tint_color);
shadow_color = shadow_color.Blend(tint_color);
}
Color tint_color;
if (!LayoutTheme::IsEnabled(o.GetNode()))
tint_color = Color(255, 255, 255, 128);
bool is_vertical_slider =
o.StyleRef().EffectiveAppearance() == kSliderVerticalPart;
float fill_radius_size = (LayoutThemeMac::kSliderTrackWidth -
LayoutThemeMac::kSliderTrackBorderWidth) /
2;
FloatSize fill_radius(fill_radius_size, fill_radius_size);
FloatRect fill_bounds(EnclosedIntRect(unzoomed_rect));
FloatRoundedRect fill_rect(fill_bounds, fill_radius, fill_radius, fill_radius,
fill_radius);
paint_info.context.FillRoundedRect(fill_rect, fill_color);
FloatSize shadow_offset(is_vertical_slider ? 1 : 0,
is_vertical_slider ? 0 : 1);
float shadow_blur = 3;
float shadow_spread = 0;
paint_info.context.Save();
paint_info.context.DrawInnerShadow(fill_rect, shadow_color, shadow_offset,
shadow_blur, shadow_spread);
paint_info.context.Restore();
scoped_refptr<Gradient> border_gradient =
Gradient::CreateLinear(fill_bounds.MinXMinYCorner(),
is_vertical_slider ? fill_bounds.MaxXMinYCorner()
: fill_bounds.MinXMaxYCorner());
border_gradient->AddColorStop(0.0, border_gradient_top_color);
border_gradient->AddColorStop(1.0, border_gradient_bottom_color);
FloatRect border_rect(unzoomed_rect);
border_rect.Inflate(-LayoutThemeMac::kSliderTrackBorderWidth / 2.0);
float border_radius_size =
(is_vertical_slider ? border_rect.Width() : border_rect.Height()) / 2;
FloatSize border_radius(border_radius_size, border_radius_size);
FloatRoundedRect border_r_rect(border_rect, border_radius, border_radius,
border_radius, border_radius);
paint_info.context.SetStrokeThickness(
LayoutThemeMac::kSliderTrackBorderWidth);
PaintFlags border_flags(paint_info.context.StrokeFlags());
border_gradient->ApplyToFlags(border_flags, SkMatrix::I());
paint_info.context.DrawRRect(border_r_rect, border_flags);
return false;
}
bool ThemePainterMac::PaintSliderThumb(const Node* node,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
GraphicsContextStateSaver state_saver(paint_info.context);
float zoom_level = style.EffectiveZoom();
FloatRect unzoomed_rect(r.X(), r.Y(), LayoutThemeMac::kSliderThumbWidth,
LayoutThemeMac::kSliderThumbHeight);
if (zoom_level != 1.0f) {
paint_info.context.Translate(unzoomed_rect.X(), unzoomed_rect.Y());
paint_info.context.Scale(zoom_level, zoom_level);
paint_info.context.Translate(-unzoomed_rect.X(), -unzoomed_rect.Y());
}
Color fill_gradient_top_color(250, 250, 250);
Color fill_gradient_upper_middle_color(244, 244, 244);
Color fill_gradient_lower_middle_color(236, 236, 236);
Color fill_gradient_bottom_color(238, 238, 238);
Color border_gradient_top_color(151, 151, 151);
Color border_gradient_bottom_color(128, 128, 128);
Color shadow_color(0, 0, 0, 36);
if (!LayoutTheme::IsEnabled(node)) {
Color tint_color(255, 255, 255, 128);
fill_gradient_top_color = fill_gradient_top_color.Blend(tint_color);
fill_gradient_upper_middle_color =
fill_gradient_upper_middle_color.Blend(tint_color);
fill_gradient_lower_middle_color =
fill_gradient_lower_middle_color.Blend(tint_color);
fill_gradient_bottom_color = fill_gradient_bottom_color.Blend(tint_color);
border_gradient_top_color = border_gradient_top_color.Blend(tint_color);
border_gradient_bottom_color =
border_gradient_bottom_color.Blend(tint_color);
shadow_color = shadow_color.Blend(tint_color);
} else if (LayoutTheme::IsPressed(node)) {
Color tint_color(0, 0, 0, 32);
fill_gradient_top_color = fill_gradient_top_color.Blend(tint_color);
fill_gradient_upper_middle_color =
fill_gradient_upper_middle_color.Blend(tint_color);
fill_gradient_lower_middle_color =
fill_gradient_lower_middle_color.Blend(tint_color);
fill_gradient_bottom_color = fill_gradient_bottom_color.Blend(tint_color);
border_gradient_top_color = border_gradient_top_color.Blend(tint_color);
border_gradient_bottom_color =
border_gradient_bottom_color.Blend(tint_color);
shadow_color = shadow_color.Blend(tint_color);
}
FloatRect border_bounds = unzoomed_rect;
border_bounds.Inflate(LayoutThemeMac::kSliderThumbBorderWidth / 2.0);
border_bounds.Inflate(-LayoutThemeMac::kSliderThumbBorderWidth);
FloatSize shadow_offset(0, 1);
paint_info.context.SetShadow(
shadow_offset, LayoutThemeMac::kSliderThumbShadowBlur, shadow_color);
paint_info.context.SetFillColor(Color::kBlack);
paint_info.context.FillEllipse(border_bounds);
paint_info.context.SetDrawLooper(nullptr);
FloatRect fill_bounds = FloatRect(EnclosedIntRect(unzoomed_rect));
scoped_refptr<Gradient> fill_gradient = Gradient::CreateLinear(
fill_bounds.MinXMinYCorner(), fill_bounds.MinXMaxYCorner());
fill_gradient->AddColorStop(0.0, fill_gradient_top_color);
fill_gradient->AddColorStop(0.52, fill_gradient_upper_middle_color);
fill_gradient->AddColorStop(0.52, fill_gradient_lower_middle_color);
fill_gradient->AddColorStop(1.0, fill_gradient_bottom_color);
PaintFlags fill_flags(paint_info.context.FillFlags());
fill_gradient->ApplyToFlags(fill_flags, SkMatrix::I());
paint_info.context.DrawOval(border_bounds, fill_flags);
scoped_refptr<Gradient> border_gradient = Gradient::CreateLinear(
fill_bounds.MinXMinYCorner(), fill_bounds.MinXMaxYCorner());
border_gradient->AddColorStop(0.0, border_gradient_top_color);
border_gradient->AddColorStop(1.0, border_gradient_bottom_color);
paint_info.context.SetStrokeThickness(
LayoutThemeMac::kSliderThumbBorderWidth);
PaintFlags border_flags(paint_info.context.StrokeFlags());
border_gradient->ApplyToFlags(border_flags, SkMatrix::I());
paint_info.context.DrawOval(border_bounds, border_flags);
if (LayoutTheme::IsFocused(node)) {
Path border_path;
border_path.AddEllipse(border_bounds);
paint_info.context.DrawFocusRing(border_path, 5, -2,
layout_theme_.FocusRingColor());
}
return false;
}
// We don't use controlSizeForFont() for search field decorations because it
// needs to fit into the search field. The font size will already be modified by
// setFontFromControlSize() called on the search field.
static NSControlSize SearchFieldControlSizeForFont(const ComputedStyle& style) {
int font_size = style.FontSize();
if (font_size >= 13)
return NSRegularControlSize;
if (font_size >= 11)
return NSSmallControlSize;
return NSMiniControlSize;
}
bool ThemePainterMac::PaintSearchField(const Node* node,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& r) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
LocalCurrentGraphicsContext local_context(paint_info.context, r);
NSSearchFieldCell* search = layout_theme_.Search();
layout_theme_.SetSearchCellState(node, style, r);
[search setControlSize:SearchFieldControlSizeForFont(style)];
GraphicsContextStateSaver state_saver(paint_info.context);
float zoom_level = style.EffectiveZoom();
IntRect unzoomed_rect = r;
if (zoom_level != 1.0f) {
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / zoom_level);
paint_info.context.Translate(unzoomed_rect.X(), unzoomed_rect.Y());
paint_info.context.Scale(zoom_level, zoom_level);
paint_info.context.Translate(-unzoomed_rect.X(), -unzoomed_rect.Y());
}
// Set the search button to nil before drawing. Then reset it so we can
// draw it later.
[search setSearchButtonCell:nil];
[search drawWithFrame:NSRect(unzoomed_rect)
inView:layout_theme_.DocumentView()];
[search setControlView:nil];
[search resetSearchButtonCell];
return false;
}
bool ThemePainterMac::PaintSearchFieldCancelButton(
const LayoutObject& cancel_button,
const PaintInfo& paint_info,
const IntRect& r) {
if (!cancel_button.GetNode())
return false;
ScopedColorSchemeAppearance appearance(
cancel_button.StyleRef().UsedColorScheme());
GraphicsContextStateSaver state_saver(paint_info.context);
float zoom_level = cancel_button.StyleRef().EffectiveZoom();
FloatRect unzoomed_rect(r);
if (zoom_level != 1.0f) {
unzoomed_rect.SetWidth(unzoomed_rect.Width() / zoom_level);
unzoomed_rect.SetHeight(unzoomed_rect.Height() / zoom_level);
paint_info.context.Translate(unzoomed_rect.X(), unzoomed_rect.Y());
paint_info.context.Scale(zoom_level, zoom_level);
paint_info.context.Translate(-unzoomed_rect.X(), -unzoomed_rect.Y());
}
Color fill_color(200, 200, 200);
if (LayoutTheme::IsPressed(cancel_button.GetNode())) {
Color tint_color(0, 0, 0, 32);
fill_color = fill_color.Blend(tint_color);
}
float center_x = unzoomed_rect.X() + unzoomed_rect.Width() / 2;
float center_y = unzoomed_rect.Y() + unzoomed_rect.Height() / 2;
// The line width is 3px on a regular sized, high DPI NSCancelButtonCell
// (which is 28px wide).
float line_width = unzoomed_rect.Width() * 3 / 28;
// The line length is 16px on a regular sized, high DPI NSCancelButtonCell.
float line_length = unzoomed_rect.Width() * 16 / 28;
Path x_path;
FloatSize line_rect_radius(line_width / 2, line_width / 2);
x_path.AddRoundedRect(
FloatRect(-line_length / 2, -line_width / 2, line_length, line_width),
line_rect_radius, line_rect_radius, line_rect_radius, line_rect_radius);
x_path.AddRoundedRect(
FloatRect(-line_width / 2, -line_length / 2, line_width, line_length),
line_rect_radius, line_rect_radius, line_rect_radius, line_rect_radius);
paint_info.context.Translate(center_x, center_y);
paint_info.context.Rotate(deg2rad(45.0));
paint_info.context.ClipOut(x_path);
paint_info.context.Rotate(deg2rad(-45.0));
paint_info.context.Translate(-center_x, -center_y);
paint_info.context.SetFillColor(fill_color);
paint_info.context.FillEllipse(unzoomed_rect);
return false;
}
// FIXME: Share more code with radio buttons.
bool ThemePainterMac::PaintCheckbox(const Node* node,
const Document& document,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& zoomed_rect) {
BEGIN_BLOCK_OBJC_EXCEPTIONS
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
ControlStates states = LayoutTheme::ControlStatesForNode(node, style);
float zoom_factor = style.EffectiveZoom();
// Determine the width and height needed for the control and prepare the cell
// for painting.
NSButtonCell* checkbox_cell =
LayoutThemeMac::Checkbox(states, zoomed_rect, zoom_factor);
GraphicsContextStateSaver state_saver(paint_info.context);
NSControlSize control_size = [checkbox_cell controlSize];
IntSize zoomed_size = LayoutThemeMac::CheckboxSizes()[control_size];
zoomed_size.SetWidth(zoomed_size.Width() * zoom_factor);
zoomed_size.SetHeight(zoomed_size.Height() * zoom_factor);
IntRect inflated_rect = LayoutThemeMac::InflateRect(
zoomed_rect, zoomed_size, LayoutThemeMac::CheckboxMargins(control_size),
zoom_factor);
if (zoom_factor != 1.0f) {
inflated_rect.SetWidth(inflated_rect.Width() / zoom_factor);
inflated_rect.SetHeight(inflated_rect.Height() / zoom_factor);
paint_info.context.Translate(inflated_rect.X(), inflated_rect.Y());
paint_info.context.Scale(zoom_factor, zoom_factor);
paint_info.context.Translate(-inflated_rect.X(), -inflated_rect.Y());
}
LocalCurrentGraphicsContext local_context(
paint_info.context,
LayoutThemeMac::InflateRectForFocusRing(inflated_rect));
NSView* view = LayoutThemeMac::EnsuredView(document.View()->Size());
[checkbox_cell drawWithFrame:NSRect(inflated_rect) inView:view];
if (states & kFocusControlState)
[checkbox_cell cr_drawFocusRingWithFrame:NSRect(inflated_rect) inView:view];
[checkbox_cell setControlView:nil];
END_BLOCK_OBJC_EXCEPTIONS
return false;
}
bool ThemePainterMac::PaintRadio(const Node* node,
const Document& document,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& zoomed_rect) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
ControlStates states = LayoutTheme::ControlStatesForNode(node, style);
float zoom_factor = style.EffectiveZoom();
// Determine the width and height needed for the control and prepare the cell
// for painting.
NSButtonCell* radio_cell =
LayoutThemeMac::Radio(states, zoomed_rect, zoom_factor);
GraphicsContextStateSaver state_saver(paint_info.context);
NSControlSize control_size = [radio_cell controlSize];
IntSize zoomed_size = LayoutThemeMac::RadioSizes()[control_size];
zoomed_size.SetWidth(zoomed_size.Width() * zoom_factor);
zoomed_size.SetHeight(zoomed_size.Height() * zoom_factor);
IntRect inflated_rect = LayoutThemeMac::InflateRect(
zoomed_rect, zoomed_size, LayoutThemeMac::RadioMargins(control_size),
zoom_factor);
if (zoom_factor != 1.0f) {
inflated_rect.SetWidth(inflated_rect.Width() / zoom_factor);
inflated_rect.SetHeight(inflated_rect.Height() / zoom_factor);
paint_info.context.Translate(inflated_rect.X(), inflated_rect.Y());
paint_info.context.Scale(zoom_factor, zoom_factor);
paint_info.context.Translate(-inflated_rect.X(), -inflated_rect.Y());
}
LocalCurrentGraphicsContext local_context(
paint_info.context,
LayoutThemeMac::InflateRectForFocusRing(inflated_rect));
BEGIN_BLOCK_OBJC_EXCEPTIONS
NSView* view = LayoutThemeMac::EnsuredView(document.View()->Size());
[radio_cell drawWithFrame:NSRect(inflated_rect) inView:view];
if (states & kFocusControlState)
[radio_cell cr_drawFocusRingWithFrame:NSRect(inflated_rect) inView:view];
[radio_cell setControlView:nil];
END_BLOCK_OBJC_EXCEPTIONS
return false;
}
bool ThemePainterMac::PaintButton(const Node* node,
const Document& document,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& zoomed_rect) {
BEGIN_BLOCK_OBJC_EXCEPTIONS
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
ControlStates states = LayoutTheme::ControlStatesForNode(node, style);
float zoom_factor = style.EffectiveZoom();
// Determine the width and height needed for the control and prepare the cell
// for painting.
NSButtonCell* button_cell = LayoutThemeMac::Button(
style.EffectiveAppearance(), states, zoomed_rect, zoom_factor);
GraphicsContextStateSaver state_saver(paint_info.context);
NSControlSize control_size = [button_cell controlSize];
IntSize zoomed_size = LayoutThemeMac::ButtonSizes()[control_size];
// Buttons don't ever constrain width, so the zoomed width can just be
// honored.
zoomed_size.SetWidth(zoomed_rect.Width());
zoomed_size.SetHeight(zoomed_size.Height() * zoom_factor);
IntRect inflated_rect = zoomed_rect;
if ([button_cell bezelStyle] == NSRoundedBezelStyle) {
// Center the button within the available space.
if (inflated_rect.Height() > zoomed_size.Height()) {
inflated_rect.SetY(inflated_rect.Y() +
(inflated_rect.Height() - zoomed_size.Height()) / 2);
inflated_rect.SetHeight(zoomed_size.Height());
}
// Now inflate it to account for the shadow.
inflated_rect = LayoutThemeMac::InflateRect(
inflated_rect, zoomed_size, LayoutThemeMac::ButtonMargins(control_size),
zoom_factor);
if (zoom_factor != 1.0f) {
inflated_rect.SetWidth(inflated_rect.Width() / zoom_factor);
inflated_rect.SetHeight(inflated_rect.Height() / zoom_factor);
paint_info.context.Translate(inflated_rect.X(), inflated_rect.Y());
paint_info.context.Scale(zoom_factor, zoom_factor);
paint_info.context.Translate(-inflated_rect.X(), -inflated_rect.Y());
}
}
LocalCurrentGraphicsContext local_context(
paint_info.context,
LayoutThemeMac::InflateRectForFocusRing(inflated_rect));
NSView* view = LayoutThemeMac::EnsuredView(document.View()->Size());
[button_cell drawWithFrame:NSRect(inflated_rect) inView:view];
if (states & kFocusControlState)
[button_cell cr_drawFocusRingWithFrame:NSRect(inflated_rect) inView:view];
[button_cell setControlView:nil];
END_BLOCK_OBJC_EXCEPTIONS
return false;
}
static ThemeDrawState ConvertControlStatesToThemeDrawState(
ThemeButtonKind kind,
ControlStates states) {
if (states & kReadOnlyControlState)
return kThemeStateUnavailableInactive;
if (!(states & kEnabledControlState))
return kThemeStateUnavailableInactive;
// Do not process PressedState if !EnabledControlState or
// ReadOnlyControlState.
if (states & kPressedControlState) {
if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall ||
kind == kThemeIncDecButtonMini)
return states & kSpinUpControlState ? kThemeStatePressedUp
: kThemeStatePressedDown;
return kThemeStatePressed;
}
return kThemeStateActive;
}
bool ThemePainterMac::PaintInnerSpinButton(const Node* node,
const ComputedStyle& style,
const PaintInfo& paint_info,
const IntRect& zoomed_rect) {
ScopedColorSchemeAppearance appearance(style.UsedColorScheme());
ControlStates states = LayoutTheme::ControlStatesForNode(node, style);
float zoom_factor = style.EffectiveZoom();
// We don't use NSStepperCell because there are no ways to draw an
// NSStepperCell with the up button highlighted.
HIThemeButtonDrawInfo draw_info;
draw_info.version = 0;
draw_info.state =
ConvertControlStatesToThemeDrawState(kThemeIncDecButton, states);
draw_info.adornment = kThemeAdornmentDefault;
ControlSize control_size = LayoutThemeMac::ControlSizeFromPixelSize(
LayoutThemeMac::StepperSizes(), zoomed_rect.Size(), zoom_factor);
if (control_size == NSSmallControlSize)
draw_info.kind = kThemeIncDecButtonSmall;
else if (control_size == NSMiniControlSize)
draw_info.kind = kThemeIncDecButtonMini;
else
draw_info.kind = kThemeIncDecButton;
IntRect rect(zoomed_rect);
GraphicsContextStateSaver state_saver(paint_info.context);
if (zoom_factor != 1.0f) {
rect.SetWidth(rect.Width() / zoom_factor);
rect.SetHeight(rect.Height() / zoom_factor);
paint_info.context.Translate(rect.X(), rect.Y());
paint_info.context.Scale(zoom_factor, zoom_factor);
paint_info.context.Translate(-rect.X(), -rect.Y());
}
CGRect bounds(rect);
CGRect background_bounds;
HIThemeGetButtonBackgroundBounds(&bounds, &draw_info, &background_bounds);
// Center the stepper rectangle in the specified area.
background_bounds.origin.x =
bounds.origin.x + (bounds.size.width - background_bounds.size.width) / 2;
if (background_bounds.size.height < bounds.size.height) {
int height_diff =
clampTo<int>(bounds.size.height - background_bounds.size.height);
background_bounds.origin.y = bounds.origin.y + (height_diff / 2) + 1;
}
LocalCurrentGraphicsContext local_context(paint_info.context, rect);
HIThemeDrawButton(&background_bounds, &draw_info, local_context.CgContext(),
kHIThemeOrientationNormal, 0);
return false;
}
} // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment