diff options
author | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 13:31:18 +0000 |
---|---|---|
committer | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-16 13:31:18 +0000 |
commit | 990e62268f8a7074995ea00895da064312e49535 (patch) | |
tree | 6447bc15cd3e2f728b7351b27571a3c6da35ae41 | |
parent | 8d0f9016803d12e160b588cca2a7fc4612323aad (diff) | |
download | chromium_src-990e62268f8a7074995ea00895da064312e49535.zip chromium_src-990e62268f8a7074995ea00895da064312e49535.tar.gz chromium_src-990e62268f8a7074995ea00895da064312e49535.tar.bz2 |
ui: Make native_theme its own library.
BUG=103304
R=sky@chromium.org
Review URL: https://chromiumcodereview.appspot.com/11275322
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168194 0039d316-1c4b-4281-b951-d872f2087c98
68 files changed, 4595 insertions, 88 deletions
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 1cf9767..03e3d4a 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -34,8 +34,8 @@ #include "chrome/browser/ui/search/search_types.h" #include "chrome/browser/ui/tab_contents/tab_contents.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/browser_dialogs.h" #include "chrome/browser/ui/views/bookmarks/bookmark_prompt_view.h" +#include "chrome/browser/ui/views/browser_dialogs.h" #include "chrome/browser/ui/views/extensions/extension_popup.h" #include "chrome/browser/ui/views/location_bar/action_box_button_view.h" #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" @@ -79,7 +79,7 @@ #include "ui/views/widget/widget.h" #if defined(OS_WIN) -#include "ui/base/native_theme/native_theme_win.h" +#include "ui/native_theme/native_theme_win.h" #endif #if defined(OS_WIN) && !defined(USE_AURA) @@ -88,7 +88,7 @@ #if !defined(OS_CHROMEOS) #include "chrome/browser/ui/views/first_run_bubble.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #endif #if defined(USE_AURA) diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index f301244..7d199b2 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc @@ -21,19 +21,19 @@ #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/text_elider.h" #include "ui/gfx/canvas.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/render_text.h" +#include "ui/native_theme/native_theme.h" #if defined(OS_WIN) -#include "ui/base/native_theme/native_theme_win.h" +#include "ui/native_theme/native_theme_win.h" #endif #if defined(USE_AURA) -#include "ui/base/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_aura.h" #endif namespace { diff --git a/chrome/browser/ui/views/status_bubble_views.cc b/chrome/browser/ui/views/status_bubble_views.cc index 309faee..225faf1 100644 --- a/chrome/browser/ui/views/status_bubble_views.cc +++ b/chrome/browser/ui/views/status_bubble_views.cc @@ -21,13 +21,13 @@ #include "third_party/skia/include/core/SkRect.h" #include "ui/base/animation/animation_delegate.h" #include "ui/base/animation/linear_animation.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/text_elider.h" #include "ui/gfx/canvas.h" #include "ui/gfx/point.h" #include "ui/gfx/screen.h" #include "ui/gfx/skia_util.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/label.h" #include "ui/views/controls/scrollbar/native_scroll_bar.h" #include "ui/views/widget/root_view.h" diff --git a/chrome/browser/ui/views/toolbar_view.cc b/chrome/browser/ui/views/toolbar_view.cc index 5162a91..89e9c7d 100644 --- a/chrome/browser/ui/views/toolbar_view.cc +++ b/chrome/browser/ui/views/toolbar_view.cc @@ -68,8 +68,8 @@ #if defined(USE_AURA) #include "ui/aura/window.h" -#include "ui/base/native_theme/native_theme_aura.h" #include "ui/compositor/layer.h" +#include "ui/native_theme/native_theme_aura.h" #endif using content::UserMetricsAction; diff --git a/chrome/browser/ui/views/wrench_menu.cc b/chrome/browser/ui/views/wrench_menu.cc index 47df499..cefdcf4 100644 --- a/chrome/browser/ui/views/wrench_menu.cc +++ b/chrome/browser/ui/views/wrench_menu.cc @@ -53,7 +53,7 @@ #include "ui/views/widget/widget.h" #if defined(USE_AURA) -#include "ui/base/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_aura.h" #endif using content::HostZoomMap; diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index fb145d3..46eeb7f0 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -50,6 +50,7 @@ '../third_party/libxml/libxml.gyp:libxml', '../third_party/zlib/zlib.gyp:zlib', '../ui/base/strings/ui_strings.gyp:ui_strings', + '../ui/native_theme/native_theme.gyp:native_theme', '../ui/ui.gyp:ui', '../ui/ui.gyp:ui_resources', '../webkit/support/webkit_support.gyp:user_agent', diff --git a/content/DEPS b/content/DEPS index 2584f77..db04ce4 100644 --- a/content/DEPS +++ b/content/DEPS @@ -55,6 +55,7 @@ include_rules = [ "+ui/compositor", "+ui/gfx", "+ui/gl", + "+ui/native_theme", "+ui/surface", # Content knows about grd files, but the specifics of how to get a resource # given its id is left to the embedder. diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 7d3bb02..516dfae 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -16,6 +16,7 @@ '../third_party/libjingle/libjingle.gyp:libjingle', '../third_party/npapi/npapi.gyp:npapi', '<(webkit_src_dir)/Source/WebKit/chromium/WebKit.gyp:webkit', + '../ui/native_theme/native_theme.gyp:native_theme', '../ui/surface/surface.gyp:surface', '../v8/tools/gyp/v8.gyp:v8', '../webkit/support/webkit_support.gyp:glue', diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 8bccb4f..561cc9b 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -217,10 +217,10 @@ #elif defined(OS_WIN) // TODO(port): these files are currently Windows only because they concern: // * theming -#include "ui/base/native_theme/native_theme_win.h" +#include "ui/native_theme/native_theme_win.h" #elif defined(USE_X11) #include "third_party/WebKit/Source/WebKit/chromium/public/linux/WebRenderTheme.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #elif defined(OS_MACOSX) #include "skia/ext/skia_utils_mac.h" #endif diff --git a/ui/native_theme/native_theme.cc b/ui/native_theme/native_theme.cc new file mode 100644 index 0000000..85b58e9 --- /dev/null +++ b/ui/native_theme/native_theme.cc @@ -0,0 +1,26 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme.h" + +namespace ui { + +NativeTheme::NativeTheme() + : thumb_inactive_color_(0xeaeaea), + thumb_active_color_(0xf4f4f4), + track_color_(0xd3d3d3) { +} + +void NativeTheme::SetScrollbarColors(unsigned inactive_color, + unsigned active_color, + unsigned track_color) { + thumb_inactive_color_ = inactive_color; + thumb_active_color_ = active_color; + track_color_ = track_color; +} + +// NativeTheme::instance() is implemented in the platform specific source files, +// such as native_theme_win.cc or native_theme_linux.cc + +} // namespace ui diff --git a/ui/native_theme/native_theme.gyp b/ui/native_theme/native_theme.gyp new file mode 100644 index 0000000..c236a97 --- /dev/null +++ b/ui/native_theme/native_theme.gyp @@ -0,0 +1,39 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'native_theme', + 'type': '<(component)', + 'dependencies': [ + '../../base/base.gyp:base', + '../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../../skia/skia.gyp:skia', + '../ui.gyp:ui', + '../ui.gyp:ui_resources', + ], + 'defines': [ + 'NATIVE_THEME_IMPLEMENTATION', + ], + 'sources': [ + 'native_theme.cc', + 'native_theme.h', + 'native_theme_android.cc', + 'native_theme_android.h', + 'native_theme_aura.cc', + 'native_theme_aura.h', + 'native_theme_base.cc', + 'native_theme_base.h', + 'native_theme_gtk.cc', + 'native_theme_gtk.h', + 'native_theme_win.cc', + 'native_theme_win.h', + ], + }, + ], +} diff --git a/ui/native_theme/native_theme.h b/ui/native_theme/native_theme.h new file mode 100644 index 0000000..b3b9fc3 --- /dev/null +++ b/ui/native_theme/native_theme.h @@ -0,0 +1,273 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_H_ + +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/native_widget_types.h" +#include "ui/native_theme/native_theme_export.h" + +class SkCanvas; + +namespace gfx { +class Rect; +class Size; +} + +namespace ui { + +// This class supports drawing UI controls (like buttons, text fields, lists, +// comboboxes, etc) that look like the native UI controls of the underlying +// platform, such as Windows or Linux. It also supplies default colors for +// dialog box backgrounds, etc., which are obtained from the system theme where +// possible. +// +// The supported control types are listed in the Part enum. These parts can be +// in any state given by the State enum, where the actual definition of the +// state is part-specific. The supported colors are listed in the ColorId enum. +// +// Some parts require more information than simply the state in order to be +// drawn correctly, and this information is given to the Paint() method via the +// ExtraParams union. Each part that requires more information has its own +// field in the union. +// +// NativeTheme also supports getting the default size of a given part with +// the GetPartSize() method. +class NATIVE_THEME_EXPORT NativeTheme { + public: + // The part to be painted / sized. + enum Part { + kCheckbox, + kInnerSpinButton, + kMenuList, + kMenuCheck, + kMenuCheckBackground, + kMenuPopupArrow, + kMenuPopupBackground, + kMenuPopupGutter, + kMenuPopupSeparator, + kMenuItemBackground, + kProgressBar, + kPushButton, + kRadio, + + // The order of the arrow enums is important, do not change without also + // changing the code in platform implementations. + kScrollbarDownArrow, + kScrollbarLeftArrow, + kScrollbarRightArrow, + kScrollbarUpArrow, + + kScrollbarHorizontalThumb, + kScrollbarVerticalThumb, + kScrollbarHorizontalTrack, + kScrollbarVerticalTrack, + kScrollbarHorizontalGripper, + kScrollbarVerticalGripper, + kSliderTrack, + kSliderThumb, + kTabPanelBackground, + kTextField, + kTrackbarThumb, + kTrackbarTrack, + kWindowResizeGripper, + kMaxPart, + }; + + // The state of the part. + enum State { + kDisabled, + kHovered, + kNormal, + kPressed, + kMaxState, + }; + + // Each structure below holds extra information needed when painting a given + // part. + + struct ButtonExtraParams { + bool checked; + bool indeterminate; // Whether the button state is indeterminate. + bool is_default; // Whether the button is default button. + bool is_focused; + bool has_border; + int classic_state; // Used on Windows when uxtheme is not available. + SkColor background_color; + }; + + struct InnerSpinButtonExtraParams { + bool spin_up; + bool read_only; + int classic_state; // Used on Windows when uxtheme is not available. + }; + + struct MenuArrowExtraParams { + bool pointing_right; + // Used for the disabled state to indicate if the item is both disabled and + // selected. + bool is_selected; + }; + + struct MenuCheckExtraParams { + bool is_radio; + // Used for the disabled state to indicate if the item is both disabled and + // selected. + bool is_selected; + }; + + struct MenuItemExtraParams { + bool is_selected; + }; + + struct MenuListExtraParams { + bool has_border; + bool has_border_radius; + int arrow_x; + int arrow_y; + SkColor background_color; + int classic_state; // Used on Windows when uxtheme is not available. + }; + + struct MenuSeparatorExtraParams { + bool has_gutter; + }; + + struct ProgressBarExtraParams { + double animated_seconds; + bool determinate; + int value_rect_x; + int value_rect_y; + int value_rect_width; + int value_rect_height; + }; + + struct ScrollbarArrowExtraParams { + bool is_hovering; + }; + + struct ScrollbarTrackExtraParams { + bool is_upper; + int track_x; + int track_y; + int track_width; + int track_height; + int classic_state; // Used on Windows when uxtheme is not available. + }; + + struct ScrollbarThumbExtraParams { + bool is_hovering; + }; + + struct SliderExtraParams { + bool vertical; + bool in_drag; + }; + + struct TextFieldExtraParams { + bool is_text_area; + bool is_listbox; + SkColor background_color; + bool is_read_only; + bool is_focused; + bool fill_content_area; + bool draw_edges; + int classic_state; // Used on Windows when uxtheme is not available. + }; + + struct TrackbarExtraParams { + bool vertical; + int classic_state; // Used on Windows when uxtheme is not available. + }; + + union ExtraParams { + ButtonExtraParams button; + InnerSpinButtonExtraParams inner_spin; + MenuArrowExtraParams menu_arrow; + MenuCheckExtraParams menu_check; + MenuItemExtraParams menu_item; + MenuListExtraParams menu_list; + MenuSeparatorExtraParams menu_separator; + ProgressBarExtraParams progress_bar; + ScrollbarArrowExtraParams scrollbar_arrow; + ScrollbarTrackExtraParams scrollbar_track; + ScrollbarThumbExtraParams scrollbar_thumb; + SliderExtraParams slider; + TextFieldExtraParams text_field; + TrackbarExtraParams trackbar; + }; + + // Return the size of the part. + virtual gfx::Size GetPartSize(Part part, + State state, + const ExtraParams& extra) const = 0; + + // Paint the part to the canvas. + virtual void Paint(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const = 0; + + // Supports theme specific colors. + void SetScrollbarColors(unsigned inactive_color, + unsigned active_color, + unsigned track_color); + + // Colors for GetSystemColor(). + enum ColorId { + // Dialogs + kColorId_DialogBackground, + // FocusableBorder + kColorId_FocusedBorderColor, + kColorId_UnfocusedBorderColor, + // TextButton + kColorId_TextButtonBackgroundColor, + kColorId_TextButtonEnabledColor, + kColorId_TextButtonDisabledColor, + kColorId_TextButtonHighlightColor, + kColorId_TextButtonHoverColor, + // MenuItem + kColorId_EnabledMenuItemForegroundColor, + kColorId_DisabledMenuItemForegroundColor, + kColorId_FocusedMenuItemBackgroundColor, + kColorId_MenuSeparatorColor, + // Label + kColorId_LabelEnabledColor, + kColorId_LabelDisabledColor, + kColorId_LabelBackgroundColor, + // Textfield + kColorId_TextfieldDefaultColor, + kColorId_TextfieldDefaultBackground, + kColorId_TextfieldSelectionColor, + kColorId_TextfieldSelectionBackgroundFocused, + kColorId_TextfieldSelectionBackgroundUnfocused, + // TODO(benrg): move other hardcoded colors here. + }; + + // Return a color from the system theme. + virtual SkColor GetSystemColor(ColorId color_id) const = 0; + + // Returns a shared instance of the native theme. + // The returned object should not be deleted by the caller. This function + // is not thread safe and should only be called from the UI thread. + // Each port of NativeTheme should provide its own implementation of this + // function, returning the port's subclass. + static NativeTheme* instance(); + + protected: + NativeTheme(); + virtual ~NativeTheme() {} + + unsigned int thumb_inactive_color_; + unsigned int thumb_active_color_; + unsigned int track_color_; + + DISALLOW_COPY_AND_ASSIGN(NativeTheme); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_H_ diff --git a/ui/native_theme/native_theme_android.cc b/ui/native_theme/native_theme_android.cc new file mode 100644 index 0000000..884bc7e --- /dev/null +++ b/ui/native_theme/native_theme_android.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_android.h" + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace ui { + +// static +NativeTheme* NativeTheme::instance() { + return NativeThemeAndroid::instance(); +} + +// static +NativeThemeAndroid* NativeThemeAndroid::instance() { + CR_DEFINE_STATIC_LOCAL(NativeThemeAndroid, s_native_theme, ()); + return &s_native_theme; +} + +SkColor NativeThemeAndroid::GetSystemColor(ColorId color_id) const { + NOTIMPLEMENTED(); + return SK_ColorBLACK; +} + +NativeThemeAndroid::NativeThemeAndroid() { +} + +NativeThemeAndroid::~NativeThemeAndroid() { +} + +} // namespace ui diff --git a/ui/native_theme/native_theme_android.h b/ui/native_theme/native_theme_android.h new file mode 100644 index 0000000..e1d2f78 --- /dev/null +++ b/ui/native_theme/native_theme_android.h @@ -0,0 +1,28 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_ANDROID_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_ANDROID_H_ + +#include "ui/native_theme/native_theme_base.h" + +namespace ui { + +// Android implementation of native theme support. +class NativeThemeAndroid : public NativeThemeBase { + public: + static NativeThemeAndroid* instance(); + + virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE; + + private: + NativeThemeAndroid(); + virtual ~NativeThemeAndroid(); + + DISALLOW_COPY_AND_ASSIGN(NativeThemeAndroid); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_ANDROID_H_ diff --git a/ui/native_theme/native_theme_aura.cc b/ui/native_theme/native_theme_aura.cc new file mode 100644 index 0000000..dbc310d --- /dev/null +++ b/ui/native_theme/native_theme_aura.cc @@ -0,0 +1,296 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_aura.h" + +#include "base/logging.h" +#include "grit/ui_resources.h" +#include "ui/base/layout.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/size.h" +#include "ui/gfx/skbitmap_operations.h" + +namespace { + +const SkColor kMenuBackgroundColor = SK_ColorWHITE; + +// Theme colors returned by GetSystemColor(). +const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128); +// Dialogs: +const SkColor kDialogBackgroundColor = SK_ColorWHITE; +// FocusableBorder: +const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE); +const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9); +// TextButton: +const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xDE, 0xDE, 0xDE); +const SkColor kTextButtonEnabledColor = SkColorSetRGB(0x22, 0x22, 0x22); +const SkColor kTextButtonDisabledColor = SkColorSetRGB(0x99, 0x99, 0x99); +const SkColor kTextButtonHighlightColor = SkColorSetRGB(0, 0, 0); +const SkColor kTextButtonHoverColor = kTextButtonEnabledColor; +// MenuItem: +const SkColor kEnabledMenuItemForegroundColor = kTextButtonEnabledColor; +const SkColor kDisabledMenuItemForegroundColor = kTextButtonDisabledColor; +const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(0xF1, 0xF1, 0xF1); +const SkColor kMenuSeparatorColor = SkColorSetRGB(0xED, 0xED, 0xED); +// Label: +const SkColor kLabelEnabledColor = kTextButtonEnabledColor; +const SkColor kLabelDisabledColor = kTextButtonDisabledColor; +const SkColor kLabelBackgroundColor = SK_ColorWHITE; +// Textfield: +const SkColor kTextfieldDefaultColor = SK_ColorBLACK; +const SkColor kTextfieldDefaultBackground = SK_ColorWHITE; +const SkColor kTextfieldSelectionBackgroundFocused = + SkColorSetARGB(0x54, 0x60, 0xA8, 0xEB); +const SkColor kTextfieldSelectionBackgroundUnfocused = SK_ColorLTGRAY; +const SkColor kTextfieldSelectionColor = + color_utils::AlphaBlend(SK_ColorBLACK, + kTextfieldSelectionBackgroundFocused, 0xdd); + +} // namespace + +namespace ui { + +// static +NativeTheme* NativeTheme::instance() { + return NativeThemeAura::instance(); +} + +// static +NativeThemeAura* NativeThemeAura::instance() { + CR_DEFINE_STATIC_LOCAL(NativeThemeAura, s_native_theme, ()); + return &s_native_theme; +} + +NativeThemeAura::NativeThemeAura() { + // We don't draw scrollbar buttons. + set_scrollbar_button_length(0); +} + +NativeThemeAura::~NativeThemeAura() { +} + +SkColor NativeThemeAura::GetSystemColor(ColorId color_id) const { + // This implementation returns hardcoded colors. + switch (color_id) { + + // Dialogs + case kColorId_DialogBackground: + return kDialogBackgroundColor; + + // FocusableBorder + case kColorId_FocusedBorderColor: + return kFocusedBorderColor; + case kColorId_UnfocusedBorderColor: + return kUnfocusedBorderColor; + + // TextButton + case kColorId_TextButtonBackgroundColor: + return kTextButtonBackgroundColor; + case kColorId_TextButtonEnabledColor: + return kTextButtonEnabledColor; + case kColorId_TextButtonDisabledColor: + return kTextButtonDisabledColor; + case kColorId_TextButtonHighlightColor: + return kTextButtonHighlightColor; + case kColorId_TextButtonHoverColor: + return kTextButtonHoverColor; + + // MenuItem + case kColorId_EnabledMenuItemForegroundColor: + return kEnabledMenuItemForegroundColor; + case kColorId_DisabledMenuItemForegroundColor: + return kDisabledMenuItemForegroundColor; + case kColorId_FocusedMenuItemBackgroundColor: + return kFocusedMenuItemBackgroundColor; + case kColorId_MenuSeparatorColor: + return kMenuSeparatorColor; + + // Label + case kColorId_LabelEnabledColor: + return kLabelEnabledColor; + case kColorId_LabelDisabledColor: + return kLabelDisabledColor; + case kColorId_LabelBackgroundColor: + return kLabelBackgroundColor; + + // Textfield + case kColorId_TextfieldDefaultColor: + return kTextfieldDefaultColor; + case kColorId_TextfieldDefaultBackground: + return kTextfieldDefaultBackground; + case kColorId_TextfieldSelectionColor: + return kTextfieldSelectionColor; + case kColorId_TextfieldSelectionBackgroundFocused: + return kTextfieldSelectionBackgroundFocused; + case kColorId_TextfieldSelectionBackgroundUnfocused: + return kTextfieldSelectionBackgroundUnfocused; + + default: + NOTREACHED() << "Invalid color_id: " << color_id; + break; + } + + return kInvalidColorIdColor; +} + +void NativeThemeAura::PaintMenuPopupBackground(SkCanvas* canvas, + const gfx::Size& size) const { + canvas->drawColor(kMenuBackgroundColor, SkXfermode::kSrc_Mode); +} + +void NativeThemeAura::PaintScrollbarTrack( + SkCanvas* canvas, + Part part, + State state, + const ScrollbarTrackExtraParams& extra_params, + const gfx::Rect& rect) const { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + if (part == kScrollbarVerticalTrack) { + int center_offset = 0; + int center_height = rect.height(); + + if (rect.y() == extra_params.track_y) { + // TODO(derat): Honor |state| instead of only using the highlighted images + // after updating WebKit so we can draw the entire track in one go instead + // of as two separate pieces: otherwise, only the portion of the scrollbar + // that the mouse is over gets the highlighted state. + gfx::ImageSkia* top = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_VERTICAL_TOP_H); + DrawTiledImage(canvas, *top, + 0, 0, 1.0, 1.0, + rect.x(), rect.y(), top->width(), top->height()); + center_offset += top->height(); + center_height -= top->height(); + } + + if (rect.y() + rect.height() == + extra_params.track_y + extra_params.track_height) { + gfx::ImageSkia* bottom = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_VERTICAL_BOTTOM_H); + DrawTiledImage(canvas, *bottom, + 0, 0, 1.0, 1.0, + rect.x(), rect.y() + rect.height() - bottom->height(), + bottom->width(), bottom->height()); + center_height -= bottom->height(); + } + + if (center_height > 0) { + gfx::ImageSkia* center = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_VERTICAL_CENTER_H); + DrawTiledImage(canvas, *center, + 0, 0, 1.0, 1.0, + rect.x(), rect.y() + center_offset, + center->width(), center_height); + } + } else { + int center_offset = 0; + int center_width = rect.width(); + + if (rect.x() == extra_params.track_x) { + gfx::ImageSkia* left = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_HORIZONTAL_LEFT_H); + DrawTiledImage(canvas, *left, + 0, 0, 1.0, 1.0, + rect.x(), rect.y(), left->width(), left->height()); + center_offset += left->width(); + center_width -= left->width(); + } + + if (rect.x() + rect.width() == + extra_params.track_x + extra_params.track_width) { + gfx::ImageSkia* right = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_HORIZONTAL_RIGHT_H); + DrawTiledImage(canvas, *right, + 0, 0, 1.0, 1.0, + rect.x() + rect.width() - right->width(), rect.y(), + right->width(), right->height()); + center_width -= right->width(); + } + + if (center_width > 0) { + gfx::ImageSkia* center = rb.GetImageSkiaNamed( + IDR_SCROLL_BASE_HORIZONTAL_CENTER_H); + DrawTiledImage(canvas, *center, + 0, 0, 1.0, 1.0, + rect.x() + center_offset, rect.y(), + center_width, center->height()); + } + } +} + +void NativeThemeAura::PaintScrollbarThumb(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect) const { + ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); + if (part == kScrollbarVerticalThumb) { + int top_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_TOP_H : + state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_TOP_P : + IDR_SCROLL_THUMB_VERTICAL_TOP; + gfx::ImageSkia* top = rb.GetImageSkiaNamed(top_resource_id); + DrawTiledImage(canvas, *top, + 0, 0, 1.0, 1.0, + rect.x(), rect.y(), top->width(), top->height()); + + int bottom_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_BOTTOM_H : + state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_BOTTOM_P : + IDR_SCROLL_THUMB_VERTICAL_BOTTOM; + gfx::ImageSkia* bottom = rb.GetImageSkiaNamed(bottom_resource_id); + DrawTiledImage(canvas, *bottom, + 0, 0, 1.0, 1.0, + rect.x(), rect.y() + rect.height() - bottom->height(), + bottom->width(), bottom->height()); + + if (rect.height() > top->height() + bottom->height()) { + int center_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_VERTICAL_CENTER_H : + state == kPressed ? IDR_SCROLL_THUMB_VERTICAL_CENTER_P : + IDR_SCROLL_THUMB_VERTICAL_CENTER; + gfx::ImageSkia* center = rb.GetImageSkiaNamed(center_resource_id); + DrawTiledImage(canvas, *center, + 0, 0, 1.0, 1.0, + rect.x(), rect.y() + top->height(), + center->width(), + rect.height() - top->height() - bottom->height()); + } + } else { + int left_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_LEFT_H : + state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_LEFT_P : + IDR_SCROLL_THUMB_HORIZONTAL_LEFT; + gfx::ImageSkia* left = rb.GetImageSkiaNamed(left_resource_id); + DrawTiledImage(canvas, *left, + 0, 0, 1.0, 1.0, + rect.x(), rect.y(), left->width(), left->height()); + + int right_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_RIGHT_H : + state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_RIGHT_P : + IDR_SCROLL_THUMB_HORIZONTAL_RIGHT; + gfx::ImageSkia* right = rb.GetImageSkiaNamed(right_resource_id); + DrawTiledImage(canvas, *right, + 0, 0, 1.0, 1.0, + rect.x() + rect.width() - right->width(), rect.y(), + right->width(), right->height()); + + if (rect.width() > left->width() + right->width()) { + int center_resource_id = + state == kHovered ? IDR_SCROLL_THUMB_HORIZONTAL_CENTER_H : + state == kPressed ? IDR_SCROLL_THUMB_HORIZONTAL_CENTER_P : + IDR_SCROLL_THUMB_HORIZONTAL_CENTER; + gfx::ImageSkia* center = rb.GetImageSkiaNamed(center_resource_id); + DrawTiledImage(canvas, *center, + 0, 0, 1.0, 1.0, + rect.x() + left->width(), rect.y(), + rect.width() - left->width() - right->width(), + center->height()); + } + } +} + +} // namespace ui diff --git a/ui/native_theme/native_theme_aura.h b/ui/native_theme/native_theme_aura.h new file mode 100644 index 0000000..d1d3d0d --- /dev/null +++ b/ui/native_theme/native_theme_aura.h @@ -0,0 +1,43 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_AURA_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_AURA_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ui/native_theme/native_theme_base.h" + +namespace ui { + +// Aura implementation of native theme support. +class NATIVE_THEME_EXPORT NativeThemeAura : public NativeThemeBase { + public: + static NativeThemeAura* instance(); + + private: + NativeThemeAura(); + virtual ~NativeThemeAura(); + + // Overridden from NativeThemeBase: + virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE; + virtual void PaintMenuPopupBackground(SkCanvas* canvas, + const gfx::Size& size) const OVERRIDE; + virtual void PaintScrollbarTrack( + SkCanvas* canvas, + Part part, + State state, + const ScrollbarTrackExtraParams& extra_params, + const gfx::Rect& rect) const OVERRIDE; + virtual void PaintScrollbarThumb(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect) const OVERRIDE; + + DISALLOW_COPY_AND_ASSIGN(NativeThemeAura); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_AURA_H_ diff --git a/ui/native_theme/native_theme_base.cc b/ui/native_theme/native_theme_base.cc new file mode 100644 index 0000000..fa6151f --- /dev/null +++ b/ui/native_theme/native_theme_base.cc @@ -0,0 +1,1138 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_base.h" + +#include <limits> + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "grit/ui_resources.h" +#include "third_party/skia/include/effects/SkGradientShader.h" +#include "ui/base/layout.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/base/ui_base_switches.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/size.h" +#include "ui/gfx/skia_util.h" + +namespace { + +// These are the default dimensions of radio buttons and checkboxes. +const int kCheckboxAndRadioWidth = 13; +const int kCheckboxAndRadioHeight = 13; + +// These sizes match the sizes in Chromium Win. +const int kSliderThumbWidth = 11; +const int kSliderThumbHeight = 21; + +const SkColor kSliderTrackBackgroundColor = + SkColorSetRGB(0xe3, 0xdd, 0xd8); +const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef); +const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0); +const SkColor kSliderThumbBorderDarkGrey = + SkColorSetRGB(0x9d, 0x96, 0x8e); + +const SkColor kMenuPopupBackgroundColor = SkColorSetRGB(210, 225, 246); + +const unsigned int kDefaultScrollbarWidth = 15; +const unsigned int kDefaultScrollbarButtonLength = 14; + +const SkColor kCheckboxTinyColor = SK_ColorGRAY; +const SkColor kCheckboxShadowColor = SkColorSetARGB(0x15, 0, 0, 0); +const SkColor kCheckboxShadowHoveredColor = SkColorSetARGB(0x1F, 0, 0, 0); +const SkColor kCheckboxShadowDisabledColor = SkColorSetARGB(0, 0, 0, 0); +const SkColor kCheckboxGradientColors[] = { + SkColorSetRGB(0xed, 0xed, 0xed), + SkColorSetRGB(0xde, 0xde, 0xde) }; +const SkColor kCheckboxGradientPressedColors[] = { + SkColorSetRGB(0xe7, 0xe7, 0xe7), + SkColorSetRGB(0xd7, 0xd7, 0xd7) }; +const SkColor kCheckboxGradientHoveredColors[] = { + SkColorSetRGB(0xf0, 0xf0, 0xf0), + SkColorSetRGB(0xe0, 0xe0, 0xe0) }; +const SkColor kCheckboxGradientDisabledColors[] = { + SkColorSetARGB(0x80, 0xed, 0xed, 0xed), + SkColorSetARGB(0x80, 0xde, 0xde, 0xde) }; +const SkColor kCheckboxBorderColor = SkColorSetARGB(0x40, 0, 0, 0); +const SkColor kCheckboxBorderHoveredColor = SkColorSetARGB(0x4D, 0, 0, 0); +const SkColor kCheckboxBorderDisabledColor = SkColorSetARGB(0x20, 0, 0, 0); +const SkColor kCheckboxStrokeColor = SkColorSetARGB(0xB3, 0, 0, 0); +const SkColor kCheckboxStrokeDisabledColor = SkColorSetARGB(0x59, 0, 0, 0); +const SkColor kRadioDotColor = SkColorSetRGB(0x66, 0x66, 0x66); +const SkColor kRadioDotDisabledColor = SkColorSetARGB(0x80, 0x66, 0x66, 0x66); + +// Get lightness adjusted color. +SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha, + double lightness_amount) { + color_utils::HSL adjusted = hsl; + adjusted.l += lightness_amount; + if (adjusted.l > 1.0) + adjusted.l = 1.0; + if (adjusted.l < 0.0) + adjusted.l = 0.0; + + return color_utils::HSLToSkColor(adjusted, alpha); +} + +} // namespace + +namespace ui { + +gfx::Size NativeThemeBase::GetPartSize(Part part, + State state, + const ExtraParams& extra) const { + switch (part) { + // Please keep these in the order of NativeTheme::Part. + case kCheckbox: + return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight); + case kInnerSpinButton: + return gfx::Size(scrollbar_width_, 0); + case kMenuList: + return gfx::Size(); // No default size. + case kMenuCheck: + case kMenuCheckBackground: + case kMenuPopupArrow: + NOTIMPLEMENTED(); + break; + case kMenuPopupBackground: + return gfx::Size(); // No default size. + case kMenuPopupGutter: + case kMenuPopupSeparator: + NOTIMPLEMENTED(); + break; + case kMenuItemBackground: + case kProgressBar: + case kPushButton: + return gfx::Size(); // No default size. + case kRadio: + return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight); + case kScrollbarDownArrow: + case kScrollbarUpArrow: + return gfx::Size(scrollbar_width_, scrollbar_button_length_); + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + return gfx::Size(scrollbar_button_length_, scrollbar_width_); + case kScrollbarHorizontalThumb: + // This matches Firefox on Linux. + return gfx::Size(2 * scrollbar_width_, scrollbar_width_); + case kScrollbarVerticalThumb: + // This matches Firefox on Linux. + return gfx::Size(scrollbar_width_, 2 * scrollbar_width_); + case kScrollbarHorizontalTrack: + return gfx::Size(0, scrollbar_width_); + case kScrollbarVerticalTrack: + return gfx::Size(scrollbar_width_, 0); + case kScrollbarHorizontalGripper: + case kScrollbarVerticalGripper: + NOTIMPLEMENTED(); + break; + case kSliderTrack: + return gfx::Size(); // No default size. + case kSliderThumb: + // These sizes match the sizes in Chromium Win. + return gfx::Size(kSliderThumbWidth, kSliderThumbHeight); + case kTabPanelBackground: + NOTIMPLEMENTED(); + break; + case kTextField: + return gfx::Size(); // No default size. + case kTrackbarThumb: + case kTrackbarTrack: + case kWindowResizeGripper: + NOTIMPLEMENTED(); + break; + default: + NOTREACHED() << "Unknown theme part: " << part; + break; + } + return gfx::Size(); +} + +void NativeThemeBase::Paint(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const { + switch (part) { + // Please keep these in the order of NativeTheme::Part. + case kCheckbox: + PaintCheckbox(canvas, state, rect, extra.button); + break; + case kInnerSpinButton: + PaintInnerSpinButton(canvas, state, rect, extra.inner_spin); + break; + case kMenuList: + PaintMenuList(canvas, state, rect, extra.menu_list); + break; + case kMenuCheck: + case kMenuCheckBackground: + case kMenuPopupArrow: + NOTIMPLEMENTED(); + break; + case kMenuPopupBackground: + PaintMenuPopupBackground(canvas, rect.size()); + break; + case kMenuPopupGutter: + case kMenuPopupSeparator: + NOTIMPLEMENTED(); + break; + case kMenuItemBackground: + PaintMenuItemBackground(canvas, state, rect, extra.menu_list); + break; + case kProgressBar: + PaintProgressBar(canvas, state, rect, extra.progress_bar); + break; + case kPushButton: + PaintButton(canvas, state, rect, extra.button); + break; + case kRadio: + PaintRadio(canvas, state, rect, extra.button); + break; + case kScrollbarDownArrow: + case kScrollbarUpArrow: + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + PaintArrowButton(canvas, rect, part, state); + break; + case kScrollbarHorizontalThumb: + case kScrollbarVerticalThumb: + PaintScrollbarThumb(canvas, part, state, rect); + break; + case kScrollbarHorizontalTrack: + case kScrollbarVerticalTrack: + PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect); + break; + case kScrollbarHorizontalGripper: + case kScrollbarVerticalGripper: + NOTIMPLEMENTED(); + break; + case kSliderTrack: + PaintSliderTrack(canvas, state, rect, extra.slider); + break; + case kSliderThumb: + PaintSliderThumb(canvas, state, rect, extra.slider); + break; + case kTabPanelBackground: + NOTIMPLEMENTED(); + break; + case kTextField: + PaintTextField(canvas, state, rect, extra.text_field); + break; + case kTrackbarThumb: + case kTrackbarTrack: + case kWindowResizeGripper: + NOTIMPLEMENTED(); + break; + default: + NOTREACHED() << "Unknown theme part: " << part; + break; + } +} + +NativeThemeBase::NativeThemeBase() + : scrollbar_width_(kDefaultScrollbarWidth), + scrollbar_button_length_(kDefaultScrollbarButtonLength) { +} + +NativeThemeBase::~NativeThemeBase() { +} + +void NativeThemeBase::PaintArrowButton( + SkCanvas* canvas, + const gfx::Rect& rect, Part direction, State state) const { + int widthMiddle, lengthMiddle; + SkPaint paint; + if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) { + widthMiddle = rect.width() / 2 + 1; + lengthMiddle = rect.height() / 2 + 1; + } else { + lengthMiddle = rect.width() / 2 + 1; + widthMiddle = rect.height() / 2 + 1; + } + + // Calculate button color. + SkScalar trackHSV[3]; + SkColorToHSV(track_color_, trackHSV); + SkColor buttonColor = SaturateAndBrighten(trackHSV, 0, 0.2f); + SkColor backgroundColor = buttonColor; + if (state == kPressed) { + SkScalar buttonHSV[3]; + SkColorToHSV(buttonColor, buttonHSV); + buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1f); + } else if (state == kHovered) { + SkScalar buttonHSV[3]; + SkColorToHSV(buttonColor, buttonHSV); + buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05f); + } + + SkIRect skrect; + skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + + rect.height()); + // Paint the background (the area visible behind the rounded corners). + paint.setColor(backgroundColor); + canvas->drawIRect(skrect, paint); + + // Paint the button's outline and fill the middle + SkPath outline; + switch (direction) { + case kScrollbarUpArrow: + outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5); + outline.rLineTo(0, -(rect.height() - 2)); + outline.rLineTo(2, -2); + outline.rLineTo(rect.width() - 5, 0); + outline.rLineTo(2, 2); + outline.rLineTo(0, rect.height() - 2); + break; + case kScrollbarDownArrow: + outline.moveTo(rect.x() + 0.5, rect.y() - 0.5); + outline.rLineTo(0, rect.height() - 2); + outline.rLineTo(2, 2); + outline.rLineTo(rect.width() - 5, 0); + outline.rLineTo(2, -2); + outline.rLineTo(0, -(rect.height() - 2)); + break; + case kScrollbarRightArrow: + outline.moveTo(rect.x() - 0.5, rect.y() + 0.5); + outline.rLineTo(rect.width() - 2, 0); + outline.rLineTo(2, 2); + outline.rLineTo(0, rect.height() - 5); + outline.rLineTo(-2, 2); + outline.rLineTo(-(rect.width() - 2), 0); + break; + case kScrollbarLeftArrow: + outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5); + outline.rLineTo(-(rect.width() - 2), 0); + outline.rLineTo(-2, 2); + outline.rLineTo(0, rect.height() - 5); + outline.rLineTo(2, 2); + outline.rLineTo(rect.width() - 2, 0); + break; + default: + break; + } + outline.close(); + + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(buttonColor); + canvas->drawPath(outline, paint); + + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + SkScalar thumbHSV[3]; + SkColorToHSV(thumb_inactive_color_, thumbHSV); + paint.setColor(OutlineColor(trackHSV, thumbHSV)); + canvas->drawPath(outline, paint); + + // If the button is disabled or read-only, the arrow is drawn with the + // outline color. + if (state != kDisabled) + paint.setColor(SK_ColorBLACK); + + paint.setAntiAlias(false); + paint.setStyle(SkPaint::kFill_Style); + + SkPath path; + // The constants in this block of code are hand-tailored to produce good + // looking arrows without anti-aliasing. + switch (direction) { + case kScrollbarUpArrow: + path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2); + path.rLineTo(7, 0); + path.rLineTo(-4, -4); + break; + case kScrollbarDownArrow: + path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3); + path.rLineTo(7, 0); + path.rLineTo(-4, 4); + break; + case kScrollbarRightArrow: + path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4); + path.rLineTo(0, 7); + path.rLineTo(4, -4); + break; + case kScrollbarLeftArrow: + path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5); + path.rLineTo(0, 9); + path.rLineTo(-4, -4); + break; + default: + break; + } + path.close(); + + canvas->drawPath(path, paint); +} + +void NativeThemeBase::PaintScrollbarTrack(SkCanvas* canvas, + Part part, + State state, + const ScrollbarTrackExtraParams& extra_params, + const gfx::Rect& rect) const { + SkPaint paint; + SkIRect skrect; + + skrect.set(rect.x(), rect.y(), rect.right(), rect.bottom()); + SkScalar track_hsv[3]; + SkColorToHSV(track_color_, track_hsv); + paint.setColor(SaturateAndBrighten(track_hsv, 0, 0)); + canvas->drawIRect(skrect, paint); + + SkScalar thumb_hsv[3]; + SkColorToHSV(thumb_inactive_color_, thumb_hsv); + + paint.setColor(OutlineColor(track_hsv, thumb_hsv)); + DrawBox(canvas, rect, paint); +} + +void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect) const { + const bool hovered = state == kHovered; + const int midx = rect.x() + rect.width() / 2; + const int midy = rect.y() + rect.height() / 2; + const bool vertical = part == kScrollbarVerticalThumb; + + SkScalar thumb[3]; + SkColorToHSV(hovered ? thumb_active_color_ : thumb_inactive_color_, thumb); + + SkPaint paint; + paint.setColor(SaturateAndBrighten(thumb, 0, 0.02f)); + + SkIRect skrect; + if (vertical) + skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height()); + else + skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1); + + canvas->drawIRect(skrect, paint); + + paint.setColor(SaturateAndBrighten(thumb, 0, -0.02f)); + + if (vertical) { + skrect.set( + midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + } else { + skrect.set( + rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height()); + } + + canvas->drawIRect(skrect, paint); + + SkScalar track[3]; + SkColorToHSV(track_color_, track); + paint.setColor(OutlineColor(track, thumb)); + DrawBox(canvas, rect, paint); + + if (rect.height() > 10 && rect.width() > 10) { + const int grippy_half_width = 2; + const int inter_grippy_offset = 3; + if (vertical) { + DrawHorizLine(canvas, + midx - grippy_half_width, + midx + grippy_half_width, + midy - inter_grippy_offset, + paint); + DrawHorizLine(canvas, + midx - grippy_half_width, + midx + grippy_half_width, + midy, + paint); + DrawHorizLine(canvas, + midx - grippy_half_width, + midx + grippy_half_width, + midy + inter_grippy_offset, + paint); + } else { + DrawVertLine(canvas, + midx - inter_grippy_offset, + midy - grippy_half_width, + midy + grippy_half_width, + paint); + DrawVertLine(canvas, + midx, + midy - grippy_half_width, + midy + grippy_half_width, + paint); + DrawVertLine(canvas, + midx + inter_grippy_offset, + midy - grippy_half_width, + midy + grippy_half_width, + paint); + } + } +} + +bool NativeThemeBase::IsNewCheckboxStyleEnabled(SkCanvas* canvas) const { + // The new style is now the default. + // TODO(rbyers): Remove this flag once we're sure the new behavior is fine. + // http://crbug.com/133991 + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kOldCheckboxStyle)) + return true; + + return false; +} + +void NativeThemeBase::PaintCheckbox(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const { + if (IsNewCheckboxStyleEnabled(canvas)) { + PaintCheckboxNew(canvas, state, rect, button); + return; + } + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::ImageSkia* image = NULL; + if (button.indeterminate) { + image = state == kDisabled ? + rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED_INDETERMINATE) : + rb.GetImageSkiaNamed(IDR_CHECKBOX_INDETERMINATE); + } else if (button.checked) { + image = state == kDisabled ? + rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED_ON) : + rb.GetImageSkiaNamed(IDR_CHECKBOX_ON); + } else { + image = state == kDisabled ? + rb.GetImageSkiaNamed(IDR_CHECKBOX_DISABLED_OFF) : + rb.GetImageSkiaNamed(IDR_CHECKBOX_OFF); + } + + gfx::Rect bounds = rect; + bounds.ClampToCenteredSize(gfx::Size(image->width(), image->height())); + DrawImageInt(canvas, *image, 0, 0, image->width(), image->height(), + bounds.x(), bounds.y(), bounds.width(), bounds.height()); +} + +// Draws the common elements of checkboxes and radio buttons. +// Returns the rectangle within which any additional decorations should be +// drawn, or empty if none. +SkRect NativeThemeBase::PaintCheckboxRadioNewCommon( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SkScalar borderRadius) const { + + SkRect skrect = gfx::RectToSkRect(rect); + + // Use the largest square that fits inside the provided rectangle. + // No other browser seems to support non-square widget, so accidentally + // having non-square sizes is common (eg. amazon and webkit dev tools). + if (skrect.width() != skrect.height()) { + SkScalar size = SkMinScalar(skrect.width(), skrect.height()); + skrect.inset((skrect.width() - size) / 2, (skrect.height() - size) / 2); + } + + // If the rectangle is too small then paint only a rectangle. We don't want + // to have to worry about '- 1' and '+ 1' calculations below having overflow + // or underflow. + if (skrect.width() <= 2) { + SkPaint paint; + paint.setColor(kCheckboxTinyColor); + paint.setStyle(SkPaint::kFill_Style); + canvas->drawRect(skrect, paint); + // Too small to draw anything more. + return SkRect::MakeEmpty(); + } + + // Make room for the drop shadow. + skrect.iset(skrect.x(), skrect.y(), skrect.right() - 1, skrect.bottom() - 1); + + // Draw the drop shadow below the widget. + if (state != kPressed) { + SkPaint paint; + paint.setAntiAlias(true); + SkRect shadowRect = skrect; + shadowRect.offset(0, 1); + if (state == kDisabled) + paint.setColor(kCheckboxShadowDisabledColor); + else if (state == kHovered) + paint.setColor(kCheckboxShadowHoveredColor); + else + paint.setColor(kCheckboxShadowColor); + paint.setStyle(SkPaint::kFill_Style); + canvas->drawRoundRect(shadowRect, borderRadius, borderRadius, paint); + } + + // Draw the gradient-filled rectangle + SkPoint gradient_bounds[3]; + gradient_bounds[0].set(skrect.x(), skrect.y()); + gradient_bounds[1].set(skrect.x(), skrect.y() + skrect.height() * 0.38); + gradient_bounds[2].set(skrect.x(), skrect.bottom()); + const SkColor* startEndColors; + if (state == kPressed) + startEndColors = kCheckboxGradientPressedColors; + else if (state == kHovered) + startEndColors = kCheckboxGradientHoveredColors; + else if (state == kDisabled) + startEndColors = kCheckboxGradientDisabledColors; + else /* kNormal */ + startEndColors = kCheckboxGradientColors; + SkColor colors[3] = {startEndColors[0], startEndColors[0], startEndColors[1]}; + SkShader* shader = SkGradientShader::CreateLinear( + gradient_bounds, colors, NULL, 3, SkShader::kClamp_TileMode, NULL); + SkPaint paint; + paint.setAntiAlias(true); + paint.setShader(shader); + shader->unref(); + paint.setStyle(SkPaint::kFill_Style); + canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint); + paint.setShader(NULL); + + // Draw the border. + if (state == kHovered) + paint.setColor(kCheckboxBorderHoveredColor); + else if (state == kDisabled) + paint.setColor(kCheckboxBorderDisabledColor); + else + paint.setColor(kCheckboxBorderColor); + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(SkIntToScalar(1)); + skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f)); + canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint); + + // Return the rectangle excluding the drop shadow for drawing any additional + // decorations. + return skrect; +} + +void NativeThemeBase::PaintCheckboxNew(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const { + SkRect skrect = PaintCheckboxRadioNewCommon(canvas, state, rect, + SkIntToScalar(2)); + if (!skrect.isEmpty()) { + // Draw the checkmark / dash. + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kStroke_Style); + if (state == kDisabled) + paint.setColor(kCheckboxStrokeDisabledColor); + else + paint.setColor(kCheckboxStrokeColor); + if (button.indeterminate) { + SkPath dash; + dash.moveTo(skrect.x() + skrect.width() * 0.16, + (skrect.y() + skrect.bottom()) / 2); + dash.rLineTo(skrect.width() * 0.68, 0); + paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.2)); + canvas->drawPath(dash, paint); + } else if (button.checked) { + SkPath check; + check.moveTo(skrect.x() + skrect.width() * 0.2, + skrect.y() + skrect.height() * 0.5); + check.rLineTo(skrect.width() * 0.2, skrect.height() * 0.2); + paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.23)); + check.lineTo(skrect.right() - skrect.width() * 0.2, + skrect.y() + skrect.height() * 0.2); + canvas->drawPath(check, paint); + } + } +} + +void NativeThemeBase::PaintRadio(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const { + if (IsNewCheckboxStyleEnabled(canvas)) { + PaintRadioNew(canvas, state, rect, button); + return; + } + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::ImageSkia* image = NULL; + if (state == kDisabled) { + image = button.checked ? + rb.GetImageSkiaNamed(IDR_RADIO_DISABLED_ON) : + rb.GetImageSkiaNamed(IDR_RADIO_DISABLED_OFF); + } else { + image = button.checked ? + rb.GetImageSkiaNamed(IDR_RADIO_ON) : + rb.GetImageSkiaNamed(IDR_RADIO_OFF); + } + + gfx::Rect bounds = rect; + bounds.ClampToCenteredSize(gfx::Size(image->width(), image->height())); + DrawImageInt(canvas, *image, 0, 0, image->width(), image->height(), + bounds.x(), bounds.y(), bounds.width(), bounds.height()); +} + +void NativeThemeBase::PaintRadioNew(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const { + + // Most of a radio button is the same as a checkbox, except the the rounded + // square is a circle (i.e. border radius >= 100%). + const SkScalar radius = SkFloatToScalar( + static_cast<float>(std::max(rect.width(), rect.height())) / 2); + SkRect skrect = PaintCheckboxRadioNewCommon(canvas, state, rect, radius); + if (!skrect.isEmpty() && button.checked) { + // Draw the dot. + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + if (state == kDisabled) + paint.setColor(kRadioDotDisabledColor); + else + paint.setColor(kRadioDotColor); + skrect.inset(skrect.width() * 0.25, skrect.height() * 0.25); + // Use drawRoundedRect instead of drawOval to be completely consistent + // with the border in PaintCheckboxRadioNewCommon. + canvas->drawRoundRect(skrect, radius, radius, paint); + } +} + +void NativeThemeBase::PaintButton(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const { + SkPaint paint; + const int kRight = rect.right(); + const int kBottom = rect.bottom(); + SkRect skrect = SkRect::MakeLTRB(rect.x(), rect.y(), kRight, kBottom); + SkColor base_color = button.background_color; + + color_utils::HSL base_hsl; + color_utils::SkColorToHSL(base_color, &base_hsl); + + // Our standard gradient is from 0xdd to 0xf8. This is the amount of + // increased luminance between those values. + SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105)); + + // If the button is too small, fallback to drawing a single, solid color + if (rect.width() < 5 || rect.height() < 5) { + paint.setColor(base_color); + canvas->drawRect(skrect, paint); + return; + } + + paint.setColor(SK_ColorBLACK); + const int kLightEnd = state == kPressed ? 1 : 0; + const int kDarkEnd = !kLightEnd; + SkPoint gradient_bounds[2]; + gradient_bounds[kLightEnd].iset(rect.x(), rect.y()); + gradient_bounds[kDarkEnd].iset(rect.x(), kBottom - 1); + SkColor colors[2]; + colors[0] = light_color; + colors[1] = base_color; + + SkShader* shader = SkGradientShader::CreateLinear( + gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL); + paint.setStyle(SkPaint::kFill_Style); + paint.setAntiAlias(true); + paint.setShader(shader); + shader->unref(); + + canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint); + paint.setShader(NULL); + + if (button.has_border) { + int border_alpha = state == kHovered ? 0x80 : 0x55; + if (button.is_focused) { + border_alpha = 0xff; + paint.setColor(GetSystemColor(kColorId_FocusedBorderColor)); + } + paint.setStyle(SkPaint::kStroke_Style); + paint.setStrokeWidth(SkIntToScalar(1)); + paint.setAlpha(border_alpha); + skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f)); + canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint); + } +} + +void NativeThemeBase::PaintTextField(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const TextFieldExtraParams& text) const { + // The following drawing code simulates the user-agent css border for + // text area and text input so that we do not break layout tests. Once we + // have decided the desired looks, we should update the code here and + // the layout test expectations. + SkRect bounds; + bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1); + + SkPaint fill_paint; + fill_paint.setStyle(SkPaint::kFill_Style); + fill_paint.setColor(text.background_color); + canvas->drawRect(bounds, fill_paint); + + if (text.is_text_area) { + // Draw text area border: 1px solid black + SkPaint stroke_paint; + fill_paint.setStyle(SkPaint::kStroke_Style); + fill_paint.setColor(SK_ColorBLACK); + canvas->drawRect(bounds, fill_paint); + } else { + // Draw text input and listbox inset border + // Text Input: 2px inset #eee + // Listbox: 1px inset #808080 + const SkColor kLightColor = text.is_listbox ? + SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee); + const SkColor kDarkColor = text.is_listbox ? + SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a); + const int kBorderWidth = text.is_listbox ? 1 : 2; + + SkPaint dark_paint; + dark_paint.setAntiAlias(true); + dark_paint.setStyle(SkPaint::kFill_Style); + dark_paint.setColor(kDarkColor); + + SkPaint light_paint; + light_paint.setAntiAlias(true); + light_paint.setStyle(SkPaint::kFill_Style); + light_paint.setColor(kLightColor); + + int left = rect.x(); + int top = rect.y(); + int right = rect.right(); + int bottom = rect.bottom(); + + SkPath path; + path.incReserve(4); + + // Top + path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); + path.lineTo(SkIntToScalar(left + kBorderWidth), + SkIntToScalar(top + kBorderWidth)); + path.lineTo(SkIntToScalar(right - kBorderWidth), + SkIntToScalar(top + kBorderWidth)); + path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); + canvas->drawPath(path, dark_paint); + + // Bottom + path.reset(); + path.moveTo(SkIntToScalar(left + kBorderWidth), + SkIntToScalar(bottom - kBorderWidth)); + path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); + path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); + path.lineTo(SkIntToScalar(right - kBorderWidth), + SkIntToScalar(bottom - kBorderWidth)); + canvas->drawPath(path, light_paint); + + // Left + path.reset(); + path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); + path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); + path.lineTo(SkIntToScalar(left + kBorderWidth), + SkIntToScalar(bottom - kBorderWidth)); + path.lineTo(SkIntToScalar(left + kBorderWidth), + SkIntToScalar(top + kBorderWidth)); + canvas->drawPath(path, dark_paint); + + // Right + path.reset(); + path.moveTo(SkIntToScalar(right - kBorderWidth), + SkIntToScalar(top + kBorderWidth)); + path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom)); + path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); + path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); + canvas->drawPath(path, light_paint); + } +} + +void NativeThemeBase::PaintMenuList( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& menu_list) const { + // If a border radius is specified, we let the WebCore paint the background + // and the border of the control. + if (!menu_list.has_border_radius) { + ButtonExtraParams button = { 0 }; + button.background_color = menu_list.background_color; + button.has_border = menu_list.has_border; + PaintButton(canvas, state, rect, button); + } + + SkPaint paint; + paint.setColor(SK_ColorBLACK); + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + + SkPath path; + path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3); + path.rLineTo(6, 0); + path.rLineTo(-3, 6); + path.close(); + canvas->drawPath(path, paint); +} + +void NativeThemeBase::PaintMenuPopupBackground(SkCanvas* canvas, + const gfx::Size& size) const { + canvas->drawColor(kMenuPopupBackgroundColor, SkXfermode::kSrc_Mode); +} + +void NativeThemeBase::PaintMenuItemBackground( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& menu_list) const { + // By default don't draw anything over the normal background. +} + +void NativeThemeBase::PaintSliderTrack(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SliderExtraParams& slider) const { + const int kMidX = rect.x() + rect.width() / 2; + const int kMidY = rect.y() + rect.height() / 2; + + SkPaint paint; + paint.setColor(kSliderTrackBackgroundColor); + + SkRect skrect; + if (slider.vertical) { + skrect.set(std::max(rect.x(), kMidX - 2), + rect.y(), + std::min(rect.right(), kMidX + 2), + rect.bottom()); + } else { + skrect.set(rect.x(), + std::max(rect.y(), kMidY - 2), + rect.right(), + std::min(rect.bottom(), kMidY + 2)); + } + canvas->drawRect(skrect, paint); +} + +void NativeThemeBase::PaintSliderThumb(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SliderExtraParams& slider) const { + const bool hovered = (state == kHovered) || slider.in_drag; + const int kMidX = rect.x() + rect.width() / 2; + const int kMidY = rect.y() + rect.height() / 2; + + SkPaint paint; + paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey); + + SkIRect skrect; + if (slider.vertical) + skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom()); + else + skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1); + + canvas->drawIRect(skrect, paint); + + paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey); + + if (slider.vertical) + skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom()); + else + skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom()); + + canvas->drawIRect(skrect, paint); + + paint.setColor(kSliderThumbBorderDarkGrey); + DrawBox(canvas, rect, paint); + + if (rect.height() > 10 && rect.width() > 10) { + DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint); + DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint); + DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint); + } +} + +void NativeThemeBase::PaintInnerSpinButton(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const InnerSpinButtonExtraParams& spin_button) const { + if (spin_button.read_only) + state = kDisabled; + + State north_state = state; + State south_state = state; + if (spin_button.spin_up) + south_state = south_state != kDisabled ? kNormal : kDisabled; + else + north_state = north_state != kDisabled ? kNormal : kDisabled; + + gfx::Rect half = rect; + half.set_height(rect.height() / 2); + PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state); + + half.set_y(rect.y() + rect.height() / 2); + PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state); +} + +void NativeThemeBase::PaintProgressBar(SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ProgressBarExtraParams& progress_bar) const { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gfx::ImageSkia* bar_image = rb.GetImageSkiaNamed(IDR_PROGRESS_BAR); + gfx::ImageSkia* left_border_image = rb.GetImageSkiaNamed( + IDR_PROGRESS_BORDER_LEFT); + gfx::ImageSkia* right_border_image = rb.GetImageSkiaNamed( + IDR_PROGRESS_BORDER_RIGHT); + + float tile_scale = static_cast<float>(rect.height()) / + bar_image->height(); + + int new_tile_width = static_cast<int>(bar_image->width() * tile_scale); + float tile_scale_x = static_cast<float>(new_tile_width) / + bar_image->width(); + + DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale, + rect.x(), rect.y(), rect.width(), rect.height()); + + if (progress_bar.value_rect_width) { + gfx::ImageSkia* value_image = rb.GetImageSkiaNamed(IDR_PROGRESS_VALUE); + + new_tile_width = static_cast<int>(value_image->width() * tile_scale); + tile_scale_x = static_cast<float>(new_tile_width) / + value_image->width(); + + DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale, + progress_bar.value_rect_x, + progress_bar.value_rect_y, + progress_bar.value_rect_width, + progress_bar.value_rect_height); + } + + int dest_left_border_width = static_cast<int>(left_border_image->width() * + tile_scale); + DrawImageInt(canvas, *left_border_image, 0, 0, left_border_image->width(), + left_border_image->height(), rect.x(), rect.y(), dest_left_border_width, + rect.height()); + + int dest_right_border_width = static_cast<int>(right_border_image->width() * + tile_scale); + int dest_x = rect.right() - dest_right_border_width; + DrawImageInt(canvas, *right_border_image, 0, 0, right_border_image->width(), + right_border_image->height(), dest_x, rect.y(), + dest_right_border_width, rect.height()); +} + +bool NativeThemeBase::IntersectsClipRectInt(SkCanvas* canvas, + int x, int y, int w, int h) const { + SkRect clip; + return canvas->getClipBounds(&clip) && + clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w), + SkIntToScalar(y + h)); +} + +void NativeThemeBase::DrawImageInt( + SkCanvas* sk_canvas, const gfx::ImageSkia& image, + int src_x, int src_y, int src_w, int src_h, + int dest_x, int dest_y, int dest_w, int dest_h) const { + // TODO(pkotwicz): Do something better and don't infer device + // scale factor from canvas scale. + SkMatrix m = sk_canvas->getTotalMatrix(); + ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale( + SkScalarAbs(m.getScaleX())); + scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( + sk_canvas, device_scale_factor)); + canvas->DrawImageInt(image, src_x, src_y, src_w, src_h, + dest_x, dest_y, dest_w, dest_h, true); +} + +void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas, + const gfx::ImageSkia& image, + int src_x, int src_y, float tile_scale_x, float tile_scale_y, + int dest_x, int dest_y, int w, int h) const { + // TODO(pkotwicz): Do something better and don't infer device + // scale factor from canvas scale. + SkMatrix m = sk_canvas->getTotalMatrix(); + ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale( + SkScalarAbs(m.getScaleX())); + scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling( + sk_canvas, device_scale_factor)); + canvas->TileImageInt(image, src_x, src_y, tile_scale_x, + tile_scale_y, dest_x, dest_y, w, h); +} + +SkColor NativeThemeBase::SaturateAndBrighten(SkScalar* hsv, + SkScalar saturate_amount, + SkScalar brighten_amount) const { + SkScalar color[3]; + color[0] = hsv[0]; + color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0); + color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0); + return SkHSVToColor(color); +} + +void NativeThemeBase::DrawVertLine(SkCanvas* canvas, + int x, + int y1, + int y2, + const SkPaint& paint) const { + SkIRect skrect; + skrect.set(x, y1, x + 1, y2 + 1); + canvas->drawIRect(skrect, paint); +} + +void NativeThemeBase::DrawHorizLine(SkCanvas* canvas, + int x1, + int x2, + int y, + const SkPaint& paint) const { + SkIRect skrect; + skrect.set(x1, y, x2 + 1, y + 1); + canvas->drawIRect(skrect, paint); +} + +void NativeThemeBase::DrawBox(SkCanvas* canvas, + const gfx::Rect& rect, + const SkPaint& paint) const { + const int right = rect.x() + rect.width() - 1; + const int bottom = rect.y() + rect.height() - 1; + DrawHorizLine(canvas, rect.x(), right, rect.y(), paint); + DrawVertLine(canvas, right, rect.y(), bottom, paint); + DrawHorizLine(canvas, rect.x(), right, bottom, paint); + DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint); +} + +SkScalar NativeThemeBase::Clamp(SkScalar value, + SkScalar min, + SkScalar max) const { + return std::min(std::max(value, min), max); +} + +SkColor NativeThemeBase::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const { + // GTK Theme engines have way too much control over the layout of + // the scrollbar. We might be able to more closely approximate its + // look-and-feel, if we sent whole images instead of just colors + // from the browser to the renderer. But even then, some themes + // would just break. + // + // So, instead, we don't even try to 100% replicate the look of + // the native scrollbar. We render our own version, but we make + // sure to pick colors that blend in nicely with the system GTK + // theme. In most cases, we can just sample a couple of pixels + // from the system scrollbar and use those colors to draw our + // scrollbar. + // + // This works fine for the track color and the overall thumb + // color. But it fails spectacularly for the outline color used + // around the thumb piece. Not all themes have a clearly defined + // outline. For some of them it is partially transparent, and for + // others the thickness is very unpredictable. + // + // So, instead of trying to approximate the system theme, we + // instead try to compute a reasonable looking choice based on the + // known color of the track and the thumb piece. This is difficult + // when trying to deal both with high- and low-contrast themes, + // and both with positive and inverted themes. + // + // The following code has been tested to look OK with all of the + // default GTK themes. + SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f); + SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f); + + if (hsv1[2] + hsv2[2] > 1.0) + diff = -diff; + + return SaturateAndBrighten(hsv2, -0.2f, diff); +} + +} // namespace ui diff --git a/ui/native_theme/native_theme_base.h b/ui/native_theme/native_theme_base.h new file mode 100644 index 0000000..0705665 --- /dev/null +++ b/ui/native_theme/native_theme_base.h @@ -0,0 +1,199 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_BASE_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_BASE_H_ + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "skia/ext/platform_canvas.h" +#include "ui/native_theme/native_theme.h" + +namespace gfx { +class ImageSkia; +class Rect; +class Size; +} + +namespace ui { + +// Theme support for non-Windows toolkits. +class NATIVE_THEME_EXPORT NativeThemeBase : public NativeTheme { + public: + // NativeTheme implementation: + virtual gfx::Size GetPartSize(Part part, + State state, + const ExtraParams& extra) const OVERRIDE; + virtual void Paint(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const OVERRIDE; + + protected: + NativeThemeBase(); + virtual ~NativeThemeBase(); + + // Draw the arrow. Used by scrollbar and inner spin button. + virtual void PaintArrowButton( + SkCanvas* gc, + const gfx::Rect& rect, + Part direction, + State state) const; + // Paint the scrollbar track. Done before the thumb so that it can contain + // alpha. + virtual void PaintScrollbarTrack( + SkCanvas* canvas, + Part part, + State state, + const ScrollbarTrackExtraParams& extra_params, + const gfx::Rect& rect) const; + // Draw the scrollbar thumb over the track. + virtual void PaintScrollbarThumb( + SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect) const; + + virtual void PaintCheckbox( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const; + + virtual void PaintRadio( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const; + + virtual void PaintButton( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const; + + virtual void PaintTextField( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const TextFieldExtraParams& text) const; + + virtual void PaintMenuList( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& menu_list) const; + + virtual void PaintMenuPopupBackground(SkCanvas* canvas, + const gfx::Size& size) const; + + virtual void PaintMenuItemBackground( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& menu_list) const; + + virtual void PaintSliderTrack( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SliderExtraParams& slider) const; + + virtual void PaintSliderThumb( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SliderExtraParams& slider) const; + + virtual void PaintInnerSpinButton( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const InnerSpinButtonExtraParams& spin_button) const; + + virtual void PaintProgressBar( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ProgressBarExtraParams& progress_bar) const; + + protected: + void set_scrollbar_button_length(unsigned int length) { + scrollbar_button_length_ = length; + } + + bool IntersectsClipRectInt(SkCanvas* canvas, + int x, int y, int w, int h) const; + + void DrawImageInt(SkCanvas* canvas, const gfx::ImageSkia& image, + int src_x, int src_y, int src_w, int src_h, + int dest_x, int dest_y, int dest_w, int dest_h) const; + + void DrawTiledImage(SkCanvas* canvas, + const gfx::ImageSkia& image, + int src_x, int src_y, + float tile_scale_x, float tile_scale_y, + int dest_x, int dest_y, int w, int h) const; + + SkColor SaturateAndBrighten(SkScalar* hsv, + SkScalar saturate_amount, + SkScalar brighten_amount) const; + private: + void DrawVertLine(SkCanvas* canvas, + int x, + int y1, + int y2, + const SkPaint& paint) const; + void DrawHorizLine(SkCanvas* canvas, + int x1, + int x2, + int y, + const SkPaint& paint) const; + void DrawBox(SkCanvas* canvas, + const gfx::Rect& rect, + const SkPaint& paint) const; + SkScalar Clamp(SkScalar value, + SkScalar min, + SkScalar max) const; + SkColor OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const; + + // Returns whether the new vector-graphics based checkbox and radio button + // style is enabled. + bool IsNewCheckboxStyleEnabled(SkCanvas* canvas) const; + + // Paint the common parts of the new (experimental) checkboxes and radio + // buttons. + // borderRadius specifies how rounded the corners should be. + SkRect PaintCheckboxRadioNewCommon( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const SkScalar borderRadius) const; + + // Paint an (experimental) vector-graphics based checkbox on the supplied + // canvas at the specified co-ordinates. + void PaintCheckboxNew( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const; + + // Paint an (experimental) vector-graphics based radio button on the + // supplied canbas at the specified co-ordinates. + void PaintRadioNew( + SkCanvas* canvas, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& button) const; + + unsigned int scrollbar_width_; + unsigned int scrollbar_button_length_; + + DISALLOW_COPY_AND_ASSIGN(NativeThemeBase); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_BASE_H_ diff --git a/ui/native_theme/native_theme_export.h b/ui/native_theme/native_theme_export.h new file mode 100644 index 0000000..85641e5 --- /dev/null +++ b/ui/native_theme/native_theme_export.h @@ -0,0 +1,36 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_EXPORT_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_EXPORT_H_ + +// Defines NATIVE_THEME_EXPORT so that functionality implemented by the +// native_theme library can be exported to consumers. + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(NATIVE_THEME_IMPLEMENTATION) +#define NATIVE_THEME_EXPORT __declspec(dllexport) +#else +#define NATIVE_THEME_EXPORT __declspec(dllimport) +#endif // defined(NATIVE_THEME_IMPLEMENTATION) + +#else // !defined(WIN32) + +#if defined(NATIVE_THEME_IMPLEMENTATION) +#define NATIVE_THEME_EXPORT __attribute__((visibility("default"))) +#else +#define NATIVE_THEME_EXPORT +#endif + +#endif // defined(WIN32) + +#else // !defined(COMPONENT_BUILD) + +#define NATIVE_THEME_EXPORT + +#endif // defined(COMPONENT_BUILD) + +#endif // UI_NATIVE_THEME_NATIVE_THEME_EXPORT_H_ diff --git a/ui/native_theme/native_theme_gtk.cc b/ui/native_theme/native_theme_gtk.cc new file mode 100644 index 0000000..07209d8 --- /dev/null +++ b/ui/native_theme/native_theme_gtk.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_gtk.h" + +#include <gtk/gtk.h> + +#include "base/basictypes.h" +#include "base/logging.h" +#include "ui/gfx/skia_utils_gtk.h" + +namespace { + +const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128); + +// Theme colors returned by GetSystemColor(). + +// FocusableBorder: +const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE); +const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9); + +// TextButton: +const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xde, 0xde, 0xde); +const SkColor kTextButtonEnabledColor = SkColorSetRGB(6, 45, 117); +const SkColor kTextButtonDisabledColor = SkColorSetRGB(161, 161, 146); +const SkColor kTextButtonHighlightColor = SkColorSetARGB(200, 255, 255, 255); +const SkColor kTextButtonHoverColor = kTextButtonEnabledColor; + +} // namespace + +namespace ui { + +// static +NativeTheme* NativeTheme::instance() { + return NativeThemeGtk::instance(); +} + +// static +NativeThemeGtk* NativeThemeGtk::instance() { + CR_DEFINE_STATIC_LOCAL(NativeThemeGtk, s_native_theme, ()); + return &s_native_theme; +} + +SkColor NativeThemeGtk::GetSystemColor(ColorId color_id) const { + switch (color_id) { + case kColorId_DialogBackground: + // TODO(benrg): This code used to call gtk_widget_get_style() on the + // widget being styled. After refactoring, that widget is not available + // and we have to call gtk_widget_get_default_style(). Unfortunately, + // it turns out that this breaks everything (chromium bug 105609, + // chromium-os bug 23461). Need to figure out the right thing and do it. + return gfx::GdkColorToSkColor( + gtk_widget_get_default_style()->bg[GTK_STATE_NORMAL]); + + // FocusableBorder: + case kColorId_FocusedBorderColor: + return kFocusedBorderColor; + case kColorId_UnfocusedBorderColor: + return kUnfocusedBorderColor; + + // TextButton: + case kColorId_TextButtonBackgroundColor: + return kTextButtonBackgroundColor; + case kColorId_TextButtonEnabledColor: + return kTextButtonEnabledColor; + case kColorId_TextButtonDisabledColor: + return kTextButtonDisabledColor; + case kColorId_TextButtonHighlightColor: + return kTextButtonHighlightColor; + case kColorId_TextButtonHoverColor: + return kTextButtonHoverColor; + + default: + NOTREACHED() << "Invalid color_id: " << color_id; + break; + } + return kInvalidColorIdColor; +} + +NativeThemeGtk::NativeThemeGtk() { +} + +NativeThemeGtk::~NativeThemeGtk() { +} + +} // namespace ui diff --git a/ui/native_theme/native_theme_gtk.h b/ui/native_theme/native_theme_gtk.h new file mode 100644 index 0000000..05f5a8c --- /dev/null +++ b/ui/native_theme/native_theme_gtk.h @@ -0,0 +1,28 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_GTK_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_GTK_H_ + +#include "ui/native_theme/native_theme_base.h" + +namespace ui { + +// GTK implementation of native theme support. +class NativeThemeGtk : public NativeThemeBase { + public: + static NativeThemeGtk* instance(); + + virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE; + + private: + NativeThemeGtk(); + virtual ~NativeThemeGtk(); + + DISALLOW_COPY_AND_ASSIGN(NativeThemeGtk); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_GTK_H_ diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc new file mode 100644 index 0000000..d83f396 --- /dev/null +++ b/ui/native_theme/native_theme_win.cc @@ -0,0 +1,1944 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_win.h" + +#include <windows.h> +#include <uxtheme.h> +#include <vsstyle.h> +#include <vssym32.h> + +#include "base/basictypes.h" +#include "base/logging.h" +#include "base/memory/scoped_handle.h" +#include "base/memory/scoped_ptr.h" +#include "base/win/scoped_gdi_object.h" +#include "base/win/scoped_hdc.h" +#include "base/win/scoped_select_object.h" +#include "base/win/windows_version.h" +#include "skia/ext/bitmap_platform_device.h" +#include "skia/ext/platform_canvas.h" +#include "skia/ext/skia_utils_win.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColorPriv.h" +#include "third_party/skia/include/core/SkShader.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/gdi_util.h" +#include "ui/gfx/rect.h" + +namespace { + +// TODO: Obtain the correct colors using GetSysColor. +// Theme colors returned by GetSystemColor(). +const SkColor kInvalidColorIdColor = SkColorSetRGB(255, 0, 128); +// Dialogs: +const SkColor kDialogBackgroundColor = SkColorSetRGB(200, 200, 200); +// FocusableBorder: +const SkColor kFocusedBorderColor = SkColorSetRGB(0x4D, 0x90, 0xFE); +const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xD9, 0xD9, 0xD9); +// TextButton: +const SkColor kTextButtonBackgroundColor = SkColorSetRGB(0xde, 0xde, 0xde); +const SkColor kTextButtonEnabledColor = SkColorSetRGB(6, 45, 117); +const SkColor kTextButtonDisabledColor = SkColorSetRGB(161, 161, 146); +const SkColor kTextButtonHighlightColor = SkColorSetARGB(200, 255, 255, 255); +const SkColor kTextButtonHoverColor = kTextButtonEnabledColor; +// MenuItem: +const SkColor kEnabledMenuItemForegroundColor = kTextButtonEnabledColor; +const SkColor kDisabledMenuItemForegroundColor = kTextButtonDisabledColor; +const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(246, 249, 253); +const SkColor kMenuSeparatorColor = SkColorSetARGB(50, 0, 0, 0); +// Label: +const SkColor kLabelEnabledColor = color_utils::GetSysSkColor(COLOR_WINDOWTEXT); +const SkColor kLabelDisabledColor = color_utils::GetSysSkColor(COLOR_GRAYTEXT); +const SkColor kLabelBackgroundColor = color_utils::GetSysSkColor(COLOR_WINDOW); +// Textfield: +const SkColor kTextfieldDefaultColor = SK_ColorBLACK; +const SkColor kTextfieldDefaultBackground = SK_ColorWHITE; +const SkColor kTextfieldSelectionColor = SK_ColorWHITE; +const SkColor kTextfieldSelectionBackgroundFocused = + SkColorSetRGB(0x1D, 0x90, 0xFF); +const SkColor kTextfieldSelectionBackgroundUnfocused = SK_ColorLTGRAY; + +SkColor WinColorToSkColor(COLORREF color) { + return SkColorSetRGB(GetRValue(color), GetGValue(color), GetBValue(color)); +} + +void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) { + // Create a 2x2 checkerboard pattern using the 3D face and highlight colors. + SkColor face = skia::COLORREFToSkColor(GetSysColor(COLOR_3DFACE)); + SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT)); + SkColor buffer[] = { face, highlight, highlight, face }; + // Confusing bit: we first create a temporary bitmap with our desired pattern, + // then copy it to another bitmap. The temporary bitmap doesn't take + // ownership of the pixel data, and so will point to garbage when this + // function returns. The copy will copy the pixel data into a place owned by + // the bitmap, which is in turn owned by the shader, etc., so it will live + // until we're done using it. + SkBitmap temp_bitmap; + temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); + temp_bitmap.setPixels(buffer); + SkBitmap bitmap; + temp_bitmap.copyTo(&bitmap, temp_bitmap.config()); + SkShader* shader = SkShader::CreateBitmapShader(bitmap, + SkShader::kRepeat_TileMode, + SkShader::kRepeat_TileMode); + + // Align the pattern with the upper corner of |align_rect|. + SkMatrix matrix; + matrix.setTranslate(SkIntToScalar(align_rect.left), + SkIntToScalar(align_rect.top)); + shader->setLocalMatrix(matrix); + SkSafeUnref(paint->setShader(shader)); +} + +// <-a-> +// [ ***** ] +// ____ | | +// <-a-> <------b-----> +// a: object_width +// b: frame_width +// *: animating object +// +// - the animation goes from "[" to "]" repeatedly. +// - the animation offset is at first "|" +// +int ComputeAnimationProgress(int frame_width, + int object_width, + int pixels_per_second, + double animated_seconds) { + int animation_width = frame_width + object_width; + double interval = static_cast<double>(animation_width) / pixels_per_second; + double ratio = fmod(animated_seconds, interval) / interval; + return static_cast<int>(animation_width * ratio) - object_width; +} + +RECT InsetRect(const RECT* rect, int size) { + gfx::Rect result(*rect); + result.Inset(size, size); + return result.ToRECT(); +} + +} // namespace + +namespace ui { + +bool NativeThemeWin::IsThemingActive() const { + if (is_theme_active_) + return !!is_theme_active_(); + return false; +} + +HRESULT NativeThemeWin::GetThemeColor(ThemeName theme, + int part_id, + int state_id, + int prop_id, + SkColor* color) const { + HANDLE handle = GetThemeHandle(theme); + if (handle && get_theme_color_) { + COLORREF color_ref; + if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) == + S_OK) { + *color = skia::COLORREFToSkColor(color_ref); + return S_OK; + } + } + return E_NOTIMPL; +} + +SkColor NativeThemeWin::GetThemeColorWithDefault(ThemeName theme, + int part_id, + int state_id, + int prop_id, + int default_sys_color) const { + SkColor color; + if (GetThemeColor(theme, part_id, state_id, prop_id, &color) != S_OK) + color = skia::COLORREFToSkColor(GetSysColor(default_sys_color)); + return color; +} + +gfx::Size NativeThemeWin::GetThemeBorderSize(ThemeName theme) const { + // For simplicity use the wildcard state==0, part==0, since it works + // for the cases we currently depend on. + int border; + if (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK) + return gfx::Size(border, border); + else + return gfx::Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE)); +} + +void NativeThemeWin::DisableTheming() const { + if (!set_theme_properties_) + return; + set_theme_properties_(0); +} + +void NativeThemeWin::CloseHandles() const { + if (!close_theme_) + return; + + for (int i = 0; i < LAST; ++i) { + if (theme_handles_[i]) { + close_theme_(theme_handles_[i]); + theme_handles_[i] = NULL; + } + } +} + +bool NativeThemeWin::IsClassicTheme(ThemeName name) const { + if (!theme_dll_) + return true; + + return !GetThemeHandle(name); +} + +// TODO(sky): seems like we should default to NativeThemeWin, but that currently +// breaks a couple of tests (FocusTraversalTest.NormalTraversal in +// views_unittests). +#if !defined(USE_AURA) +// static +NativeTheme* NativeTheme::instance() { + return NativeThemeWin::instance(); +} +#endif + +// static +NativeThemeWin* NativeThemeWin::instance() { + CR_DEFINE_STATIC_LOCAL(NativeThemeWin, s_native_theme, ()); + return &s_native_theme; +} + +gfx::Size NativeThemeWin::GetPartSize(Part part, + State state, + const ExtraParams& extra) const { + SIZE size; + int part_id = GetWindowsPart(part, state, extra); + int state_id = GetWindowsState(part, state, extra); + + HDC hdc = GetDC(NULL); + HRESULT hr = GetThemePartSize(GetThemeName(part), hdc, part_id, state_id, + NULL, TS_TRUE, &size); + ReleaseDC(NULL, hdc); + + if (FAILED(hr)) { + // TODO(rogerta): For now, we need to support radio buttons and checkboxes + // when theming is not enabled. Support for other parts can be added + // if/when needed. + switch (part) { + case kCheckbox: + case kRadio: + // TODO(rogerta): I was not able to find any API to get the default + // size of these controls, so determined these values empirically. + size.cx = 13; + size.cy = 13; + break; + default: + size.cx = 0; + size.cy = 0; + break; + } + } + + return gfx::Size(size.cx, size.cy); +} + +void NativeThemeWin::Paint(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const { + bool needs_paint_indirect = false; + if (!skia::SupportsPlatformPaint(canvas)) { + // This block will only get hit with --enable-accelerated-drawing flag. + needs_paint_indirect = true; + } else { + // Scrollbars on Windows XP and the Windows Classic theme have particularly + // problematic alpha values, so always draw them indirectly. + switch (part) { + case kScrollbarDownArrow: + case kScrollbarUpArrow: + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + case kScrollbarHorizontalThumb: + case kScrollbarVerticalThumb: + case kScrollbarHorizontalGripper: + case kScrollbarVerticalGripper: + if (!GetThemeHandle(SCROLLBAR)) + needs_paint_indirect = true; + break; + default: + break; + } + } + + if (needs_paint_indirect) + PaintIndirect(canvas, part, state, rect, extra); + else + PaintDirect(canvas, part, state, rect, extra); +} + +NativeThemeWin::NativeThemeWin() + : theme_dll_(LoadLibrary(L"uxtheme.dll")), + draw_theme_(NULL), + draw_theme_ex_(NULL), + get_theme_color_(NULL), + get_theme_content_rect_(NULL), + get_theme_part_size_(NULL), + open_theme_(NULL), + close_theme_(NULL), + set_theme_properties_(NULL), + is_theme_active_(NULL), + get_theme_int_(NULL) { + if (theme_dll_) { + draw_theme_ = reinterpret_cast<DrawThemeBackgroundPtr>( + GetProcAddress(theme_dll_, "DrawThemeBackground")); + draw_theme_ex_ = reinterpret_cast<DrawThemeBackgroundExPtr>( + GetProcAddress(theme_dll_, "DrawThemeBackgroundEx")); + get_theme_color_ = reinterpret_cast<GetThemeColorPtr>( + GetProcAddress(theme_dll_, "GetThemeColor")); + get_theme_content_rect_ = reinterpret_cast<GetThemeContentRectPtr>( + GetProcAddress(theme_dll_, "GetThemeBackgroundContentRect")); + get_theme_part_size_ = reinterpret_cast<GetThemePartSizePtr>( + GetProcAddress(theme_dll_, "GetThemePartSize")); + open_theme_ = reinterpret_cast<OpenThemeDataPtr>( + GetProcAddress(theme_dll_, "OpenThemeData")); + close_theme_ = reinterpret_cast<CloseThemeDataPtr>( + GetProcAddress(theme_dll_, "CloseThemeData")); + set_theme_properties_ = reinterpret_cast<SetThemeAppPropertiesPtr>( + GetProcAddress(theme_dll_, "SetThemeAppProperties")); + is_theme_active_ = reinterpret_cast<IsThemeActivePtr>( + GetProcAddress(theme_dll_, "IsThemeActive")); + get_theme_int_ = reinterpret_cast<GetThemeIntPtr>( + GetProcAddress(theme_dll_, "GetThemeInt")); + } + memset(theme_handles_, 0, sizeof(theme_handles_)); +} + +NativeThemeWin::~NativeThemeWin() { + if (theme_dll_) { + // todo (cpu): fix this soon. Making a call to CloseHandles() here breaks + // certain tests and the reliability bots. + // CloseHandles(); + FreeLibrary(theme_dll_); + } +} + +void NativeThemeWin::PaintDirect(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const { + skia::ScopedPlatformPaint scoped_platform_paint(canvas); + HDC hdc = scoped_platform_paint.GetPlatformSurface(); + + switch (part) { + case kCheckbox: + PaintCheckbox(hdc, part, state, rect, extra.button); + break; + case kRadio: + PaintRadioButton(hdc, part, state, rect, extra.button); + break; + case kPushButton: + PaintPushButton(hdc, part, state, rect, extra.button); + break; + case kMenuPopupArrow: + PaintMenuArrow(hdc, state, rect, extra.menu_arrow); + break; + case kMenuPopupGutter: + PaintMenuGutter(hdc, rect); + break; + case kMenuPopupSeparator: + PaintMenuSeparator(hdc, rect, extra.menu_separator); + break; + case kMenuPopupBackground: + PaintMenuBackground(hdc, rect); + break; + case kMenuCheck: + PaintMenuCheck(hdc, state, rect, extra.menu_check); + break; + case kMenuCheckBackground: + PaintMenuCheckBackground(hdc, state, rect); + break; + case kMenuItemBackground: + PaintMenuItemBackground(hdc, state, rect, extra.menu_item); + break; + case kMenuList: + PaintMenuList(hdc, state, rect, extra.menu_list); + break; + case kScrollbarDownArrow: + case kScrollbarUpArrow: + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow); + break; + case kScrollbarHorizontalTrack: + case kScrollbarVerticalTrack: + PaintScrollbarTrack(canvas, hdc, part, state, rect, + extra.scrollbar_track); + break; + case kScrollbarHorizontalThumb: + case kScrollbarVerticalThumb: + case kScrollbarHorizontalGripper: + case kScrollbarVerticalGripper: + PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb); + break; + case kInnerSpinButton: + PaintSpinButton(hdc, part, state, rect, extra.inner_spin); + break; + case kTrackbarThumb: + case kTrackbarTrack: + PaintTrackbar(canvas, hdc, part, state, rect, extra.trackbar); + break; + case kProgressBar: + PaintProgressBar(hdc, rect, extra.progress_bar); + break; + case kWindowResizeGripper: + PaintWindowResizeGripper(hdc, rect); + break; + case kTabPanelBackground: + PaintTabPanelBackground(hdc, rect); + break; + case kTextField: + PaintTextField(hdc, part, state, rect, extra.text_field); + break; + + case kSliderTrack: + case kSliderThumb: + default: + // While transitioning NativeThemeWin to the single Paint() entry point, + // unsupported parts will DCHECK here. + NOTREACHED(); + } +} + +SkColor NativeThemeWin::GetSystemColor(ColorId color_id) const { + switch (color_id) { + + // Dialogs + case kColorId_DialogBackground: + // TODO(benrg): Should this use the new Windows theme functions? The old + // code in DialogClientView::OnPaint used GetSysColor(COLOR_3DFACE). + return WinColorToSkColor(GetSysColor(COLOR_3DFACE)); + + // FocusableBorder + case kColorId_FocusedBorderColor: + return kFocusedBorderColor; + case kColorId_UnfocusedBorderColor: + return kUnfocusedBorderColor; + + // TextButton + case kColorId_TextButtonBackgroundColor: + return kTextButtonBackgroundColor; + case kColorId_TextButtonEnabledColor: + return kTextButtonEnabledColor; + case kColorId_TextButtonDisabledColor: + return kTextButtonDisabledColor; + case kColorId_TextButtonHighlightColor: + return kTextButtonHighlightColor; + case kColorId_TextButtonHoverColor: + return kTextButtonHoverColor; + + // MenuItem + case kColorId_EnabledMenuItemForegroundColor: + return kEnabledMenuItemForegroundColor; + case kColorId_DisabledMenuItemForegroundColor: + return kDisabledMenuItemForegroundColor; + case kColorId_FocusedMenuItemBackgroundColor: + return kFocusedMenuItemBackgroundColor; + case kColorId_MenuSeparatorColor: + return kMenuSeparatorColor; + + // Label + case kColorId_LabelEnabledColor: + return kLabelEnabledColor; + case kColorId_LabelDisabledColor: + return kLabelDisabledColor; + case kColorId_LabelBackgroundColor: + return kLabelBackgroundColor; + + // Textfield + case kColorId_TextfieldDefaultColor: + return kTextfieldDefaultColor; + case kColorId_TextfieldDefaultBackground: + return kTextfieldDefaultBackground; + case kColorId_TextfieldSelectionColor: + return kTextfieldSelectionColor; + case kColorId_TextfieldSelectionBackgroundFocused: + return kTextfieldSelectionBackgroundFocused; + case kColorId_TextfieldSelectionBackgroundUnfocused: + return kTextfieldSelectionBackgroundUnfocused; + + default: + NOTREACHED() << "Invalid color_id: " << color_id; + break; + } + return kInvalidColorIdColor; +} + +void NativeThemeWin::PaintIndirect(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const { + // TODO(asvitkine): This path is pretty inefficient - for each paint operation + // it creates a new offscreen bitmap Skia canvas. This can + // be sped up by doing it only once per part/state and + // keeping a cache of the resulting bitmaps. + + // Create an offscreen canvas that is backed by an HDC. + skia::BitmapPlatformDevice* device = skia::BitmapPlatformDevice::Create( + rect.width(), rect.height(), false, NULL); + DCHECK(device); + SkCanvas offscreen_canvas(device); + device->unref(); + DCHECK(skia::SupportsPlatformPaint(&offscreen_canvas)); + + // Some of the Windows theme drawing operations do not write correct alpha + // values for fully-opaque pixels; instead the pixels get alpha 0. This is + // especially a problem on Windows XP or when using the Classic theme. + // + // To work-around this, mark all pixels with a placeholder value, to detect + // which pixels get touched by the paint operation. After paint, set any + // pixels that have alpha 0 to opaque and placeholders to fully-transparent. + const SkColor placeholder = SkColorSetARGB(1, 0, 0, 0); + offscreen_canvas.clear(placeholder); + + // Offset destination rects to have origin (0,0). + gfx::Rect adjusted_rect(rect.size()); + ExtraParams adjusted_extra(extra); + switch (part) { + case kProgressBar: + adjusted_extra.progress_bar.value_rect_x = 0; + adjusted_extra.progress_bar.value_rect_y = 0; + break; + case kScrollbarHorizontalTrack: + case kScrollbarVerticalTrack: + adjusted_extra.scrollbar_track.track_x = 0; + adjusted_extra.scrollbar_track.track_y = 0; + break; + default: break; + } + // Draw the theme controls using existing HDC-drawing code. + PaintDirect(&offscreen_canvas, + part, + state, + adjusted_rect, + adjusted_extra); + + // Copy the pixels to a bitmap that has ref-counted pixel storage, which is + // necessary to have when drawing to a SkPicture. + const SkBitmap& hdc_bitmap = + offscreen_canvas.getDevice()->accessBitmap(false); + SkBitmap bitmap; + hdc_bitmap.copyTo(&bitmap, SkBitmap::kARGB_8888_Config); + + // Post-process the pixels to fix up the alpha values (see big comment above). + const SkPMColor placeholder_value = SkPreMultiplyColor(placeholder); + const int pixel_count = rect.width() * rect.height(); + SkPMColor* pixels = bitmap.getAddr32(0, 0); + for (int i = 0; i < pixel_count; i++) { + if (pixels[i] == placeholder_value) { + // Pixel wasn't touched - make it fully transparent. + pixels[i] = SkPackARGB32(0, 0, 0, 0); + } else if (SkGetPackedA32(pixels[i]) == 0) { + // Pixel was touched but has incorrect alpha of 0, make it fully opaque. + pixels[i] = SkPackARGB32(0xFF, + SkGetPackedR32(pixels[i]), + SkGetPackedG32(pixels[i]), + SkGetPackedB32(pixels[i])); + } + } + + // Draw the offscreen bitmap to the destination canvas. + canvas->drawBitmap(bitmap, rect.x(), rect.y()); +} + +HRESULT NativeThemeWin::GetThemePartSize(ThemeName theme_name, + HDC hdc, + int part_id, + int state_id, + RECT* rect, + int ts, + SIZE* size) const { + HANDLE handle = GetThemeHandle(theme_name); + if (handle && get_theme_part_size_) + return get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size); + + return E_NOTIMPL; +} + +HRESULT NativeThemeWin::PaintButton(HDC hdc, + State state, + const ButtonExtraParams& extra, + int part_id, + int state_id, + RECT* rect) const { + HANDLE handle = GetThemeHandle(BUTTON); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, part_id, state_id, rect, NULL); + + // Adjust classic_state based on part, state, and extras. + int classic_state = extra.classic_state; + switch (part_id) { + case BP_CHECKBOX: + classic_state |= DFCS_BUTTONCHECK; + break; + case BP_RADIOBUTTON: + classic_state |= DFCS_BUTTONRADIO; + break; + case BP_PUSHBUTTON: + classic_state |= DFCS_BUTTONPUSH; + break; + default: + NOTREACHED() << "Unknown part_id: " << part_id; + break; + } + + switch (state) { + case kDisabled: + classic_state |= DFCS_INACTIVE; + break; + case kPressed: + classic_state |= DFCS_PUSHED; + break; + case kNormal: + case kHovered: + break; + default: + NOTREACHED() << "Unknown state: " << state; + break; + } + + if (extra.checked) + classic_state |= DFCS_CHECKED; + + // Draw it manually. + // All pressed states have both low bits set, and no other states do. + const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED); + const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED); + if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) { + // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the + // button itself is shrunk by 1 pixel. + HBRUSH brush = GetSysColorBrush(COLOR_3DDKSHADOW); + if (brush) { + FrameRect(hdc, rect, brush); + InflateRect(rect, -1, -1); + } + } + DrawFrameControl(hdc, rect, DFC_BUTTON, classic_state); + + // Draw the focus rectangle (the dotted line box) only on buttons. For radio + // and checkboxes, we let webkit draw the focus rectangle (orange glow). + if ((BP_PUSHBUTTON == part_id) && focused) { + // The focus rect is inside the button. The exact number of pixels depends + // on whether we're in classic mode or using uxtheme. + if (handle && get_theme_content_rect_) { + get_theme_content_rect_(handle, hdc, part_id, state_id, rect, rect); + } else { + InflateRect(rect, -GetSystemMetrics(SM_CXEDGE), + -GetSystemMetrics(SM_CYEDGE)); + } + DrawFocusRect(hdc, rect); + } + + return S_OK; +} + +HRESULT NativeThemeWin::PaintMenuSeparator( + HDC hdc, + const gfx::Rect& rect, + const MenuSeparatorExtraParams& extra) const { + RECT rect_win = rect.ToRECT(); + + HANDLE handle = GetThemeHandle(MENU); + if (handle && draw_theme_) { + // Delta is needed for non-classic to move separator up slightly. + --rect_win.top; + --rect_win.bottom; + return draw_theme_(handle, hdc, MENU_POPUPSEPARATOR, MPI_NORMAL, &rect_win, + NULL); + } + + DrawEdge(hdc, &rect_win, EDGE_ETCHED, BF_TOP); + return S_OK; +} + +HRESULT NativeThemeWin::PaintMenuGutter(HDC hdc, + const gfx::Rect& rect) const { + RECT rect_win = rect.ToRECT(); + HANDLE handle = GetThemeHandle(MENU); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, MENU_POPUPGUTTER, MPI_NORMAL, &rect_win, + NULL); + return E_NOTIMPL; +} + +HRESULT NativeThemeWin::PaintMenuArrow(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuArrowExtraParams& extra) + const { + int state_id = MSM_NORMAL; + if (state == kDisabled) + state_id = MSM_DISABLED; + + HANDLE handle = GetThemeHandle(MENU); + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) { + if (extra.pointing_right) { + return draw_theme_(handle, hdc, MENU_POPUPSUBMENU, state_id, &rect_win, + NULL); + } else { + // There is no way to tell the uxtheme API to draw a left pointing arrow; + // it doesn't have a flag equivalent to DFCS_MENUARROWRIGHT. But they + // are needed for RTL locales on Vista. So use a memory DC and mirror + // the region with GDI's StretchBlt. + gfx::Rect r(rect); + base::win::ScopedCreateDC mem_dc(CreateCompatibleDC(hdc)); + base::win::ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(), + r.height())); + base::win::ScopedSelectObject select_bitmap(mem_dc, mem_bitmap); + // Copy and horizontally mirror the background from hdc into mem_dc. Use + // a negative-width source rect, starting at the rightmost pixel. + StretchBlt(mem_dc, 0, 0, r.width(), r.height(), + hdc, r.right()-1, r.y(), -r.width(), r.height(), SRCCOPY); + // Draw the arrow. + RECT theme_rect = {0, 0, r.width(), r.height()}; + HRESULT result = draw_theme_(handle, mem_dc, MENU_POPUPSUBMENU, + state_id, &theme_rect, NULL); + // Copy and mirror the result back into mem_dc. + StretchBlt(hdc, r.x(), r.y(), r.width(), r.height(), + mem_dc, r.width()-1, 0, -r.width(), r.height(), SRCCOPY); + return result; + } + } + + // For some reason, Windows uses the name DFCS_MENUARROWRIGHT to indicate a + // left pointing arrow. This makes the following 'if' statement slightly + // counterintuitive. + UINT pfc_state; + if (extra.pointing_right) + pfc_state = DFCS_MENUARROW; + else + pfc_state = DFCS_MENUARROWRIGHT; + return PaintFrameControl(hdc, rect, DFC_MENU, pfc_state, extra.is_selected, + state); +} + +HRESULT NativeThemeWin::PaintMenuBackground(HDC hdc, + const gfx::Rect& rect) const { + HANDLE handle = GetThemeHandle(MENU); + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) { + HRESULT result = draw_theme_(handle, hdc, MENU_POPUPBACKGROUND, 0, + &rect_win, NULL); + FrameRect(hdc, &rect_win, GetSysColorBrush(COLOR_3DSHADOW)); + return result; + } + + FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_MENU)); + DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT); + return S_OK; +} + +HRESULT NativeThemeWin::PaintMenuCheck( + HDC hdc, + State state, + const gfx::Rect& rect, + const MenuCheckExtraParams& extra) const { + HANDLE handle = GetThemeHandle(MENU); + int state_id; + if (extra.is_radio) { + state_id = state == kDisabled ? MC_BULLETDISABLED : MC_BULLETNORMAL; + } else { + state_id = state == kDisabled ? MC_CHECKMARKDISABLED : MC_CHECKMARKNORMAL; + } + + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, MENU_POPUPCHECK, state_id, &rect_win, NULL); + + return PaintFrameControl(hdc, rect, DFC_MENU, + extra.is_radio ? DFCS_MENUBULLET : DFCS_MENUCHECK, + extra.is_selected, state); +} + +HRESULT NativeThemeWin::PaintMenuCheckBackground(HDC hdc, + State state, + const gfx::Rect& rect) const { + HANDLE handle = GetThemeHandle(MENU); + int state_id = state == kDisabled ? MCB_DISABLED : MCB_NORMAL; + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, MENU_POPUPCHECKBACKGROUND, state_id, + &rect_win, NULL); + // Nothing to do for background. + return S_OK; +} + +HRESULT NativeThemeWin::PaintMenuItemBackground( + HDC hdc, + State state, + const gfx::Rect& rect, + const MenuItemExtraParams& extra) const { + HANDLE handle = GetThemeHandle(MENU); + RECT rect_win = rect.ToRECT(); + int state_id; + switch (state) { + case kNormal: + state_id = MPI_NORMAL; + break; + case kDisabled: + state_id = extra.is_selected ? MPI_DISABLEDHOT : MPI_DISABLED; + break; + case kHovered: + state_id = MPI_HOT; + break; + default: + NOTREACHED() << "Invalid state " << state; + break; + } + + if (handle && draw_theme_) + return draw_theme_(handle, hdc, MENU_POPUPITEM, state_id, &rect_win, NULL); + + if (extra.is_selected) + FillRect(hdc, &rect_win, GetSysColorBrush(COLOR_HIGHLIGHT)); + return S_OK; +} + +HRESULT NativeThemeWin::PaintPushButton(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const { + int state_id; + switch (state) { + case kDisabled: + state_id = PBS_DISABLED; + break; + case kHovered: + state_id = PBS_HOT; + break; + case kNormal: + state_id = extra.is_default ? PBS_DEFAULTED : PBS_NORMAL; + break; + case kPressed: + state_id = PBS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + RECT rect_win = rect.ToRECT(); + return PaintButton(hdc, state, extra, BP_PUSHBUTTON, state_id, &rect_win); +} + +HRESULT NativeThemeWin::PaintRadioButton(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const { + int state_id; + switch (state) { + case kDisabled: + state_id = extra.checked ? RBS_CHECKEDDISABLED : RBS_UNCHECKEDDISABLED; + break; + case kHovered: + state_id = extra.checked ? RBS_CHECKEDHOT : RBS_UNCHECKEDHOT; + break; + case kNormal: + state_id = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL; + break; + case kPressed: + state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + RECT rect_win = rect.ToRECT(); + return PaintButton(hdc, state, extra, BP_RADIOBUTTON, state_id, &rect_win); +} + +HRESULT NativeThemeWin::PaintCheckbox(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const { + int state_id; + switch (state) { + case kDisabled: + state_id = extra.checked ? CBS_CHECKEDDISABLED : + extra.indeterminate ? CBS_MIXEDDISABLED : + CBS_UNCHECKEDDISABLED; + break; + case kHovered: + state_id = extra.checked ? CBS_CHECKEDHOT : + extra.indeterminate ? CBS_MIXEDHOT : + CBS_UNCHECKEDHOT; + break; + case kNormal: + state_id = extra.checked ? CBS_CHECKEDNORMAL : + extra.indeterminate ? CBS_MIXEDNORMAL : + CBS_UNCHECKEDNORMAL; + break; + case kPressed: + state_id = extra.checked ? CBS_CHECKEDPRESSED : + extra.indeterminate ? CBS_MIXEDPRESSED : + CBS_UNCHECKEDPRESSED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + RECT rect_win = rect.ToRECT(); + return PaintButton(hdc, state, extra, BP_CHECKBOX, state_id, &rect_win); +} + +HRESULT NativeThemeWin::PaintMenuList(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& extra) const { + HANDLE handle = GetThemeHandle(MENULIST); + RECT rect_win = rect.ToRECT(); + int state_id; + switch (state) { + case kNormal: + state_id = CBXS_NORMAL; + break; + case kDisabled: + state_id = CBXS_DISABLED; + break; + case kHovered: + state_id = CBXS_HOT; + break; + case kPressed: + state_id = CBXS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state " << state; + break; + } + + if (handle && draw_theme_) + return draw_theme_(handle, hdc, CP_DROPDOWNBUTTON, state_id, &rect_win, + NULL); + + // Draw it manually. + DrawFrameControl(hdc, &rect_win, DFC_SCROLL, + DFCS_SCROLLCOMBOBOX | extra.classic_state); + return S_OK; +} + +HRESULT NativeThemeWin::PaintScrollbarArrow( + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarArrowExtraParams& extra) const { + static const int state_id_matrix[4][kMaxState] = { + ABS_DOWNDISABLED, ABS_DOWNHOT, ABS_DOWNNORMAL, ABS_DOWNPRESSED, + ABS_LEFTDISABLED, ABS_LEFTHOT, ABS_LEFTNORMAL, ABS_LEFTPRESSED, + ABS_RIGHTDISABLED, ABS_RIGHTHOT, ABS_RIGHTNORMAL, ABS_RIGHTPRESSED, + ABS_UPDISABLED, ABS_UPHOT, ABS_UPNORMAL, ABS_UPPRESSED + }; + HANDLE handle = GetThemeHandle(SCROLLBAR); + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) { + int index = part - kScrollbarDownArrow; + DCHECK(index >=0 && index < 4); + int state_id = state_id_matrix[index][state]; + + // Hovering means that the cursor is over the scroolbar, but not over the + // specific arrow itself. We don't want to show it "hot" mode, but only + // in "hover" mode. + if (state == kHovered && extra.is_hovering) { + switch (part) { + case kScrollbarDownArrow: + state_id = ABS_DOWNHOVER; + break; + case kScrollbarLeftArrow: + state_id = ABS_LEFTHOVER; + break; + case kScrollbarRightArrow: + state_id = ABS_RIGHTHOVER; + break; + case kScrollbarUpArrow: + state_id = ABS_UPHOVER; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + } + + return draw_theme_(handle, hdc, SBP_ARROWBTN, state_id, &rect_win, NULL); + } + + int classic_state = DFCS_SCROLLDOWN; + switch (part) { + case kScrollbarDownArrow: + classic_state = DFCS_SCROLLDOWN; + break; + case kScrollbarLeftArrow: + classic_state = DFCS_SCROLLLEFT; + break; + case kScrollbarRightArrow: + classic_state = DFCS_SCROLLRIGHT; + break; + case kScrollbarUpArrow: + classic_state = DFCS_SCROLLUP; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + switch (state) { + case kDisabled: + classic_state |= DFCS_INACTIVE; + break; + case kHovered: + classic_state |= DFCS_HOT; + break; + case kNormal: + break; + case kPressed: + classic_state |= DFCS_PUSHED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + DrawFrameControl(hdc, &rect_win, DFC_SCROLL, classic_state); + return S_OK; +} + +HRESULT NativeThemeWin::PaintScrollbarThumb( + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarThumbExtraParams& extra) const { + HANDLE handle = GetThemeHandle(SCROLLBAR); + RECT rect_win = rect.ToRECT(); + int part_id; + int state_id; + + switch (part) { + case NativeTheme::kScrollbarHorizontalThumb: + part_id = SBP_THUMBBTNHORZ; + break; + case NativeTheme::kScrollbarVerticalThumb: + part_id = SBP_THUMBBTNVERT; + break; + case NativeTheme::kScrollbarHorizontalGripper: + part_id = SBP_GRIPPERHORZ; + break; + case NativeTheme::kScrollbarVerticalGripper: + part_id = SBP_GRIPPERVERT; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + + switch (state) { + case kDisabled: + state_id = SCRBS_DISABLED; + break; + case kHovered: + state_id = extra.is_hovering ? SCRBS_HOVER : SCRBS_HOT; + break; + case kNormal: + state_id = SCRBS_NORMAL; + break; + case kPressed: + state_id = SCRBS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + if (handle && draw_theme_) + return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); + + // Draw it manually. + if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT)) + DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT | BF_MIDDLE); + // Classic mode doesn't have a gripper. + return S_OK; +} + +HRESULT NativeThemeWin::PaintScrollbarTrack( + SkCanvas* canvas, + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarTrackExtraParams& extra) const { + HANDLE handle = GetThemeHandle(SCROLLBAR); + RECT rect_win = rect.ToRECT(); + int part_id; + int state_id; + + switch (part) { + case NativeTheme::kScrollbarHorizontalTrack: + part_id = extra.is_upper ? SBP_UPPERTRACKHORZ : SBP_LOWERTRACKHORZ; + break; + case NativeTheme::kScrollbarVerticalTrack: + part_id = extra.is_upper ? SBP_UPPERTRACKVERT : SBP_LOWERTRACKVERT; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + + switch (state) { + case kDisabled: + state_id = SCRBS_DISABLED; + break; + case kHovered: + state_id = SCRBS_HOVER; + break; + case kNormal: + state_id = SCRBS_NORMAL; + break; + case kPressed: + state_id = SCRBS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + if (handle && draw_theme_) + return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); + + // Draw it manually. + const DWORD colorScrollbar = GetSysColor(COLOR_SCROLLBAR); + const DWORD color3DFace = GetSysColor(COLOR_3DFACE); + if ((colorScrollbar != color3DFace) && + (colorScrollbar != GetSysColor(COLOR_WINDOW))) { + FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); + } else { + SkPaint paint; + RECT align_rect = gfx::Rect(extra.track_x, extra.track_y, extra.track_width, + extra.track_height).ToRECT(); + SetCheckerboardShader(&paint, align_rect); + canvas->drawIRect(skia::RECTToSkIRect(rect_win), paint); + } + if (extra.classic_state & DFCS_PUSHED) + InvertRect(hdc, &rect_win); + return S_OK; +} + +HRESULT NativeThemeWin::PaintSpinButton( + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const InnerSpinButtonExtraParams& extra) const { + HANDLE handle = GetThemeHandle(SPIN); + RECT rect_win = rect.ToRECT(); + int part_id = extra.spin_up ? SPNP_UP : SPNP_DOWN; + int state_id; + switch (state) { + case kDisabled: + state_id = extra.spin_up ? UPS_DISABLED : DNS_DISABLED; + break; + case kHovered: + state_id = extra.spin_up ? UPS_HOT : DNS_HOT; + break; + case kNormal: + state_id = extra.spin_up ? UPS_NORMAL : DNS_NORMAL; + break; + case kPressed: + state_id = extra.spin_up ? UPS_PRESSED : DNS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state " << state; + break; + } + + if (handle && draw_theme_) + return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL); + DrawFrameControl(hdc, &rect_win, DFC_SCROLL, extra.classic_state); + return S_OK; +} + +HRESULT NativeThemeWin::PaintTrackbar( + SkCanvas* canvas, + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const TrackbarExtraParams& extra) const { + int part_id = part == kTrackbarTrack ? TKP_TRACK : TKP_THUMBBOTTOM; + if (extra.vertical) + part_id = part == kTrackbarTrack ? TKP_TRACKVERT : TKP_THUMBVERT; + + int state_id = 0; + switch (state) { + case kDisabled: + state_id = TUS_DISABLED; + break; + case kHovered: + state_id = TUS_HOT; + break; + case kNormal: + state_id = TUS_NORMAL; + break; + case kPressed: + state_id = TUS_PRESSED; + break; + default: + NOTREACHED() << "Invalid state " << state; + break; + } + + // Make the channel be 4 px thick in the center of the supplied rect. (4 px + // matches what XP does in various menus; GetThemePartSize() doesn't seem to + // return good values here.) + RECT rect_win = rect.ToRECT(); + RECT channel_rect = rect.ToRECT(); + const int channel_thickness = 4; + if (part_id == TKP_TRACK) { + channel_rect.top += + ((channel_rect.bottom - channel_rect.top - channel_thickness) / 2); + channel_rect.bottom = channel_rect.top + channel_thickness; + } else if (part_id == TKP_TRACKVERT) { + channel_rect.left += + ((channel_rect.right - channel_rect.left - channel_thickness) / 2); + channel_rect.right = channel_rect.left + channel_thickness; + } // else this isn't actually a channel, so |channel_rect| == |rect|. + + HANDLE handle = GetThemeHandle(TRACKBAR); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, part_id, state_id, &channel_rect, NULL); + + // Classic mode, draw it manually. + if ((part_id == TKP_TRACK) || (part_id == TKP_TRACKVERT)) { + DrawEdge(hdc, &channel_rect, EDGE_SUNKEN, BF_RECT); + } else if (part_id == TKP_THUMBVERT) { + DrawEdge(hdc, &rect_win, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE); + } else { + // Split rect into top and bottom pieces. + RECT top_section = rect.ToRECT(); + RECT bottom_section = rect.ToRECT(); + top_section.bottom -= ((bottom_section.right - bottom_section.left) / 2); + bottom_section.top = top_section.bottom; + DrawEdge(hdc, &top_section, EDGE_RAISED, + BF_LEFT | BF_TOP | BF_RIGHT | BF_SOFT | BF_MIDDLE | BF_ADJUST); + + // Split triangular piece into two diagonals. + RECT& left_half = bottom_section; + RECT right_half = bottom_section; + right_half.left += ((bottom_section.right - bottom_section.left) / 2); + left_half.right = right_half.left; + DrawEdge(hdc, &left_half, EDGE_RAISED, + BF_DIAGONAL_ENDTOPLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST); + DrawEdge(hdc, &right_half, EDGE_RAISED, + BF_DIAGONAL_ENDBOTTOMLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST); + + // If the button is pressed, draw hatching. + if (extra.classic_state & DFCS_PUSHED) { + SkPaint paint; + SetCheckerboardShader(&paint, rect_win); + + // Fill all three pieces with the pattern. + canvas->drawIRect(skia::RECTToSkIRect(top_section), paint); + + SkScalar left_triangle_top = SkIntToScalar(left_half.top); + SkScalar left_triangle_right = SkIntToScalar(left_half.right); + SkPath left_triangle; + left_triangle.moveTo(SkIntToScalar(left_half.left), left_triangle_top); + left_triangle.lineTo(left_triangle_right, left_triangle_top); + left_triangle.lineTo(left_triangle_right, + SkIntToScalar(left_half.bottom)); + left_triangle.close(); + canvas->drawPath(left_triangle, paint); + + SkScalar right_triangle_left = SkIntToScalar(right_half.left); + SkScalar right_triangle_top = SkIntToScalar(right_half.top); + SkPath right_triangle; + right_triangle.moveTo(right_triangle_left, right_triangle_top); + right_triangle.lineTo(SkIntToScalar(right_half.right), + right_triangle_top); + right_triangle.lineTo(right_triangle_left, + SkIntToScalar(right_half.bottom)); + right_triangle.close(); + canvas->drawPath(right_triangle, paint); + } + } + return S_OK; +} + +HRESULT NativeThemeWin::PaintProgressBar( + HDC hdc, + const gfx::Rect& rect, + const ProgressBarExtraParams& extra) const { + // There is no documentation about the animation speed, frame-rate, nor + // size of moving overlay of the indeterminate progress bar. + // So we just observed real-world programs and guessed following parameters. + const int kDeteminateOverlayPixelsPerSecond = 300; + const int kDeteminateOverlayWidth = 120; + const int kIndeterminateOverlayPixelsPerSecond = 175; + const int kVistaIndeterminateOverlayWidth = 120; + const int kXPIndeterminateOverlayWidth = 55; + // The thickness of the bar frame inside |value_rect| + const int kXPBarPadding = 3; + + RECT bar_rect = rect.ToRECT(); + RECT value_rect = gfx::Rect(extra.value_rect_x, + extra.value_rect_y, + extra.value_rect_width, + extra.value_rect_height).ToRECT(); + + bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA; + HANDLE handle = GetThemeHandle(PROGRESS); + if (handle && draw_theme_ && draw_theme_ex_) { + draw_theme_(handle, hdc, PP_BAR, 0, &bar_rect, NULL); + + int bar_width = bar_rect.right - bar_rect.left; + if (extra.determinate) { + // TODO(morrita): this RTL guess can be wrong. + // We should pass the direction from WebKit side. + bool is_rtl = (bar_rect.right == value_rect.right && + bar_rect.left != value_rect.left); + // We should care the direction here because PP_CNUNK painting + // is asymmetric. + DTBGOPTS value_draw_options; + value_draw_options.dwSize = sizeof(DTBGOPTS); + value_draw_options.dwFlags = is_rtl ? DTBG_MIRRORDC : 0; + value_draw_options.rcClip = bar_rect; + + if (pre_vista) { + // On XP, progress bar is chunk-style and has no glossy effect. + // We need to shrink destination rect to fit the part inside the bar + // with an appropriate margin. + RECT shrunk_value_rect = InsetRect(&value_rect, kXPBarPadding); + draw_theme_ex_(handle, hdc, PP_CHUNK, 0, + &shrunk_value_rect, &value_draw_options); + } else { + // On Vista or later, the progress bar part has a + // single-block value part. It also has glossy effect. + // And the value part has exactly same height as the bar part + // so we don't need to shrink the rect. + draw_theme_ex_(handle, hdc, PP_FILL, 0, + &value_rect, &value_draw_options); + + int dx = ComputeAnimationProgress(bar_width, + kDeteminateOverlayWidth, + kDeteminateOverlayPixelsPerSecond, + extra.animated_seconds); + RECT overlay_rect = value_rect; + overlay_rect.left += dx; + overlay_rect.right = overlay_rect.left + kDeteminateOverlayWidth; + draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &value_rect); + } + } else { + // A glossy overlay for indeterminate progress bar has small pause + // after each animation. We emulate this by adding an invisible margin + // the animation has to traverse. + int width_with_margin = bar_width + kIndeterminateOverlayPixelsPerSecond; + int overlay_width = pre_vista ? + kXPIndeterminateOverlayWidth : kVistaIndeterminateOverlayWidth; + int dx = ComputeAnimationProgress(width_with_margin, + overlay_width, + kIndeterminateOverlayPixelsPerSecond, + extra.animated_seconds); + RECT overlay_rect = bar_rect; + overlay_rect.left += dx; + overlay_rect.right = overlay_rect.left + overlay_width; + if (pre_vista) { + RECT shrunk_rect = InsetRect(&overlay_rect, kXPBarPadding); + RECT shrunk_bar_rect = InsetRect(&bar_rect, kXPBarPadding); + draw_theme_(handle, hdc, PP_CHUNK, 0, &shrunk_rect, &shrunk_bar_rect); + } else { + draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &bar_rect); + } + } + + return S_OK; + } + + HBRUSH bg_brush = GetSysColorBrush(COLOR_BTNFACE); + HBRUSH fg_brush = GetSysColorBrush(COLOR_BTNSHADOW); + FillRect(hdc, &bar_rect, bg_brush); + FillRect(hdc, &value_rect, fg_brush); + DrawEdge(hdc, &bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + return S_OK; +} + +HRESULT NativeThemeWin::PaintWindowResizeGripper(HDC hdc, + const gfx::Rect& rect) const { + HANDLE handle = GetThemeHandle(STATUS); + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) { + // Paint the status bar gripper. There doesn't seem to be a + // standard gripper in Windows for the space between + // scrollbars. This is pretty close, but it's supposed to be + // painted over a status bar. + return draw_theme_(handle, hdc, SP_GRIPPER, 0, &rect_win, NULL); + } + + // Draw a windows classic scrollbar gripper. + DrawFrameControl(hdc, &rect_win, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); + return S_OK; +} + +HRESULT NativeThemeWin::PaintTabPanelBackground(HDC hdc, + const gfx::Rect& rect) const { + HANDLE handle = GetThemeHandle(TAB); + RECT rect_win = rect.ToRECT(); + if (handle && draw_theme_) + return draw_theme_(handle, hdc, TABP_BODY, 0, &rect_win, NULL); + + // Classic just renders a flat color background. + FillRect(hdc, &rect_win, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1)); + return S_OK; +} + +HRESULT NativeThemeWin::PaintTextField( + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const TextFieldExtraParams& extra) const { + int part_id = EP_EDITTEXT; + int state_id = ETS_NORMAL; + switch (state) { + case kNormal: + if (extra.is_read_only) { + state_id = ETS_READONLY; + } else if (extra.is_focused) { + state_id = ETS_FOCUSED; + } else { + state_id = ETS_NORMAL; + } + break; + case kHovered: + state_id = ETS_HOT; + break; + case kPressed: + state_id = ETS_SELECTED; + break; + case kDisabled: + state_id = ETS_DISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + + RECT rect_win = rect.ToRECT(); + return PaintTextField(hdc, part_id, state_id, extra.classic_state, + &rect_win, + skia::SkColorToCOLORREF(extra.background_color), + extra.fill_content_area, extra.draw_edges); +} + +HRESULT NativeThemeWin::PaintTextField(HDC hdc, + int part_id, + int state_id, + int classic_state, + RECT* rect, + COLORREF color, + bool fill_content_area, + bool draw_edges) const { + // TODO(ojan): http://b/1210017 Figure out how to give the ability to + // exclude individual edges from being drawn. + + HANDLE handle = GetThemeHandle(TEXTFIELD); + // TODO(mpcomplete): can we detect if the color is specified by the user, + // and if not, just use the system color? + // CreateSolidBrush() accepts a RGB value but alpha must be 0. + HBRUSH bg_brush = CreateSolidBrush(color); + HRESULT hr; + // DrawThemeBackgroundEx was introduced in XP SP2, so that it's possible + // draw_theme_ex_ is NULL and draw_theme_ is non-null. + if (handle && (draw_theme_ex_ || (draw_theme_ && draw_edges))) { + if (draw_theme_ex_) { + static const DTBGOPTS omit_border_options = { + sizeof(DTBGOPTS), + DTBG_OMITBORDER, + { 0, 0, 0, 0 } + }; + const DTBGOPTS* draw_opts = draw_edges ? NULL : &omit_border_options; + hr = draw_theme_ex_(handle, hdc, part_id, state_id, rect, draw_opts); + } else { + hr = draw_theme_(handle, hdc, part_id, state_id, rect, NULL); + } + + // TODO(maruel): Need to be fixed if get_theme_content_rect_ is NULL. + if (fill_content_area && get_theme_content_rect_) { + RECT content_rect; + hr = get_theme_content_rect_(handle, hdc, part_id, state_id, rect, + &content_rect); + FillRect(hdc, &content_rect, bg_brush); + } + } else { + // Draw it manually. + if (draw_edges) + DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST); + + if (fill_content_area) { + FillRect(hdc, rect, (classic_state & DFCS_INACTIVE) ? + reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) : bg_brush); + } + hr = S_OK; + } + DeleteObject(bg_brush); + return hr; +} + +// static +NativeThemeWin::ThemeName NativeThemeWin::GetThemeName(Part part) { + ThemeName name; + switch (part) { + case kCheckbox: + case kRadio: + case kPushButton: + name = BUTTON; + break; + case kInnerSpinButton: + name = SPIN; + break; + case kMenuCheck: + case kMenuPopupGutter: + case kMenuList: + case kMenuPopupArrow: + case kMenuPopupSeparator: + name = MENU; + break; + case kProgressBar: + name = PROGRESS; + break; + case kScrollbarDownArrow: + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + case kScrollbarUpArrow: + case kScrollbarHorizontalThumb: + case kScrollbarVerticalThumb: + case kScrollbarHorizontalTrack: + case kScrollbarVerticalTrack: + name = SCROLLBAR; + break; + case kSliderTrack: + case kSliderThumb: + name = TRACKBAR; + break; + case kTextField: + name = TEXTFIELD; + break; + case kWindowResizeGripper: + name = STATUS; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + return name; +} + +// static +int NativeThemeWin::GetWindowsPart(Part part, + State state, + const ExtraParams& extra) { + int part_id; + switch (part) { + case kCheckbox: + part_id = BP_CHECKBOX; + break; + case kMenuCheck: + part_id = MENU_POPUPCHECK; + break; + case kMenuPopupArrow: + part_id = MENU_POPUPSUBMENU; + break; + case kMenuPopupGutter: + part_id = MENU_POPUPGUTTER; + break; + case kMenuPopupSeparator: + part_id = MENU_POPUPSEPARATOR; + break; + case kPushButton: + part_id = BP_PUSHBUTTON; + break; + case kRadio: + part_id = BP_RADIOBUTTON; + break; + case kWindowResizeGripper: + part_id = SP_GRIPPER; + break; + case kScrollbarDownArrow: + case kScrollbarLeftArrow: + case kScrollbarRightArrow: + case kScrollbarUpArrow: + part_id = SBP_ARROWBTN; + break; + case kScrollbarHorizontalThumb: + part_id = extra.scrollbar_track.is_upper ? SBP_UPPERTRACKHORZ : + SBP_LOWERTRACKHORZ; + break; + case kScrollbarVerticalThumb: + part_id = extra.scrollbar_track.is_upper ? SBP_UPPERTRACKVERT : + SBP_LOWERTRACKVERT; + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + return part_id; +} + +int NativeThemeWin::GetWindowsState(Part part, + State state, + const ExtraParams& extra) { + int state_id; + switch (part) { + case kCheckbox: + switch (state) { + case kNormal: + state_id = CBS_UNCHECKEDNORMAL; + break; + case kHovered: + state_id = CBS_UNCHECKEDHOT; + break; + case kPressed: + state_id = CBS_UNCHECKEDPRESSED; + break; + case kDisabled: + state_id = CBS_UNCHECKEDDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kMenuCheck: + switch (state) { + case kNormal: + case kHovered: + case kPressed: + state_id = extra.menu_check.is_radio ? MC_BULLETNORMAL + : MC_CHECKMARKNORMAL; + break; + case kDisabled: + state_id = extra.menu_check.is_radio ? MC_BULLETDISABLED + : MC_CHECKMARKDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kMenuPopupArrow: + case kMenuPopupGutter: + case kMenuPopupSeparator: + switch (state) { + case kNormal: + state_id = MBI_NORMAL; + break; + case kHovered: + state_id = MBI_HOT; + break; + case kPressed: + state_id = MBI_PUSHED; + break; + case kDisabled: + state_id = MBI_DISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kPushButton: + switch (state) { + case kNormal: + state_id = PBS_NORMAL; + break; + case kHovered: + state_id = PBS_HOT; + break; + case kPressed: + state_id = PBS_PRESSED; + break; + case kDisabled: + state_id = PBS_DISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kRadio: + switch (state) { + case kNormal: + state_id = RBS_UNCHECKEDNORMAL; + break; + case kHovered: + state_id = RBS_UNCHECKEDHOT; + break; + case kPressed: + state_id = RBS_UNCHECKEDPRESSED; + break; + case kDisabled: + state_id = RBS_UNCHECKEDDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kWindowResizeGripper: + switch (state) { + case kNormal: + case kHovered: + case kPressed: + case kDisabled: + state_id = 1; // gripper has no windows state + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kScrollbarDownArrow: + switch (state) { + case kNormal: + state_id = ABS_DOWNNORMAL; + break; + case kHovered: + // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. + state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? + ABS_DOWNHOT : ABS_DOWNHOVER; + break; + case kPressed: + state_id = ABS_DOWNPRESSED; + break; + case kDisabled: + state_id = ABS_DOWNDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kScrollbarLeftArrow: + switch (state) { + case kNormal: + state_id = ABS_LEFTNORMAL; + break; + case kHovered: + // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. + state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? + ABS_LEFTHOT : ABS_LEFTHOVER; + break; + case kPressed: + state_id = ABS_LEFTPRESSED; + break; + case kDisabled: + state_id = ABS_LEFTDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kScrollbarRightArrow: + switch (state) { + case kNormal: + state_id = ABS_RIGHTNORMAL; + break; + case kHovered: + // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. + state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? + ABS_RIGHTHOT : ABS_RIGHTHOVER; + break; + case kPressed: + state_id = ABS_RIGHTPRESSED; + break; + case kDisabled: + state_id = ABS_RIGHTDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kScrollbarUpArrow: + switch (state) { + case kNormal: + state_id = ABS_UPNORMAL; + break; + case kHovered: + // Mimic ScrollbarThemeChromiumWin.cpp in WebKit. + state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? + ABS_UPHOT : ABS_UPHOVER; + break; + case kPressed: + state_id = ABS_UPPRESSED; + break; + case kDisabled: + state_id = ABS_UPDISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + case kScrollbarHorizontalThumb: + case kScrollbarVerticalThumb: + switch (state) { + case kNormal: + state_id = SCRBS_NORMAL; + break; + case kHovered: + // Mimic WebKit's behaviour in ScrollbarThemeChromiumWin.cpp. + state_id = base::win::GetVersion() < base::win::VERSION_VISTA ? + SCRBS_HOT : SCRBS_HOVER; + break; + case kPressed: + state_id = SCRBS_PRESSED; + break; + case kDisabled: + state_id = SCRBS_DISABLED; + break; + default: + NOTREACHED() << "Invalid state: " << state; + break; + } + break; + default: + NOTREACHED() << "Invalid part: " << part; + break; + } + return state_id; +} + +HRESULT NativeThemeWin::GetThemeInt(ThemeName theme, + int part_id, + int state_id, + int prop_id, + int *value) const { + HANDLE handle = GetThemeHandle(theme); + if (handle && get_theme_int_) + return get_theme_int_(handle, part_id, state_id, prop_id, value); + return E_NOTIMPL; +} + +HRESULT NativeThemeWin::PaintFrameControl(HDC hdc, + const gfx::Rect& rect, + UINT type, + UINT state, + bool is_selected, + State control_state) const { + const int width = rect.width(); + const int height = rect.height(); + + // DrawFrameControl for menu arrow/check wants a monochrome bitmap. + base::win::ScopedBitmap mask_bitmap(CreateBitmap(width, height, 1, 1, NULL)); + + if (mask_bitmap == NULL) + return E_OUTOFMEMORY; + + base::win::ScopedCreateDC bitmap_dc(CreateCompatibleDC(NULL)); + base::win::ScopedSelectObject select_bitmap(bitmap_dc, mask_bitmap); + RECT local_rect = { 0, 0, width, height }; + DrawFrameControl(bitmap_dc, &local_rect, type, state); + + // We're going to use BitBlt with a b&w mask. This results in using the dest + // dc's text color for the black bits in the mask, and the dest dc's + // background color for the white bits in the mask. DrawFrameControl draws the + // check in black, and the background in white. + int bg_color_key; + int text_color_key; + switch (control_state) { + case NativeTheme::kHovered: + bg_color_key = COLOR_HIGHLIGHT; + text_color_key = COLOR_HIGHLIGHTTEXT; + break; + case NativeTheme::kNormal: + bg_color_key = COLOR_MENU; + text_color_key = COLOR_MENUTEXT; + break; + case NativeTheme::kDisabled: + bg_color_key = is_selected ? COLOR_HIGHLIGHT : COLOR_MENU; + text_color_key = COLOR_GRAYTEXT; + break; + default: + NOTREACHED(); + bg_color_key = COLOR_MENU; + text_color_key = COLOR_MENUTEXT; + break; + } + COLORREF old_bg_color = SetBkColor(hdc, GetSysColor(bg_color_key)); + COLORREF old_text_color = SetTextColor(hdc, GetSysColor(text_color_key)); + BitBlt(hdc, rect.x(), rect.y(), width, height, bitmap_dc, 0, 0, SRCCOPY); + SetBkColor(hdc, old_bg_color); + SetTextColor(hdc, old_text_color); + + return S_OK; +} + +HANDLE NativeThemeWin::GetThemeHandle(ThemeName theme_name) const { + if (!open_theme_ || theme_name < 0 || theme_name >= LAST) + return 0; + + if (theme_handles_[theme_name]) + return theme_handles_[theme_name]; + + // Not found, try to load it. + HANDLE handle = 0; + switch (theme_name) { + case BUTTON: + handle = open_theme_(NULL, L"Button"); + break; + case LIST: + handle = open_theme_(NULL, L"Listview"); + break; + case MENU: + handle = open_theme_(NULL, L"Menu"); + break; + case MENULIST: + handle = open_theme_(NULL, L"Combobox"); + break; + case SCROLLBAR: + handle = open_theme_(NULL, L"Scrollbar"); + break; + case STATUS: + handle = open_theme_(NULL, L"Status"); + break; + case TAB: + handle = open_theme_(NULL, L"Tab"); + break; + case TEXTFIELD: + handle = open_theme_(NULL, L"Edit"); + break; + case TRACKBAR: + handle = open_theme_(NULL, L"Trackbar"); + break; + case WINDOW: + handle = open_theme_(NULL, L"Window"); + break; + case PROGRESS: + handle = open_theme_(NULL, L"Progress"); + break; + case SPIN: + handle = open_theme_(NULL, L"Spin"); + break; + default: + NOTREACHED(); + } + theme_handles_[theme_name] = handle; + return handle; +} + +} // namespace ui diff --git a/ui/native_theme/native_theme_win.h b/ui/native_theme/native_theme_win.h new file mode 100644 index 0000000..1e83d15 --- /dev/null +++ b/ui/native_theme/native_theme_win.h @@ -0,0 +1,340 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ +#define UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ + +// A wrapper class for working with custom XP/Vista themes provided in +// uxtheme.dll. This is a singleton class that can be grabbed using +// NativeThemeWin::instance(). +// For more information on visual style parts and states, see: +// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp + +#include <windows.h> +#include <uxtheme.h> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/size.h" +#include "ui/native_theme/native_theme.h" + +class SkCanvas; + +namespace ui { + +// Windows implementation of native theme class. +// +// At the moment, this class in in transition from an older API that consists +// of several PaintXXX methods to an API, inherited from the NativeTheme base +// class, that consists of a single Paint() method with a argument to indicate +// what kind of part to paint. +class NATIVE_THEME_EXPORT NativeThemeWin : public NativeTheme { + public: + enum ThemeName { + BUTTON, + LIST, + MENU, + MENULIST, + SCROLLBAR, + STATUS, + TAB, + TEXTFIELD, + TRACKBAR, + WINDOW, + PROGRESS, + SPIN, + LAST + }; + + bool IsThemingActive() const; + + HRESULT GetThemeColor(ThemeName theme, + int part_id, + int state_id, + int prop_id, + SkColor* color) const; + + // Get the theme color if theming is enabled. If theming is unsupported + // for this part, use Win32's GetSysColor to find the color specified + // by default_sys_color. + SkColor GetThemeColorWithDefault(ThemeName theme, + int part_id, + int state_id, + int prop_id, + int default_sys_color) const; + + // Get the thickness of the border associated with the specified theme, + // defaulting to GetSystemMetrics edge size if themes are disabled. + // In Classic Windows, borders are typically 2px; on XP+, they are 1px. + gfx::Size GetThemeBorderSize(ThemeName theme) const; + + // Disables all theming for top-level windows in the entire process, from + // when this method is called until the process exits. All the other + // methods in this class will continue to work, but their output will ignore + // the user's theme. This is meant for use when running tests that require + // consistent visual results. + void DisableTheming() const; + + // Closes cached theme handles so we can unload the DLL or update our UI + // for a theme change. + void CloseHandles() const; + + // Returns true if classic theme is in use. + bool IsClassicTheme(ThemeName name) const; + + // Gets our singleton instance. + static NativeThemeWin* instance(); + + HRESULT PaintTextField(HDC hdc, + int part_id, + int state_id, + int classic_state, + RECT* rect, + COLORREF color, + bool fill_content_area, + bool draw_edges) const; + + // NativeTheme Implementation: + virtual gfx::Size GetPartSize(Part part, + State state, + const ExtraParams& extra) const OVERRIDE; + virtual void Paint(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const OVERRIDE; + virtual SkColor GetSystemColor(ColorId color_id) const OVERRIDE; + + private: + NativeThemeWin(); + ~NativeThemeWin(); + + // Paint directly to canvas' HDC. + void PaintDirect(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const; + + // Create a temporary HDC, paint to that, clean up the alpha values in the + // temporary HDC, and then blit the result to canvas. This is to work around + // the fact that Windows XP and some classic themes give bogus alpha values. + void PaintIndirect(SkCanvas* canvas, + Part part, + State state, + const gfx::Rect& rect, + const ExtraParams& extra) const; + + HRESULT GetThemePartSize(ThemeName themeName, + HDC hdc, + int part_id, + int state_id, + RECT* rect, + int ts, + SIZE* size) const; + + HRESULT PaintButton(HDC hdc, + State state, + const ButtonExtraParams& extra, + int part_id, + int state_id, + RECT* rect) const; + + HRESULT PaintMenuSeparator(HDC hdc, + const gfx::Rect& rect, + const MenuSeparatorExtraParams& extra) const; + + HRESULT PaintMenuGutter(HDC hdc, const gfx::Rect& rect) const; + + // |arrow_direction| determines whether the arrow is pointing to the left or + // to the right. In RTL locales, sub-menus open from right to left and + // therefore the menu arrow should point to the left and not to the right. + HRESULT PaintMenuArrow(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuArrowExtraParams& extra) const; + + HRESULT PaintMenuBackground(HDC hdc, const gfx::Rect& rect) const; + + HRESULT PaintMenuCheck(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuCheckExtraParams& extra) const; + + HRESULT PaintMenuCheckBackground(HDC hdc, + State state, + const gfx::Rect& rect) const; + + HRESULT PaintMenuItemBackground(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuItemExtraParams& extra) const; + + HRESULT PaintPushButton(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const; + + HRESULT PaintRadioButton(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const; + + HRESULT PaintCheckbox(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ButtonExtraParams& extra) const; + + HRESULT PaintMenuList(HDC hdc, + State state, + const gfx::Rect& rect, + const MenuListExtraParams& extra) const; + + // Paints a scrollbar arrow. |classic_state| should have the appropriate + // classic part number ORed in already. + HRESULT PaintScrollbarArrow(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarArrowExtraParams& extra) const; + + HRESULT PaintScrollbarThumb(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarThumbExtraParams& extra) const; + + // This method is deprecated and will be removed in the near future. + // Paints a scrollbar track section. |align_rect| is only used in classic + // mode, and makes sure the checkerboard pattern in |target_rect| is aligned + // with one presumed to be in |align_rect|. + HRESULT PaintScrollbarTrack(SkCanvas* canvas, + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const ScrollbarTrackExtraParams& extra) const; + + HRESULT PaintSpinButton(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const InnerSpinButtonExtraParams& extra) const; + + HRESULT PaintTrackbar(SkCanvas* canvas, + HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const TrackbarExtraParams& extra) const; + + HRESULT PaintProgressBar(HDC hdc, + const gfx::Rect& rect, + const ProgressBarExtraParams& extra) const; + + HRESULT PaintWindowResizeGripper(HDC hdc, const gfx::Rect& rect) const; + + HRESULT PaintTabPanelBackground(HDC hdc, const gfx::Rect& rect) const; + + HRESULT PaintTextField(HDC hdc, + Part part, + State state, + const gfx::Rect& rect, + const TextFieldExtraParams& extra) const; + + + // Get the windows theme name/part/state. These three helper functions are + // used only by GetPartSize(), as each of the corresponding PaintXXX() + // methods do further validation of the part and state that is required for + // getting the size. + static ThemeName GetThemeName(Part part); + static int GetWindowsPart(Part part, State state, const ExtraParams& extra); + static int GetWindowsState(Part part, State state, const ExtraParams& extra); + + HRESULT GetThemeInt(ThemeName theme, + int part_id, + int state_id, + int prop_id, + int *result) const; + + HRESULT PaintFrameControl(HDC hdc, + const gfx::Rect& rect, + UINT type, + UINT state, + bool is_selected, + State control_state) const; + + // Returns a handle to the theme data. + HANDLE GetThemeHandle(ThemeName theme_name) const; + + typedef HRESULT (WINAPI* DrawThemeBackgroundPtr)(HANDLE theme, + HDC hdc, + int part_id, + int state_id, + const RECT* rect, + const RECT* clip_rect); + typedef HRESULT (WINAPI* DrawThemeBackgroundExPtr)(HANDLE theme, + HDC hdc, + int part_id, + int state_id, + const RECT* rect, + const DTBGOPTS* opts); + typedef HRESULT (WINAPI* GetThemeColorPtr)(HANDLE hTheme, + int part_id, + int state_id, + int prop_id, + COLORREF* color); + typedef HRESULT (WINAPI* GetThemeContentRectPtr)(HANDLE hTheme, + HDC hdc, + int part_id, + int state_id, + const RECT* rect, + RECT* content_rect); + typedef HRESULT (WINAPI* GetThemePartSizePtr)(HANDLE hTheme, + HDC hdc, + int part_id, + int state_id, + RECT* rect, + int ts, + SIZE* size); + typedef HANDLE (WINAPI* OpenThemeDataPtr)(HWND window, + LPCWSTR class_list); + typedef HRESULT (WINAPI* CloseThemeDataPtr)(HANDLE theme); + + typedef void (WINAPI* SetThemeAppPropertiesPtr) (DWORD flags); + typedef BOOL (WINAPI* IsThemeActivePtr)(); + typedef HRESULT (WINAPI* GetThemeIntPtr)(HANDLE hTheme, + int part_id, + int state_id, + int prop_id, + int *value); + + // Function pointers into uxtheme.dll. + DrawThemeBackgroundPtr draw_theme_; + DrawThemeBackgroundExPtr draw_theme_ex_; + GetThemeColorPtr get_theme_color_; + GetThemeContentRectPtr get_theme_content_rect_; + GetThemePartSizePtr get_theme_part_size_; + OpenThemeDataPtr open_theme_; + CloseThemeDataPtr close_theme_; + SetThemeAppPropertiesPtr set_theme_properties_; + IsThemeActivePtr is_theme_active_; + GetThemeIntPtr get_theme_int_; + + // Handle to uxtheme.dll. + HMODULE theme_dll_; + + // A cache of open theme handles. + mutable HANDLE theme_handles_[LAST]; + + DISALLOW_COPY_AND_ASSIGN(NativeThemeWin); +}; + +} // namespace ui + +#endif // UI_NATIVE_THEME_NATIVE_THEME_WIN_H_ diff --git a/ui/native_theme/native_theme_win_unittest.cc b/ui/native_theme/native_theme_win_unittest.cc new file mode 100644 index 0000000..a2bd6aa --- /dev/null +++ b/ui/native_theme/native_theme_win_unittest.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/native_theme/native_theme_win.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace ui { + +TEST(NativeThemeTest, Init) { + ASSERT_TRUE(NativeThemeWin::instance() != NULL); +} + +} // namespace ui @@ -253,18 +253,6 @@ 'base/models/tree_model.h', 'base/models/tree_node_iterator.h', 'base/models/tree_node_model.h', - 'base/native_theme/native_theme.cc', - 'base/native_theme/native_theme.h', - 'base/native_theme/native_theme_android.cc', - 'base/native_theme/native_theme_android.h', - 'base/native_theme/native_theme_aura.cc', - 'base/native_theme/native_theme_aura.h', - 'base/native_theme/native_theme_base.cc', - 'base/native_theme/native_theme_base.h', - 'base/native_theme/native_theme_gtk.cc', - 'base/native_theme/native_theme_gtk.h', - 'base/native_theme/native_theme_win.cc', - 'base/native_theme/native_theme_win.h', 'base/range/range.cc', 'base/range/range.h', 'base/range/range_mac.mm', @@ -619,8 +607,6 @@ 'base/cursor/cursor_loader_x11.h', 'base/cursor/cursor_win.cc', 'base/cursor/cursor_x11.cc', - 'base/native_theme/native_theme_aura.cc', - 'base/native_theme/native_theme_aura.h', ] }], ['use_aura==1 and OS=="win"', { @@ -699,11 +685,6 @@ 'gfx/image/cairo_cached_surface.cc', 'gfx/image/cairo_cached_surface.h', ], - }, { # toolkit_uses_gtk != 1 - 'sources!': [ - 'base/native_theme/native_theme_gtk.cc', - 'base/native_theme/native_theme_gtk.h', - ] }], ['chromeos==1', { 'sources!': [ @@ -716,8 +697,6 @@ 'gfx/gdi_util.h', 'gfx/icon_util.cc', 'gfx/icon_util.h', - 'base/native_theme/native_theme_win.cc', - 'base/native_theme/native_theme_win.h', 'base/touch/touch_device_win.cc', 'base/touch/touch_device_win.h', ], @@ -771,8 +750,6 @@ 'base/dragdrop/drop_target.cc', 'base/dragdrop/drop_target.h', 'base/dragdrop/os_exchange_data.cc', - 'base/native_theme/native_theme_win.cc', - 'base/native_theme/native_theme_win.h', ], 'sources/': [ ['exclude', '^base/win/*'], diff --git a/ui/ui_unittests.gypi b/ui/ui_unittests.gypi index abcf32d..715ce17 100644 --- a/ui/ui_unittests.gypi +++ b/ui/ui_unittests.gypi @@ -156,7 +156,6 @@ ['OS == "win"', { 'sources': [ 'base/dragdrop/os_exchange_data_win_unittest.cc', - 'base/native_theme/native_theme_win_unittest.cc', 'base/win/hwnd_subclass_unittest.cc', 'gfx/font_fallback_win_unittest.cc', 'gfx/icon_util_unittest.cc', @@ -261,7 +260,6 @@ 'sources!': [ 'base/dialogs/select_file_dialog_win_unittest.cc', 'base/dragdrop/os_exchange_data_win_unittest.cc', - 'base/native_theme/native_theme_win_unittest.cc', 'gfx/screen_unittest.cc', ], }], diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 83cebe8..047b85a 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc @@ -7,14 +7,14 @@ #include "base/logging.h" #include "grit/ui_resources.h" #include "ui/base/animation/throb_animation.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/label_button_border.h" #include "ui/views/focus_border.h" #if defined(OS_WIN) #include "ui/gfx/color_utils.h" -#include "ui/base/native_theme/native_theme_win.h" +#include "ui/native_theme/native_theme_win.h" #endif namespace { diff --git a/ui/views/controls/button/label_button_border.cc b/ui/views/controls/button/label_button_border.cc index 4839716..5fe6276 100644 --- a/ui/views/controls/button/label_button_border.cc +++ b/ui/views/controls/button/label_button_border.cc @@ -6,9 +6,9 @@ #include "base/logging.h" #include "ui/base/animation/animation.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" #include "ui/gfx/rect.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/label_button.h" #include "ui/views/native_theme_delegate.h" diff --git a/ui/views/controls/button/text_button.cc b/ui/views/controls/button/text_button.cc index 77de4a5..64c0cfa 100644 --- a/ui/views/controls/button/text_button.cc +++ b/ui/views/controls/button/text_button.cc @@ -18,8 +18,8 @@ #if defined(OS_WIN) #include "skia/ext/skia_utils_win.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/gfx/platform_font_win.h" +#include "ui/native_theme/native_theme_win.h" #endif namespace views { diff --git a/ui/views/controls/combobox/native_combobox_win.cc b/ui/views/controls/combobox/native_combobox_win.cc index 3bca066..35cb649 100644 --- a/ui/views/controls/combobox/native_combobox_win.cc +++ b/ui/views/controls/combobox/native_combobox_win.cc @@ -8,10 +8,10 @@ #include "base/utf_string_conversions.h" #include "ui/base/events/event.h" #include "ui/base/models/combobox_model.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/win/hwnd_util.h" #include "ui/gfx/font.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/controls/combobox/combobox.h" #include "ui/views/controls/combobox/native_combobox_views.h" #include "ui/views/widget/widget.h" diff --git a/ui/views/controls/focusable_border.cc b/ui/views/controls/focusable_border.cc index 0ca52d7..f0c5e3a 100644 --- a/ui/views/controls/focusable_border.cc +++ b/ui/views/controls/focusable_border.cc @@ -4,10 +4,10 @@ #include "ui/views/controls/focusable_border.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" #include "ui/gfx/insets.h" #include "ui/gfx/skia_util.h" +#include "ui/native_theme/native_theme.h" namespace { diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 356ad30..4a21911 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc @@ -15,7 +15,6 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "ui/base/accessibility/accessible_view_state.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/text/text_elider.h" #include "ui/gfx/canvas.h" @@ -23,6 +22,7 @@ #include "ui/gfx/font.h" #include "ui/gfx/insets.h" #include "ui/gfx/shadow_value.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/background.h" namespace { diff --git a/ui/views/controls/menu/menu_config.cc b/ui/views/controls/menu/menu_config.cc index fbbd465..5c951c8 100644 --- a/ui/views/controls/menu/menu_config.cc +++ b/ui/views/controls/menu/menu_config.cc @@ -6,7 +6,7 @@ #include "build/build_config.h" #include "ui/base/layout.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" namespace views { diff --git a/ui/views/controls/menu/menu_config_views.cc b/ui/views/controls/menu/menu_config_views.cc index 4e53ed1..15e849a 100644 --- a/ui/views/controls/menu/menu_config_views.cc +++ b/ui/views/controls/menu/menu_config_views.cc @@ -6,10 +6,10 @@ #include "grit/ui_resources.h" #include "ui/base/layout.h" -#include "ui/base/native_theme/native_theme_aura.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" +#include "ui/native_theme/native_theme_aura.h" namespace views { diff --git a/ui/views/controls/menu/menu_config_win.cc b/ui/views/controls/menu/menu_config_win.cc index e0eb432..d7ae562 100644 --- a/ui/views/controls/menu/menu_config_win.cc +++ b/ui/views/controls/menu/menu_config_win.cc @@ -12,11 +12,11 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/win_util.h" #include "ui/base/l10n/l10n_util_win.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/gfx/color_utils.h" +#include "ui/native_theme/native_theme_win.h" #if defined(USE_AURA) -#include "ui/base/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_aura.h" #endif using ui::NativeTheme; diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index e417b3e..9151c34 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc @@ -15,9 +15,9 @@ #include "ui/base/events/event_utils.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" #include "ui/gfx/screen.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_controller_delegate.h" diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index af1fd1e..e941d4e 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc @@ -11,9 +11,9 @@ #include "ui/base/accessibility/accessible_view_state.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/models/menu_model.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/menu_button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/menu/menu_config.h" diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h index 17cf889..ee11d97 100644 --- a/ui/views/controls/menu/menu_item_view.h +++ b/ui/views/controls/menu/menu_item_view.h @@ -20,7 +20,7 @@ #if defined(OS_WIN) #include <windows.h> -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #endif namespace gfx { diff --git a/ui/views/controls/menu/menu_item_view_views.cc b/ui/views/controls/menu/menu_item_view_views.cc index f26f646f..0628241 100644 --- a/ui/views/controls/menu/menu_item_view_views.cc +++ b/ui/views/controls/menu/menu_item_view_views.cc @@ -7,11 +7,11 @@ #include "base/utf_string_conversions.h" #include "grit/ui_resources.h" #include "third_party/skia/include/effects/SkGradientShader.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/favicon_size.h" #include "ui/gfx/image/image.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_image_util.h" #include "ui/views/controls/menu/submenu_view.h" diff --git a/ui/views/controls/menu/menu_item_view_win.cc b/ui/views/controls/menu/menu_item_view_win.cc index 87a75ba..5d543ba 100644 --- a/ui/views/controls/menu/menu_item_view_win.cc +++ b/ui/views/controls/menu/menu_item_view_win.cc @@ -8,13 +8,13 @@ #include <Vssym32.h> #include "grit/ui_strings.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/gfx/canvas.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/submenu_view.h" #if defined(USE_AURA) -#include "ui/base/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_aura.h" #endif using ui::NativeTheme; diff --git a/ui/views/controls/menu/menu_scroll_view_container.cc b/ui/views/controls/menu/menu_scroll_view_container.cc index ccdf93a7..8a85d60 100644 --- a/ui/views/controls/menu/menu_scroll_view_container.cc +++ b/ui/views/controls/menu/menu_scroll_view_container.cc @@ -13,8 +13,8 @@ #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkPath.h" #include "ui/base/accessibility/accessible_view_state.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/border.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_controller.h" diff --git a/ui/views/controls/menu/menu_separator_views.cc b/ui/views/controls/menu/menu_separator_views.cc index 43a7632..affbae4 100644 --- a/ui/views/controls/menu/menu_separator_views.cc +++ b/ui/views/controls/menu/menu_separator_views.cc @@ -5,8 +5,8 @@ #include "ui/views/controls/menu/menu_separator.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_item_view.h" diff --git a/ui/views/controls/menu/menu_separator_win.cc b/ui/views/controls/menu/menu_separator_win.cc index 7a3d8f9..89db94a 100644 --- a/ui/views/controls/menu/menu_separator_win.cc +++ b/ui/views/controls/menu/menu_separator_win.cc @@ -8,14 +8,14 @@ #include <uxtheme.h> #include <Vssym32.h> -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/canvas.h" #include "ui/gfx/rect.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_item_view.h" #if defined(USE_AURA) -#include "ui/base/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_aura.h" #endif namespace views { diff --git a/ui/views/controls/menu/native_menu_win.cc b/ui/views/controls/menu/native_menu_win.cc index 7dda1f7..bed8f13 100644 --- a/ui/views/controls/menu/native_menu_win.cc +++ b/ui/views/controls/menu/native_menu_win.cc @@ -17,14 +17,14 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_win.h" #include "ui/base/models/menu_model.h" -#include "ui/base/native_theme/native_theme.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/win/hwnd_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" #include "ui/gfx/image/image.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/rect.h" +#include "ui/native_theme/native_theme.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/controls/menu/menu_2.h" #include "ui/views/controls/menu/menu_config.h" #include "ui/views/controls/menu/menu_listener.h" diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index 1d649f7..b85553f 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc @@ -6,7 +6,7 @@ #include "base/logging.h" #include "ui/base/events/event.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/border.h" #include "ui/views/controls/scrollbar/native_scroll_bar.h" #include "ui/views/widget/root_view.h" diff --git a/ui/views/controls/scrollbar/native_scroll_bar_views.h b/ui/views/controls/scrollbar/native_scroll_bar_views.h index 99cf399..e928db0 100644 --- a/ui/views/controls/scrollbar/native_scroll_bar_views.h +++ b/ui/views/controls/scrollbar/native_scroll_bar_views.h @@ -6,8 +6,8 @@ #define UI_VIEWS_CONTROLS_SCROLLBAR_NATIVE_SCROLL_BAR_VIEWS_H_ #include "base/compiler_specific.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/point.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/scrollbar/base_scroll_bar.h" #include "ui/views/controls/scrollbar/native_scroll_bar_wrapper.h" diff --git a/ui/views/controls/tabbed_pane/native_tabbed_pane_win.cc b/ui/views/controls/tabbed_pane/native_tabbed_pane_win.cc index 5d35466..51d41a3 100644 --- a/ui/views/controls/tabbed_pane/native_tabbed_pane_win.cc +++ b/ui/views/controls/tabbed_pane/native_tabbed_pane_win.cc @@ -9,11 +9,11 @@ #include "base/logging.h" #include "base/stl_util.h" #include "ui/base/l10n/l10n_util_win.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/win/hwnd_util.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/controls/tabbed_pane/tabbed_pane.h" #include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h" #include "ui/views/layout/fill_layout.h" diff --git a/ui/views/controls/textfield/native_textfield_views.cc b/ui/views/controls/textfield/native_textfield_views.cc index e909db30..0006720 100644 --- a/ui/views/controls/textfield/native_textfield_views.cc +++ b/ui/views/controls/textfield/native_textfield_views.cc @@ -20,13 +20,13 @@ #include "ui/base/dragdrop/drag_drop_types.h" #include "ui/base/events/event.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/range/range.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/insets.h" #include "ui/gfx/render_text.h" #include "ui/gfx/text_constants.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/focusable_border.h" diff --git a/ui/views/controls/textfield/native_textfield_win.cc b/ui/views/controls/textfield/native_textfield_win.cc index 6c15f45..85233c8 100644 --- a/ui/views/controls/textfield/native_textfield_win.cc +++ b/ui/views/controls/textfield/native_textfield_win.cc @@ -18,13 +18,13 @@ #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" #include "ui/base/events/event.h" -#include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/ime/win/tsf_bridge.h" +#include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_win.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/range/range.h" #include "ui/base/win/mouse_wheel_util.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_item_view.h" #include "ui/views/controls/menu/menu_model_adapter.h" diff --git a/ui/views/controls/textfield/textfield_views_model.cc b/ui/views/controls/textfield/textfield_views_model.cc index d975eff..c779927 100644 --- a/ui/views/controls/textfield/textfield_views_model.cc +++ b/ui/views/controls/textfield/textfield_views_model.cc @@ -12,13 +12,13 @@ #include "base/utf_string_conversions.h" #include "ui/base/clipboard/clipboard.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/range/range.h" #include "ui/base/text/utf16_indexing.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" #include "ui/gfx/render_text.h" #include "ui/gfx/text_constants.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/textfield/textfield.h" namespace views { diff --git a/ui/views/examples/native_theme_button_example.h b/ui/views/examples/native_theme_button_example.h index d8eaf81..fdfca48 100644 --- a/ui/views/examples/native_theme_button_example.h +++ b/ui/views/examples/native_theme_button_example.h @@ -9,7 +9,7 @@ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/custom_button.h" #include "ui/views/controls/combobox/combobox_listener.h" #include "ui/views/examples/example_base.h" diff --git a/ui/views/examples/native_theme_checkbox_example.h b/ui/views/examples/native_theme_checkbox_example.h index 517afb1..5d464584d 100644 --- a/ui/views/examples/native_theme_checkbox_example.h +++ b/ui/views/examples/native_theme_checkbox_example.h @@ -6,7 +6,7 @@ #define UI_VIEWS_EXAMPLES_NATIVE_THEME_CHECKBOX_EXAMPLE_H_ #include "base/basictypes.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/button.h" #include "ui/views/examples/example_base.h" diff --git a/ui/views/native_theme_delegate.h b/ui/views/native_theme_delegate.h index 1cdd7ce..d4bc880 100644 --- a/ui/views/native_theme_delegate.h +++ b/ui/views/native_theme_delegate.h @@ -5,8 +5,8 @@ #ifndef UI_VIEWS_NATIVE_THEME_DELEGATE_H_ #define UI_VIEWS_NATIVE_THEME_DELEGATE_H_ -#include "ui/base/native_theme/native_theme.h" #include "ui/gfx/rect.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/views_export.h" namespace views { diff --git a/ui/views/view.cc b/ui/views/view.cc index 9d04967..e49a3c0 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc @@ -15,18 +15,18 @@ #include "third_party/skia/include/core/SkRect.h" #include "ui/base/accessibility/accessibility_types.h" #include "ui/base/dragdrop/drag_drop_types.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/compositor/compositor.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animator.h" #include "ui/gfx/canvas.h" #include "ui/gfx/interpolated_transform.h" #include "ui/gfx/path.h" -#include "ui/gfx/point_conversions.h" #include "ui/gfx/point3_f.h" +#include "ui/gfx/point_conversions.h" #include "ui/gfx/rect_conversions.h" #include "ui/gfx/skia_util.h" #include "ui/gfx/transform.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/background.h" #include "ui/views/context_menu_controller.h" #include "ui/views/drag_controller.h" diff --git a/ui/views/views.gyp b/ui/views/views.gyp index 1bd8e46..cae784b 100644 --- a/ui/views/views.gyp +++ b/ui/views/views.gyp @@ -30,6 +30,7 @@ '../../third_party/icu/icu.gyp:icuuc', '../base/strings/ui_strings.gyp:ui_strings', '../compositor/compositor.gyp:compositor', + '../native_theme/native_theme.gyp:native_theme', '../ui.gyp:ui', '../ui.gyp:ui_resources', ], diff --git a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc index 16dc947..47a9504 100644 --- a/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc +++ b/ui/views/widget/desktop_aura/desktop_native_widget_aura.cc @@ -12,9 +12,9 @@ #include "ui/aura/window.h" #include "ui/aura/window_property.h" #include "ui/base/hit_test.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/ime/input_method.h" #include "ui/views/widget/desktop_aura/desktop_root_window_host.h" #include "ui/views/widget/native_widget_aura_window_observer.h" diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc index 67e42e9..ac411ea 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_linux.cc @@ -16,13 +16,13 @@ #include "ui/aura/client/user_action_client.h" #include "ui/aura/focus_manager.h" #include "ui/aura/root_window.h" -#include "ui/views/corewm/compound_event_filter.h" -#include "ui/views/corewm/input_method_event_filter.h" #include "ui/aura/window_property.h" #include "ui/base/events/event_utils.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/touch/touch_factory.h" #include "ui/base/x/x11_util.h" +#include "ui/native_theme/native_theme.h" +#include "ui/views/corewm/compound_event_filter.h" +#include "ui/views/corewm/input_method_event_filter.h" #include "ui/views/ime/input_method_bridge.h" #include "ui/views/widget/desktop_aura/desktop_activation_client.h" #include "ui/views/widget/desktop_aura/desktop_cursor_client.h" diff --git a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc index 9c4c6c1..854d479 100644 --- a/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc +++ b/ui/views/widget/desktop_aura/desktop_root_window_host_win.cc @@ -10,15 +10,15 @@ #include "ui/aura/client/default_capture_client.h" #include "ui/aura/focus_manager.h" #include "ui/aura/root_window.h" -#include "ui/views/corewm/compound_event_filter.h" -#include "ui/views/corewm/input_method_event_filter.h" #include "ui/aura/window_property.h" #include "ui/base/cursor/cursor_loader_win.h" -#include "ui/base/native_theme/native_theme_aura.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/win/shell.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/path_win.h" +#include "ui/native_theme/native_theme_aura.h" +#include "ui/native_theme/native_theme_win.h" +#include "ui/views/corewm/compound_event_filter.h" +#include "ui/views/corewm/input_method_event_filter.h" #include "ui/views/ime/input_method_win.h" #include "ui/views/widget/desktop_aura/desktop_activation_client.h" #include "ui/views/widget/desktop_aura/desktop_cursor_client.h" diff --git a/ui/views/widget/native_widget_aura.cc b/ui/views/widget/native_widget_aura.cc index 58bd7a8..0c5ce19 100644 --- a/ui/views/widget/native_widget_aura.cc +++ b/ui/views/widget/native_widget_aura.cc @@ -23,12 +23,12 @@ #include "ui/aura/window_observer.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/events/event.h" -#include "ui/base/native_theme/native_theme_aura.h" #include "ui/base/ui_base_types.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" #include "ui/gfx/screen.h" +#include "ui/native_theme/native_theme_aura.h" #include "ui/views/drag_utils.h" #include "ui/views/ime/input_method_bridge.h" #include "ui/views/views_delegate.h" diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc index 39ba1137..d3174df 100644 --- a/ui/views/widget/native_widget_win.cc +++ b/ui/views/widget/native_widget_win.cc @@ -21,7 +21,6 @@ #include "ui/base/events/event.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" #include "ui/base/l10n/l10n_util_win.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/theme_provider.h" #include "ui/base/view_prop.h" #include "ui/base/win/hwnd_util.h" @@ -32,6 +31,7 @@ #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/path.h" #include "ui/gfx/screen.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/accessibility/native_view_accessibility_win.h" #include "ui/views/controls/native_control_win.h" #include "ui/views/controls/textfield/textfield.h" diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 0f2cb9c..9f6557a 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc @@ -13,7 +13,6 @@ #include "ui/base/events/event.h" #include "ui/base/events/event_utils.h" #include "ui/base/keycodes/keyboard_code_conversion_win.h" -#include "ui/base/native_theme/native_theme_win.h" #include "ui/base/win/hwnd_util.h" #include "ui/base/win/mouse_wheel_util.h" #include "ui/base/win/shell.h" @@ -24,6 +23,7 @@ #include "ui/gfx/path.h" #include "ui/gfx/path_win.h" #include "ui/gfx/screen.h" +#include "ui/native_theme/native_theme_win.h" #include "ui/views/views_delegate.h" #include "ui/views/widget/monitor_win.h" #include "ui/views/widget/native_widget_win.h" diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc index a4ffff7..7a2ce426 100644 --- a/ui/views/window/dialog_client_view.cc +++ b/ui/views/window/dialog_client_view.cc @@ -19,12 +19,12 @@ #include "ui/base/hit_test.h" #include "ui/base/keycodes/keyboard_codes.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/native_theme/native_theme.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/font.h" -#include "ui/views/controls/button/text_button.h" +#include "ui/native_theme/native_theme.h" #include "ui/views/controls/button/chrome_style.h" +#include "ui/views/controls/button/text_button.h" #include "ui/views/layout/layout_constants.h" #include "ui/views/widget/root_view.h" #include "ui/views/widget/widget.h" diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 7a17b05..297ee5b 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -90,6 +90,7 @@ '<(DEPTH)/third_party/icu/icu.gyp:icuuc', '<(DEPTH)/third_party/npapi/npapi.gyp:npapi', '<(DEPTH)/ui/gl/gl.gyp:gl', + '<(DEPTH)/ui/native_theme/native_theme.gyp:native_theme', '<(DEPTH)/ui/ui.gyp:ui', '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', '<(DEPTH)/webkit/compositor_bindings/compositor_bindings.gyp:webkit_compositor_support', diff --git a/webkit/glue/webthemeengine_impl_android.cc b/webkit/glue/webthemeengine_impl_android.cc index f9fb758..b7dae4b 100644 --- a/webkit/glue/webthemeengine_impl_android.cc +++ b/webkit/glue/webthemeengine_impl_android.cc @@ -8,7 +8,7 @@ #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" using WebKit::WebCanvas; using WebKit::WebColor; diff --git a/webkit/glue/webthemeengine_impl_linux.cc b/webkit/glue/webthemeengine_impl_linux.cc index 4166765..79e5430 100644 --- a/webkit/glue/webthemeengine_impl_linux.cc +++ b/webkit/glue/webthemeengine_impl_linux.cc @@ -7,7 +7,7 @@ #include "skia/ext/platform_canvas.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" using WebKit::WebCanvas; using WebKit::WebColor; diff --git a/webkit/glue/webthemeengine_impl_win.cc b/webkit/glue/webthemeengine_impl_win.cc index 7e60501..4290932 100644 --- a/webkit/glue/webthemeengine_impl_win.cc +++ b/webkit/glue/webthemeengine_impl_win.cc @@ -10,7 +10,7 @@ #include "skia/ext/platform_canvas.h" #include "skia/ext/skia_utils_win.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" -#include "ui/base/native_theme/native_theme.h" +#include "ui/native_theme/native_theme.h" using WebKit::WebCanvas; using WebKit::WebColor; diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi index feab7114..cec3656 100644 --- a/webkit/tools/test_shell/test_shell.gypi +++ b/webkit/tools/test_shell/test_shell.gypi @@ -47,6 +47,7 @@ '<(DEPTH)/testing/gtest.gyp:gtest', '<(DEPTH)/third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:inspector_resources', '<(DEPTH)/third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit', + '<(DEPTH)/ui/native_theme/native_theme.gyp:native_theme', '<(DEPTH)/v8/tools/gyp/v8.gyp:v8', '<(DEPTH)/webkit/support/webkit_support.gyp:glue', '<(DEPTH)/webkit/support/webkit_support.gyp:user_agent', diff --git a/webkit/tools/test_shell/test_shell_platform_delegate_win.cc b/webkit/tools/test_shell/test_shell_platform_delegate_win.cc index 8f9204d..c01bd32 100644 --- a/webkit/tools/test_shell/test_shell_platform_delegate_win.cc +++ b/webkit/tools/test_shell/test_shell_platform_delegate_win.cc @@ -11,7 +11,7 @@ #include "base/event_recorder.h" #include "base/win/win_util.h" #include "ui/base/win/foreground_helper.h" -#include "ui/base/native_theme/native_theme_win.h" +#include "ui/native_theme/native_theme_win.h" #include "webkit/tools/test_shell/test_shell.h" #include "webkit/tools/test_shell/test_shell_platform_delegate.h" |