| Index: ui/native_theme/native_theme_win.cc
|
| diff --git a/ui/native_theme/native_theme_win.cc b/ui/native_theme/native_theme_win.cc
|
| deleted file mode 100644
|
| index d79bdf09c6b1e0ecc6b65c80057e9043aaf255e1..0000000000000000000000000000000000000000
|
| --- a/ui/native_theme/native_theme_win.cc
|
| +++ /dev/null
|
| @@ -1,2068 +0,0 @@
|
| -// 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_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"
|
| -#include "ui/gfx/rect_conversions.h"
|
| -#include "ui/gfx/win/dpi.h"
|
| -#include "ui/native_theme/common_theme.h"
|
| -
|
| -// This was removed from Winvers.h but is still used.
|
| -#if !defined(COLOR_MENUHIGHLIGHT)
|
| -#define COLOR_MENUHIGHLIGHT 29
|
| -#endif
|
| -
|
| -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(251, 251, 251);
|
| -// FocusableBorder:
|
| -const SkColor kFocusedBorderColor = SkColorSetRGB(0x4d, 0x90, 0xfe);
|
| -const SkColor kUnfocusedBorderColor = SkColorSetRGB(0xd9, 0xd9, 0xd9);
|
| -// Button:
|
| -const SkColor kButtonBackgroundColor = SkColorSetRGB(0xde, 0xde, 0xde);
|
| -const SkColor kButtonHighlightColor = SkColorSetARGB(200, 255, 255, 255);
|
| -const SkColor kButtonHoverColor = SkColorSetRGB(6, 45, 117);
|
| -const SkColor kButtonHoverBackgroundColor = SkColorSetRGB(0xEA, 0xEA, 0xEA);
|
| -// MenuItem:
|
| -const SkColor kEnabledMenuItemForegroundColor = SkColorSetRGB(6, 45, 117);
|
| -const SkColor kDisabledMenuItemForegroundColor = SkColorSetRGB(161, 161, 146);
|
| -const SkColor kFocusedMenuItemBackgroundColor = SkColorSetRGB(246, 249, 253);
|
| -const SkColor kMenuSeparatorColor = SkColorSetARGB(50, 0, 0, 0);
|
| -// Table:
|
| -const SkColor kTreeSelectionBackgroundUnfocused = SkColorSetRGB(240, 240, 240);
|
| -
|
| -// Windows system color IDs cached and updated by the native theme.
|
| -const int kSystemColors[] = {
|
| - COLOR_3DFACE,
|
| - COLOR_BTNTEXT,
|
| - COLOR_GRAYTEXT,
|
| - COLOR_HIGHLIGHT,
|
| - COLOR_HIGHLIGHTTEXT,
|
| - COLOR_SCROLLBAR,
|
| - COLOR_WINDOW,
|
| - COLOR_WINDOWTEXT,
|
| - COLOR_BTNFACE,
|
| - COLOR_MENUHIGHLIGHT,
|
| -};
|
| -
|
| -void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) {
|
| - // Create a 2x2 checkerboard pattern using the 3D face and highlight colors.
|
| - const SkColor face = color_utils::GetSysSkColor(COLOR_3DFACE);
|
| - const SkColor highlight = color_utils::GetSysSkColor(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.
|
| - SkImageInfo info = SkImageInfo::MakeN32Premul(2, 2);
|
| - SkBitmap temp_bitmap;
|
| - temp_bitmap.installPixels(info, buffer, info.minRowBytes());
|
| - SkBitmap bitmap;
|
| - temp_bitmap.copyTo(&bitmap);
|
| -
|
| - // Align the pattern with the upper corner of |align_rect|.
|
| - SkMatrix local_matrix;
|
| - local_matrix.setTranslate(SkIntToScalar(align_rect.left),
|
| - SkIntToScalar(align_rect.top));
|
| - skia::RefPtr<SkShader> shader =
|
| - skia::AdoptRef(SkShader::CreateBitmapShader(bitmap,
|
| - SkShader::kRepeat_TileMode,
|
| - SkShader::kRepeat_TileMode,
|
| - &local_matrix));
|
| - paint->setShader(shader.get());
|
| -}
|
| -
|
| -// <-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 {
|
| - return is_theme_active_ && is_theme_active_();
|
| -}
|
| -
|
| -bool NativeThemeWin::IsUsingHighContrastTheme() const {
|
| - if (is_using_high_contrast_valid_)
|
| - return is_using_high_contrast_;
|
| - HIGHCONTRAST result;
|
| - result.cbSize = sizeof(HIGHCONTRAST);
|
| - is_using_high_contrast_ =
|
| - SystemParametersInfo(SPI_GETHIGHCONTRAST, result.cbSize, &result, 0) &&
|
| - (result.dwFlags & HCF_HIGHCONTRASTON) == HCF_HIGHCONTRASTON;
|
| - is_using_high_contrast_valid_ = true;
|
| - return is_using_high_contrast_;
|
| -}
|
| -
|
| -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_)
|
| - return E_NOTIMPL;
|
| - COLORREF color_ref;
|
| - if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) != S_OK)
|
| - return E_NOTIMPL;
|
| - *color = skia::COLORREFToSkColor(color_ref);
|
| - return S_OK;
|
| -}
|
| -
|
| -SkColor NativeThemeWin::GetThemeColorWithDefault(ThemeName theme,
|
| - int part_id,
|
| - int state_id,
|
| - int prop_id,
|
| - int default_sys_color) const {
|
| - SkColor color;
|
| - return (GetThemeColor(theme, part_id, state_id, prop_id, &color) == S_OK) ?
|
| - color : color_utils::GetSysSkColor(default_sys_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;
|
| - return (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK) ?
|
| - gfx::Size(border, border) :
|
| - gfx::Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
|
| -}
|
| -
|
| -void NativeThemeWin::DisableTheming() const {
|
| - if (set_theme_properties_)
|
| - 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 {
|
| - return !theme_dll_ || !GetThemeHandle(name);
|
| -}
|
| -
|
| -// 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 {
|
| - gfx::Size part_size = CommonThemeGetPartSize(part, state, extra);
|
| - if (!part_size.IsEmpty())
|
| - return part_size;
|
| -
|
| - // The GetThemePartSize call below returns the default size without
|
| - // accounting for user customization (crbug/218291).
|
| - switch (part) {
|
| - case kScrollbarDownArrow:
|
| - case kScrollbarLeftArrow:
|
| - case kScrollbarRightArrow:
|
| - case kScrollbarUpArrow:
|
| - case kScrollbarHorizontalThumb:
|
| - case kScrollbarVerticalThumb:
|
| - case kScrollbarHorizontalTrack:
|
| - case kScrollbarVerticalTrack: {
|
| - int size = gfx::win::GetSystemMetricsInDIP(SM_CXVSCROLL);
|
| - if (size == 0)
|
| - size = 17;
|
| - return gfx::Size(size, size);
|
| - }
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - int part_id = GetWindowsPart(part, state, extra);
|
| - int state_id = GetWindowsState(part, state, extra);
|
| -
|
| - base::win::ScopedGetDC screen_dc(NULL);
|
| - SIZE size;
|
| - if (SUCCEEDED(GetThemePartSize(GetThemeName(part), screen_dc, part_id,
|
| - state_id, NULL, TS_TRUE, &size)))
|
| - return gfx::Size(size.cx, size.cy);
|
| -
|
| - // 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.
|
| - return (part == kCheckbox || part == kRadio) ?
|
| - gfx::Size(13, 13) : gfx::Size();
|
| -}
|
| -
|
| -void NativeThemeWin::Paint(SkCanvas* canvas,
|
| - Part part,
|
| - State state,
|
| - const gfx::Rect& rect,
|
| - const ExtraParams& extra) const {
|
| - if (rect.IsEmpty())
|
| - return;
|
| -
|
| - switch (part) {
|
| - case kComboboxArrow:
|
| - CommonThemePaintComboboxArrow(canvas, rect);
|
| - return;
|
| - case kMenuPopupGutter:
|
| - CommonThemePaintMenuGutter(canvas, rect);
|
| - return;
|
| - case kMenuPopupSeparator:
|
| - CommonThemePaintMenuSeparator(canvas, rect, extra.menu_separator);
|
| - return;
|
| - case kMenuPopupBackground:
|
| - CommonThemePaintMenuBackground(canvas, rect);
|
| - return;
|
| - case kMenuItemBackground:
|
| - CommonThemePaintMenuItemBackground(canvas, state, rect);
|
| - return;
|
| - default:
|
| - break;
|
| - }
|
| -
|
| - 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 {
|
| - // Scrollbar components on Windows Classic theme (on all Windows versions)
|
| - // have particularly problematic alpha values, so always draw them
|
| - // indirectly. In addition, scrollbar thumbs and grippers for the Windows XP
|
| - // theme (available only on Windows XP) also need their alpha values
|
| - // fixed.
|
| - switch (part) {
|
| - case kScrollbarDownArrow:
|
| - case kScrollbarUpArrow:
|
| - case kScrollbarLeftArrow:
|
| - case kScrollbarRightArrow:
|
| - needs_paint_indirect = !GetThemeHandle(SCROLLBAR);
|
| - break;
|
| - case kScrollbarHorizontalThumb:
|
| - case kScrollbarVerticalThumb:
|
| - case kScrollbarHorizontalGripper:
|
| - case kScrollbarVerticalGripper:
|
| - needs_paint_indirect = !GetThemeHandle(SCROLLBAR) ||
|
| - base::win::GetVersion() == base::win::VERSION_XP;
|
| - 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),
|
| - color_change_listener_(this),
|
| - is_using_high_contrast_(false),
|
| - is_using_high_contrast_valid_(false) {
|
| - 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_));
|
| -
|
| - // Initialize the cached system colors.
|
| - UpdateSystemColors();
|
| -}
|
| -
|
| -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::OnSysColorChange() {
|
| - UpdateSystemColors();
|
| - is_using_high_contrast_valid_ = false;
|
| - NotifyObservers();
|
| -}
|
| -
|
| -void NativeThemeWin::UpdateSystemColors() {
|
| - for (int i = 0; i < arraysize(kSystemColors); ++i) {
|
| - system_colors_[kSystemColors[i]] =
|
| - color_utils::GetSysSkColor(kSystemColors[i]);
|
| - }
|
| -}
|
| -
|
| -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);
|
| - return;
|
| - case kInnerSpinButton:
|
| - PaintSpinButton(hdc, part, state, rect, extra.inner_spin);
|
| - return;
|
| - case kMenuList:
|
| - PaintMenuList(hdc, state, rect, extra.menu_list);
|
| - return;
|
| - case kMenuCheck:
|
| - PaintMenuCheck(hdc, state, rect, extra.menu_check);
|
| - return;
|
| - case kMenuCheckBackground:
|
| - PaintMenuCheckBackground(hdc, state, rect);
|
| - return;
|
| - case kMenuPopupArrow:
|
| - PaintMenuArrow(hdc, state, rect, extra.menu_arrow);
|
| - return;
|
| - case kMenuPopupBackground:
|
| - PaintMenuBackground(hdc, rect);
|
| - return;
|
| - case kMenuPopupGutter:
|
| - PaintMenuGutter(hdc, rect);
|
| - return;
|
| - case kMenuPopupSeparator:
|
| - PaintMenuSeparator(hdc, rect);
|
| - return;
|
| - case kMenuItemBackground:
|
| - PaintMenuItemBackground(hdc, state, rect, extra.menu_item);
|
| - return;
|
| - case kProgressBar:
|
| - PaintProgressBar(hdc, rect, extra.progress_bar);
|
| - return;
|
| - case kPushButton:
|
| - PaintPushButton(hdc, part, state, rect, extra.button);
|
| - return;
|
| - case kRadio:
|
| - PaintRadioButton(hdc, part, state, rect, extra.button);
|
| - return;
|
| - case kScrollbarDownArrow:
|
| - case kScrollbarUpArrow:
|
| - case kScrollbarLeftArrow:
|
| - case kScrollbarRightArrow:
|
| - PaintScrollbarArrow(hdc, part, state, rect, extra.scrollbar_arrow);
|
| - return;
|
| - case kScrollbarHorizontalThumb:
|
| - case kScrollbarVerticalThumb:
|
| - case kScrollbarHorizontalGripper:
|
| - case kScrollbarVerticalGripper:
|
| - PaintScrollbarThumb(hdc, part, state, rect, extra.scrollbar_thumb);
|
| - return;
|
| - case kScrollbarHorizontalTrack:
|
| - case kScrollbarVerticalTrack:
|
| - PaintScrollbarTrack(canvas, hdc, part, state, rect,
|
| - extra.scrollbar_track);
|
| - return;
|
| - case kScrollbarCorner:
|
| - canvas->drawColor(SK_ColorWHITE, SkXfermode::kSrc_Mode);
|
| - return;
|
| - case kTabPanelBackground:
|
| - PaintTabPanelBackground(hdc, rect);
|
| - return;
|
| - case kTextField:
|
| - PaintTextField(hdc, part, state, rect, extra.text_field);
|
| - return;
|
| - case kTrackbarThumb:
|
| - case kTrackbarTrack:
|
| - PaintTrackbar(canvas, hdc, part, state, rect, extra.trackbar);
|
| - return;
|
| - case kWindowResizeGripper:
|
| - PaintWindowResizeGripper(hdc, rect);
|
| - return;
|
| - case kComboboxArrow:
|
| - case kSliderTrack:
|
| - case kSliderThumb:
|
| - case kMaxPart:
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -SkColor NativeThemeWin::GetSystemColor(ColorId color_id) const {
|
| - SkColor color;
|
| - if (CommonThemeGetSystemColor(color_id, &color))
|
| - return color;
|
| -
|
| - switch (color_id) {
|
| - // Windows
|
| - case kColorId_WindowBackground:
|
| - return system_colors_[COLOR_WINDOW];
|
| -
|
| - // Dialogs
|
| - case kColorId_DialogBackground:
|
| - return gfx::IsInvertedColorScheme() ?
|
| - color_utils::InvertColor(kDialogBackgroundColor) :
|
| - kDialogBackgroundColor;
|
| -
|
| - // FocusableBorder
|
| - case kColorId_FocusedBorderColor:
|
| - return kFocusedBorderColor;
|
| - case kColorId_UnfocusedBorderColor:
|
| - return kUnfocusedBorderColor;
|
| -
|
| - // Button
|
| - case kColorId_ButtonBackgroundColor:
|
| - return kButtonBackgroundColor;
|
| - case kColorId_ButtonEnabledColor:
|
| - return system_colors_[COLOR_BTNTEXT];
|
| - case kColorId_ButtonDisabledColor:
|
| - return system_colors_[COLOR_GRAYTEXT];
|
| - case kColorId_ButtonHighlightColor:
|
| - return kButtonHighlightColor;
|
| - case kColorId_ButtonHoverColor:
|
| - return kButtonHoverColor;
|
| - case kColorId_ButtonHoverBackgroundColor:
|
| - return kButtonHoverBackgroundColor;
|
| - case kColorId_BlueButtonEnabledColor:
|
| - case kColorId_BlueButtonDisabledColor:
|
| - case kColorId_BlueButtonPressedColor:
|
| - case kColorId_BlueButtonHoverColor:
|
| - NOTREACHED();
|
| - return kInvalidColorIdColor;
|
| -
|
| - // MenuItem
|
| - case kColorId_EnabledMenuItemForegroundColor:
|
| - return kEnabledMenuItemForegroundColor;
|
| - case kColorId_DisabledMenuItemForegroundColor:
|
| - return kDisabledMenuItemForegroundColor;
|
| - case kColorId_DisabledEmphasizedMenuItemForegroundColor:
|
| - return SK_ColorBLACK;
|
| - case kColorId_FocusedMenuItemBackgroundColor:
|
| - return kFocusedMenuItemBackgroundColor;
|
| - case kColorId_MenuSeparatorColor:
|
| - return kMenuSeparatorColor;
|
| - case kColorId_SelectedMenuItemForegroundColor:
|
| - case kColorId_HoverMenuItemBackgroundColor:
|
| - case kColorId_MenuBackgroundColor:
|
| - case kColorId_MenuBorderColor:
|
| - NOTREACHED();
|
| - return kInvalidColorIdColor;
|
| -
|
| - // MenuButton
|
| - case kColorId_EnabledMenuButtonBorderColor:
|
| - case kColorId_FocusedMenuButtonBorderColor:
|
| - case kColorId_HoverMenuButtonBorderColor:
|
| - NOTREACHED();
|
| - return kInvalidColorIdColor;
|
| -
|
| - // Label
|
| - case kColorId_LabelEnabledColor:
|
| - return system_colors_[COLOR_BTNTEXT];
|
| - case kColorId_LabelDisabledColor:
|
| - return system_colors_[COLOR_GRAYTEXT];
|
| - case kColorId_LabelBackgroundColor:
|
| - return system_colors_[COLOR_WINDOW];
|
| -
|
| - // Textfield
|
| - case kColorId_TextfieldDefaultColor:
|
| - return system_colors_[COLOR_WINDOWTEXT];
|
| - case kColorId_TextfieldDefaultBackground:
|
| - return system_colors_[COLOR_WINDOW];
|
| - case kColorId_TextfieldReadOnlyColor:
|
| - return system_colors_[COLOR_GRAYTEXT];
|
| - case kColorId_TextfieldReadOnlyBackground:
|
| - return system_colors_[COLOR_3DFACE];
|
| - case kColorId_TextfieldSelectionColor:
|
| - return system_colors_[COLOR_HIGHLIGHTTEXT];
|
| - case kColorId_TextfieldSelectionBackgroundFocused:
|
| - return system_colors_[COLOR_HIGHLIGHT];
|
| -
|
| - // Tooltip
|
| - case kColorId_TooltipBackground:
|
| - case kColorId_TooltipText:
|
| - NOTREACHED();
|
| - return kInvalidColorIdColor;
|
| -
|
| - // Tree
|
| - // NOTE: these aren't right for all themes, but as close as I could get.
|
| - case kColorId_TreeBackground:
|
| - return system_colors_[COLOR_WINDOW];
|
| - case kColorId_TreeText:
|
| - return system_colors_[COLOR_WINDOWTEXT];
|
| - case kColorId_TreeSelectedText:
|
| - return system_colors_[COLOR_HIGHLIGHTTEXT];
|
| - case kColorId_TreeSelectedTextUnfocused:
|
| - return system_colors_[COLOR_BTNTEXT];
|
| - case kColorId_TreeSelectionBackgroundFocused:
|
| - return system_colors_[COLOR_HIGHLIGHT];
|
| - case kColorId_TreeSelectionBackgroundUnfocused:
|
| - return system_colors_[IsUsingHighContrastTheme() ?
|
| - COLOR_MENUHIGHLIGHT : COLOR_BTNFACE];
|
| - case kColorId_TreeArrow:
|
| - return system_colors_[COLOR_WINDOWTEXT];
|
| -
|
| - // Table
|
| - case kColorId_TableBackground:
|
| - return system_colors_[COLOR_WINDOW];
|
| - case kColorId_TableText:
|
| - return system_colors_[COLOR_WINDOWTEXT];
|
| - case kColorId_TableSelectedText:
|
| - return system_colors_[COLOR_HIGHLIGHTTEXT];
|
| - case kColorId_TableSelectedTextUnfocused:
|
| - return system_colors_[COLOR_BTNTEXT];
|
| - case kColorId_TableSelectionBackgroundFocused:
|
| - return system_colors_[COLOR_HIGHLIGHT];
|
| - case kColorId_TableSelectionBackgroundUnfocused:
|
| - return system_colors_[IsUsingHighContrastTheme() ?
|
| - COLOR_MENUHIGHLIGHT : COLOR_BTNFACE];
|
| - case kColorId_TableGroupingIndicatorColor:
|
| - return system_colors_[COLOR_GRAYTEXT];
|
| -
|
| - // Results Tables
|
| - case kColorId_ResultsTableNormalBackground:
|
| - return system_colors_[COLOR_WINDOW];
|
| - case kColorId_ResultsTableHoveredBackground:
|
| - return color_utils::AlphaBlend(system_colors_[COLOR_HIGHLIGHT],
|
| - system_colors_[COLOR_WINDOW], 0x40);
|
| - case kColorId_ResultsTableSelectedBackground:
|
| - return system_colors_[COLOR_HIGHLIGHT];
|
| - case kColorId_ResultsTableNormalText:
|
| - case kColorId_ResultsTableHoveredText:
|
| - return system_colors_[COLOR_WINDOWTEXT];
|
| - case kColorId_ResultsTableSelectedText:
|
| - return system_colors_[COLOR_HIGHLIGHTTEXT];
|
| - case kColorId_ResultsTableNormalDimmedText:
|
| - return color_utils::AlphaBlend(system_colors_[COLOR_WINDOWTEXT],
|
| - system_colors_[COLOR_WINDOW], 0x80);
|
| - case kColorId_ResultsTableHoveredDimmedText:
|
| - return color_utils::AlphaBlend(
|
| - system_colors_[COLOR_WINDOWTEXT],
|
| - GetSystemColor(kColorId_ResultsTableHoveredBackground), 0x80);
|
| - case kColorId_ResultsTableSelectedDimmedText:
|
| - return color_utils::AlphaBlend(system_colors_[COLOR_HIGHLIGHTTEXT],
|
| - system_colors_[COLOR_HIGHLIGHT], 0x80);
|
| - case kColorId_ResultsTableNormalUrl:
|
| - return color_utils::GetReadableColor(SkColorSetRGB(0, 128, 0),
|
| - system_colors_[COLOR_WINDOW]);
|
| - case kColorId_ResultsTableHoveredUrl:
|
| - return color_utils::GetReadableColor(
|
| - SkColorSetRGB(0, 128, 0),
|
| - GetSystemColor(kColorId_ResultsTableHoveredBackground));
|
| - case kColorId_ResultsTableSelectedUrl:
|
| - return color_utils::GetReadableColor(SkColorSetRGB(0, 128, 0),
|
| - system_colors_[COLOR_HIGHLIGHT]);
|
| - case kColorId_ResultsTableNormalDivider:
|
| - return color_utils::AlphaBlend(system_colors_[COLOR_WINDOWTEXT],
|
| - system_colors_[COLOR_WINDOW], 0x34);
|
| - case kColorId_ResultsTableHoveredDivider:
|
| - return color_utils::AlphaBlend(
|
| - system_colors_[COLOR_WINDOWTEXT],
|
| - GetSystemColor(kColorId_ResultsTableHoveredBackground), 0x34);
|
| - case kColorId_ResultsTableSelectedDivider:
|
| - return color_utils::AlphaBlend(system_colors_[COLOR_HIGHLIGHTTEXT],
|
| - system_colors_[COLOR_HIGHLIGHT], 0x34);
|
| - }
|
| - NOTREACHED();
|
| - 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::RefPtr<skia::BitmapPlatformDevice> device = skia::AdoptRef(
|
| - skia::BitmapPlatformDevice::Create(
|
| - rect.width(), rect.height(), false, NULL));
|
| - DCHECK(device);
|
| - SkCanvas offscreen_canvas(device.get());
|
| - 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, kN32_SkColorType);
|
| -
|
| - // 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);
|
| - return (handle && get_theme_part_size_) ?
|
| - get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size) :
|
| - 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();
|
| - break;
|
| - }
|
| -
|
| - switch (state) {
|
| - case kDisabled:
|
| - classic_state |= DFCS_INACTIVE;
|
| - break;
|
| - case kHovered:
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - classic_state |= DFCS_PUSHED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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);
|
| - }
|
| -
|
| - // Classic theme doesn't support indeterminate checkboxes. We draw
|
| - // a recangle inside a checkbox like IE10 does.
|
| - if (part_id == BP_CHECKBOX && extra.indeterminate) {
|
| - RECT inner_rect = *rect;
|
| - // "4 / 13" is same as IE10 in classic theme.
|
| - int padding = (inner_rect.right - inner_rect.left) * 4 / 13;
|
| - InflateRect(&inner_rect, -padding, -padding);
|
| - int color_index = state == kDisabled ? COLOR_GRAYTEXT : COLOR_WINDOWTEXT;
|
| - FillRect(hdc, &inner_rect, GetSysColorBrush(color_index));
|
| - }
|
| -
|
| - return S_OK;
|
| -}
|
| -
|
| -HRESULT NativeThemeWin::PaintMenuSeparator(
|
| - HDC hdc,
|
| - const gfx::Rect& rect) 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);
|
| - return (handle && draw_theme_) ?
|
| - draw_theme_(handle, hdc, MENU_POPUPGUTTER, MPI_NORMAL, &rect_win, NULL) :
|
| - 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);
|
| - }
|
| - // 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.Get(), 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.Get(), 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.Get(), 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.Get(), 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 statement counterintuitive.
|
| - UINT pfc_state = extra.pointing_right ? DFCS_MENUARROW : 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);
|
| - if (handle && draw_theme_) {
|
| - const int state_id = extra.is_radio ?
|
| - ((state == kDisabled) ? MC_BULLETDISABLED : MC_BULLETNORMAL) :
|
| - ((state == kDisabled) ? MC_CHECKMARKDISABLED : MC_CHECKMARKNORMAL);
|
| - RECT rect_win = rect.ToRECT();
|
| - 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);
|
| - if (!handle || !draw_theme_)
|
| - return S_OK; // Nothing to do for background.
|
| -
|
| - int state_id = state == kDisabled ? MCB_DISABLED : MCB_NORMAL;
|
| - RECT rect_win = rect.ToRECT();
|
| - return draw_theme_(handle, hdc, MENU_POPUPCHECKBACKGROUND, state_id,
|
| - &rect_win, NULL);
|
| -}
|
| -
|
| -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 = MPI_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = extra.is_selected ? MPI_DISABLEDHOT : MPI_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = MPI_HOT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 = extra.is_default ? PBS_DEFAULTED : PBS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = PBS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = PBS_HOT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - state_id = PBS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 = extra.checked ? RBS_CHECKEDNORMAL : RBS_UNCHECKEDNORMAL;
|
| - 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:
|
| - break;
|
| - case kPressed:
|
| - state_id = extra.checked ? RBS_CHECKEDPRESSED : RBS_UNCHECKEDPRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 = extra.checked ?
|
| - CBS_CHECKEDNORMAL :
|
| - (extra.indeterminate ? CBS_MIXEDNORMAL : CBS_UNCHECKEDNORMAL);
|
| - 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:
|
| - break;
|
| - case kPressed:
|
| - state_id = extra.checked ?
|
| - CBS_CHECKEDPRESSED :
|
| - (extra.indeterminate ? CBS_MIXEDPRESSED : CBS_UNCHECKEDPRESSED);
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 = CBXS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = CBXS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = CBXS_HOT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - state_id = CBXS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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][kNumStates] = {
|
| - 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_GE(index, 0);
|
| - DCHECK_LT(static_cast<size_t>(index), arraysize(state_id_matrix));
|
| - 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();
|
| - break;
|
| - }
|
| - }
|
| - return PaintScaledTheme(handle, hdc, SBP_ARROWBTN, state_id, rect);
|
| - }
|
| -
|
| - int classic_state = DFCS_SCROLLDOWN;
|
| - switch (part) {
|
| - case kScrollbarDownArrow:
|
| - break;
|
| - case kScrollbarLeftArrow:
|
| - classic_state = DFCS_SCROLLLEFT;
|
| - break;
|
| - case kScrollbarRightArrow:
|
| - classic_state = DFCS_SCROLLRIGHT;
|
| - break;
|
| - case kScrollbarUpArrow:
|
| - classic_state = DFCS_SCROLLUP;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - 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;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 = SBP_THUMBBTNVERT;
|
| - switch (part) {
|
| - case kScrollbarHorizontalThumb:
|
| - part_id = SBP_THUMBBTNHORZ;
|
| - break;
|
| - case kScrollbarVerticalThumb:
|
| - break;
|
| - case kScrollbarHorizontalGripper:
|
| - part_id = SBP_GRIPPERHORZ;
|
| - break;
|
| - case kScrollbarVerticalGripper:
|
| - part_id = SBP_GRIPPERVERT;
|
| - break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -
|
| - int state_id = SCRBS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = SCRBS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = extra.is_hovering ? SCRBS_HOVER : SCRBS_HOT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - state_id = SCRBS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -
|
| - if (handle && draw_theme_)
|
| - return PaintScaledTheme(handle, hdc, part_id, state_id, rect);
|
| -
|
| - // 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();
|
| -
|
| - const int part_id = extra.is_upper ?
|
| - ((part == kScrollbarHorizontalTrack) ?
|
| - SBP_UPPERTRACKHORZ : SBP_UPPERTRACKVERT) :
|
| - ((part == kScrollbarHorizontalTrack) ?
|
| - SBP_LOWERTRACKHORZ : SBP_LOWERTRACKVERT);
|
| -
|
| - int state_id = SCRBS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = SCRBS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = SCRBS_HOVER;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - state_id = SCRBS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -
|
| - if (handle && draw_theme_)
|
| - return draw_theme_(handle, hdc, part_id, state_id, &rect_win, NULL);
|
| -
|
| - // Draw it manually.
|
| - if ((system_colors_[COLOR_SCROLLBAR] != system_colors_[COLOR_3DFACE]) &&
|
| - (system_colors_[COLOR_SCROLLBAR] != system_colors_[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 = extra.spin_up ? UPS_NORMAL : DNS_NORMAL;
|
| - 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:
|
| - break;
|
| - case kPressed:
|
| - state_id = extra.spin_up ? UPS_PRESSED : DNS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 {
|
| - const int part_id = extra.vertical ?
|
| - ((part == kTrackbarTrack) ? TKP_TRACKVERT : TKP_THUMBVERT) :
|
| - ((part == kTrackbarTrack) ? TKP_TRACK : TKP_THUMBBOTTOM);
|
| -
|
| - int state_id = TUS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = TUS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = TUS_HOT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - state_id = TUS_PRESSED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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 kDeterminateOverlayPixelsPerSecond = 300;
|
| - const int kDeterminateOverlayWidth = 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();
|
| -
|
| - HANDLE handle = GetThemeHandle(PROGRESS);
|
| - if (!handle || !draw_theme_ || !draw_theme_ex_) {
|
| - FillRect(hdc, &bar_rect, GetSysColorBrush(COLOR_BTNFACE));
|
| - FillRect(hdc, &value_rect, GetSysColorBrush(COLOR_BTNSHADOW));
|
| - DrawEdge(hdc, &bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
|
| - return S_OK;
|
| - }
|
| -
|
| - draw_theme_(handle, hdc, PP_BAR, 0, &bar_rect, NULL);
|
| -
|
| - bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA;
|
| - int bar_width = bar_rect.right - bar_rect.left;
|
| - if (!extra.determinate) {
|
| - // The glossy overlay for the indeterminate progress bar has a 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;
|
| - RECT overlay_rect = bar_rect;
|
| - overlay_rect.left += ComputeAnimationProgress(
|
| - width_with_margin, overlay_width, kIndeterminateOverlayPixelsPerSecond,
|
| - extra.animated_seconds);
|
| - 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;
|
| - }
|
| -
|
| - // We care about the direction here because PP_CHUNK painting is asymmetric.
|
| - // TODO(morrita): This RTL guess can be wrong. We should pass in the
|
| - // direction from WebKit.
|
| - const DTBGOPTS value_draw_options = {
|
| - sizeof(DTBGOPTS),
|
| - (bar_rect.right == value_rect.right && bar_rect.left != value_rect.left) ?
|
| - DTBG_MIRRORDC : 0,
|
| - bar_rect
|
| - };
|
| - if (pre_vista) {
|
| - // On XP, the progress bar is chunk-style and has no glossy effect. We need
|
| - // to shrink the 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
|
| - // and a glossy effect. 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);
|
| -
|
| - RECT overlay_rect = value_rect;
|
| - overlay_rect.left += ComputeAnimationProgress(
|
| - bar_width, kDeterminateOverlayWidth, kDeterminateOverlayPixelsPerSecond,
|
| - extra.animated_seconds);
|
| - overlay_rect.right = overlay_rect.left + kDeterminateOverlayWidth;
|
| - draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, &value_rect);
|
| - }
|
| - 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 state_id = ETS_NORMAL;
|
| - switch (state) {
|
| - case kDisabled:
|
| - state_id = ETS_DISABLED;
|
| - break;
|
| - case kHovered:
|
| - state_id = ETS_HOT;
|
| - break;
|
| - case kNormal:
|
| - if (extra.is_read_only)
|
| - state_id = ETS_READONLY;
|
| - else if (extra.is_focused)
|
| - state_id = ETS_FOCUSED;
|
| - break;
|
| - case kPressed:
|
| - state_id = ETS_SELECTED;
|
| - break;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| -
|
| - RECT rect_win = rect.ToRECT();
|
| - return PaintTextField(hdc, EP_EDITTEXT, 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.
|
| - base::win::ScopedGDIObject<HBRUSH> bg_brush(CreateSolidBrush(color));
|
| - // 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))) {
|
| - // 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);
|
| - }
|
| - return S_OK;
|
| - }
|
| -
|
| - static const DTBGOPTS omit_border_options = {
|
| - sizeof(DTBGOPTS),
|
| - DTBG_OMITBORDER,
|
| - { 0, 0, 0, 0 }
|
| - };
|
| - HRESULT hr = draw_theme_ex_ ?
|
| - draw_theme_ex_(handle, hdc, part_id, state_id, rect,
|
| - draw_edges ? NULL : &omit_border_options) :
|
| - 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);
|
| - }
|
| - return hr;
|
| -}
|
| -
|
| -HRESULT NativeThemeWin::PaintScaledTheme(HANDLE theme,
|
| - HDC hdc,
|
| - int part_id,
|
| - int state_id,
|
| - const gfx::Rect& rect) const {
|
| - // Correct the scaling and positioning of sub-components such as scrollbar
|
| - // arrows and thumb grippers in the event that the world transform applies
|
| - // scaling (e.g. in high-DPI mode).
|
| - XFORM save_transform;
|
| - if (GetWorldTransform(hdc, &save_transform)) {
|
| - float scale = save_transform.eM11;
|
| - if (scale != 1 && save_transform.eM12 == 0) {
|
| - ModifyWorldTransform(hdc, NULL, MWT_IDENTITY);
|
| - gfx::Rect scaled_rect(gfx::ToEnclosedRect(gfx::ScaleRect(rect, scale)));
|
| - scaled_rect.Offset(save_transform.eDx, save_transform.eDy);
|
| - RECT bounds = scaled_rect.ToRECT();
|
| - HRESULT result = draw_theme_(theme, hdc, part_id, state_id, &bounds,
|
| - NULL);
|
| - SetWorldTransform(hdc, &save_transform);
|
| - return result;
|
| - }
|
| - }
|
| - RECT bounds = rect.ToRECT();
|
| - return draw_theme_(theme, hdc, part_id, state_id, &bounds, NULL);
|
| -}
|
| -
|
| -// static
|
| -NativeThemeWin::ThemeName NativeThemeWin::GetThemeName(Part part) {
|
| - switch (part) {
|
| - case kCheckbox:
|
| - case kPushButton:
|
| - case kRadio:
|
| - return BUTTON;
|
| - case kInnerSpinButton:
|
| - return SPIN;
|
| - case kMenuList:
|
| - case kMenuCheck:
|
| - case kMenuPopupArrow:
|
| - case kMenuPopupGutter:
|
| - case kMenuPopupSeparator:
|
| - return MENU;
|
| - case kProgressBar:
|
| - return PROGRESS;
|
| - case kScrollbarDownArrow:
|
| - case kScrollbarLeftArrow:
|
| - case kScrollbarRightArrow:
|
| - case kScrollbarUpArrow:
|
| - case kScrollbarHorizontalThumb:
|
| - case kScrollbarVerticalThumb:
|
| - case kScrollbarHorizontalTrack:
|
| - case kScrollbarVerticalTrack:
|
| - return SCROLLBAR;
|
| - case kSliderTrack:
|
| - case kSliderThumb:
|
| - return TRACKBAR;
|
| - case kTextField:
|
| - return TEXTFIELD;
|
| - case kWindowResizeGripper:
|
| - return STATUS;
|
| - case kComboboxArrow:
|
| - case kMenuCheckBackground:
|
| - case kMenuPopupBackground:
|
| - case kMenuItemBackground:
|
| - case kScrollbarHorizontalGripper:
|
| - case kScrollbarVerticalGripper:
|
| - case kScrollbarCorner:
|
| - case kTabPanelBackground:
|
| - case kTrackbarThumb:
|
| - case kTrackbarTrack:
|
| - case kMaxPart:
|
| - NOTREACHED();
|
| - }
|
| - return LAST;
|
| -}
|
| -
|
| -// static
|
| -int NativeThemeWin::GetWindowsPart(Part part,
|
| - State state,
|
| - const ExtraParams& extra) {
|
| - switch (part) {
|
| - case kCheckbox:
|
| - return BP_CHECKBOX;
|
| - case kMenuCheck:
|
| - return MENU_POPUPCHECK;
|
| - case kMenuPopupArrow:
|
| - return MENU_POPUPSUBMENU;
|
| - case kMenuPopupGutter:
|
| - return MENU_POPUPGUTTER;
|
| - case kMenuPopupSeparator:
|
| - return MENU_POPUPSEPARATOR;
|
| - case kPushButton:
|
| - return BP_PUSHBUTTON;
|
| - case kRadio:
|
| - return BP_RADIOBUTTON;
|
| - case kScrollbarDownArrow:
|
| - case kScrollbarLeftArrow:
|
| - case kScrollbarRightArrow:
|
| - case kScrollbarUpArrow:
|
| - return SBP_ARROWBTN;
|
| - case kScrollbarHorizontalThumb:
|
| - return SBP_THUMBBTNHORZ;
|
| - case kScrollbarVerticalThumb:
|
| - return SBP_THUMBBTNVERT;
|
| - case kWindowResizeGripper:
|
| - return SP_GRIPPER;
|
| - case kComboboxArrow:
|
| - case kInnerSpinButton:
|
| - case kMenuList:
|
| - case kMenuCheckBackground:
|
| - case kMenuPopupBackground:
|
| - case kMenuItemBackground:
|
| - case kProgressBar:
|
| - case kScrollbarHorizontalTrack:
|
| - case kScrollbarVerticalTrack:
|
| - case kScrollbarHorizontalGripper:
|
| - case kScrollbarVerticalGripper:
|
| - case kScrollbarCorner:
|
| - case kSliderTrack:
|
| - case kSliderThumb:
|
| - case kTabPanelBackground:
|
| - case kTextField:
|
| - case kTrackbarThumb:
|
| - case kTrackbarTrack:
|
| - case kMaxPart:
|
| - NOTREACHED();
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -int NativeThemeWin::GetWindowsState(Part part,
|
| - State state,
|
| - const ExtraParams& extra) {
|
| - switch (part) {
|
| - case kCheckbox:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return CBS_UNCHECKEDDISABLED;
|
| - case kHovered:
|
| - return CBS_UNCHECKEDHOT;
|
| - case kNormal:
|
| - return CBS_UNCHECKEDNORMAL;
|
| - case kPressed:
|
| - return CBS_UNCHECKEDPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kMenuCheck:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return extra.menu_check.is_radio ?
|
| - MC_BULLETDISABLED : MC_CHECKMARKDISABLED;
|
| - case kHovered:
|
| - case kNormal:
|
| - case kPressed:
|
| - return extra.menu_check.is_radio ?
|
| - MC_BULLETNORMAL : MC_CHECKMARKNORMAL;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kMenuPopupArrow:
|
| - case kMenuPopupGutter:
|
| - case kMenuPopupSeparator:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return MBI_DISABLED;
|
| - case kHovered:
|
| - return MBI_HOT;
|
| - case kNormal:
|
| - return MBI_NORMAL;
|
| - case kPressed:
|
| - return MBI_PUSHED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kPushButton:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return PBS_DISABLED;
|
| - case kHovered:
|
| - return PBS_HOT;
|
| - case kNormal:
|
| - return PBS_NORMAL;
|
| - case kPressed:
|
| - return PBS_PRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kRadio:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return RBS_UNCHECKEDDISABLED;
|
| - case kHovered:
|
| - return RBS_UNCHECKEDHOT;
|
| - case kNormal:
|
| - return RBS_UNCHECKEDNORMAL;
|
| - case kPressed:
|
| - return RBS_UNCHECKEDPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kScrollbarDownArrow:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return ABS_DOWNDISABLED;
|
| - case kHovered:
|
| - // Mimic ScrollbarThemeChromiumWin.cpp in WebKit.
|
| - return base::win::GetVersion() < base::win::VERSION_VISTA ?
|
| - ABS_DOWNHOT : ABS_DOWNHOVER;
|
| - case kNormal:
|
| - return ABS_DOWNNORMAL;
|
| - case kPressed:
|
| - return ABS_DOWNPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kScrollbarLeftArrow:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return ABS_LEFTDISABLED;
|
| - case kHovered:
|
| - // Mimic ScrollbarThemeChromiumWin.cpp in WebKit.
|
| - return base::win::GetVersion() < base::win::VERSION_VISTA ?
|
| - ABS_LEFTHOT : ABS_LEFTHOVER;
|
| - case kNormal:
|
| - return ABS_LEFTNORMAL;
|
| - case kPressed:
|
| - return ABS_LEFTPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kScrollbarRightArrow:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return ABS_RIGHTDISABLED;
|
| - case kHovered:
|
| - // Mimic ScrollbarThemeChromiumWin.cpp in WebKit.
|
| - return base::win::GetVersion() < base::win::VERSION_VISTA ?
|
| - ABS_RIGHTHOT : ABS_RIGHTHOVER;
|
| - case kNormal:
|
| - return ABS_RIGHTNORMAL;
|
| - case kPressed:
|
| - return ABS_RIGHTPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - break;
|
| - case kScrollbarUpArrow:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return ABS_UPDISABLED;
|
| - case kHovered:
|
| - // Mimic ScrollbarThemeChromiumWin.cpp in WebKit.
|
| - return base::win::GetVersion() < base::win::VERSION_VISTA ?
|
| - ABS_UPHOT : ABS_UPHOVER;
|
| - case kNormal:
|
| - return ABS_UPNORMAL;
|
| - case kPressed:
|
| - return ABS_UPPRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - break;
|
| - case kScrollbarHorizontalThumb:
|
| - case kScrollbarVerticalThumb:
|
| - switch (state) {
|
| - case kDisabled:
|
| - return SCRBS_DISABLED;
|
| - case kHovered:
|
| - // Mimic WebKit's behaviour in ScrollbarThemeChromiumWin.cpp.
|
| - return base::win::GetVersion() < base::win::VERSION_VISTA ?
|
| - SCRBS_HOT : SCRBS_HOVER;
|
| - case kNormal:
|
| - return SCRBS_NORMAL;
|
| - case kPressed:
|
| - return SCRBS_PRESSED;
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kWindowResizeGripper:
|
| - switch (state) {
|
| - case kDisabled:
|
| - case kHovered:
|
| - case kNormal:
|
| - case kPressed:
|
| - return 1; // gripper has no windows state
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - return 0;
|
| - }
|
| - case kComboboxArrow:
|
| - case kInnerSpinButton:
|
| - case kMenuList:
|
| - case kMenuCheckBackground:
|
| - case kMenuPopupBackground:
|
| - case kMenuItemBackground:
|
| - case kProgressBar:
|
| - case kScrollbarHorizontalTrack:
|
| - case kScrollbarVerticalTrack:
|
| - case kScrollbarHorizontalGripper:
|
| - case kScrollbarVerticalGripper:
|
| - case kScrollbarCorner:
|
| - case kSliderTrack:
|
| - case kSliderThumb:
|
| - case kTabPanelBackground:
|
| - case kTextField:
|
| - case kTrackbarThumb:
|
| - case kTrackbarTrack:
|
| - case kMaxPart:
|
| - NOTREACHED();
|
| - }
|
| - return 0;
|
| -}
|
| -
|
| -HRESULT NativeThemeWin::GetThemeInt(ThemeName theme,
|
| - int part_id,
|
| - int state_id,
|
| - int prop_id,
|
| - int *value) const {
|
| - HANDLE handle = GetThemeHandle(theme);
|
| - return (handle && get_theme_int_) ?
|
| - get_theme_int_(handle, part_id, state_id, prop_id, value) : 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.Get(), mask_bitmap);
|
| - RECT local_rect = { 0, 0, width, height };
|
| - DrawFrameControl(bitmap_dc.Get(), &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 = COLOR_MENU;
|
| - int text_color_key = COLOR_MENUTEXT;
|
| - switch (control_state) {
|
| - case kDisabled:
|
| - bg_color_key = is_selected ? COLOR_HIGHLIGHT : COLOR_MENU;
|
| - text_color_key = COLOR_GRAYTEXT;
|
| - break;
|
| - case kHovered:
|
| - bg_color_key = COLOR_HIGHLIGHT;
|
| - text_color_key = COLOR_HIGHLIGHTTEXT;
|
| - break;
|
| - case kNormal:
|
| - break;
|
| - case kPressed:
|
| - case kNumStates:
|
| - NOTREACHED();
|
| - 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.Get(), 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;
|
| - case LAST:
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - theme_handles_[theme_name] = handle;
|
| - return handle;
|
| -}
|
| -
|
| -} // namespace ui
|
|
|