Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Unified Diff: gfx/native_theme_win.cc

Issue 6246027: Move src/gfx/ to src/ui/gfx... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gfx/native_theme_win.h ('k') | gfx/native_theme_win_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gfx/native_theme_win.cc
===================================================================
--- gfx/native_theme_win.cc (revision 73487)
+++ gfx/native_theme_win.cc (working copy)
@@ -1,874 +0,0 @@
-// Copyright (c) 2011 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 "gfx/native_theme_win.h"
-
-#include <windows.h>
-#include <uxtheme.h>
-#include <vsstyle.h>
-#include <vssym32.h>
-
-#include "base/logging.h"
-#include "base/scoped_handle.h"
-#include "base/win/scoped_gdi_object.h"
-#include "base/win/scoped_hdc.h"
-#include "base/win/windows_version.h"
-#include "gfx/gdi_util.h"
-#include "gfx/rect.h"
-#include "skia/ext/platform_canvas.h"
-#include "skia/ext/skia_utils_win.h"
-#include "third_party/skia/include/core/SkShader.h"
-
-namespace {
-
-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));
-}
-
-} // namespace
-
-namespace gfx {
-
-/* static */
-const NativeTheme* NativeTheme::instance() {
- // The global NativeTheme instance.
- static const NativeTheme s_native_theme;
- return &s_native_theme;
-}
-
-NativeTheme::NativeTheme()
- : 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_));
-}
-
-NativeTheme::~NativeTheme() {
- if (theme_dll_) {
- // todo (cpu): fix this soon.
- // CloseHandles();
- FreeLibrary(theme_dll_);
- }
-}
-
-HRESULT NativeTheme::PaintButton(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(BUTTON);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
-
- // 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 NativeTheme::PaintDialogBackground(HDC hdc, bool active,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(WINDOW);
- if (handle && draw_theme_) {
- return draw_theme_(handle, hdc, WP_DIALOG,
- active ? FS_ACTIVE : FS_INACTIVE, rect, NULL);
- }
-
- // Classic just renders a flat color background.
- FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1));
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintListBackground(HDC hdc,
- bool enabled,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(LIST);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, 1, TS_NORMAL, rect, NULL);
-
- // Draw it manually.
- HBRUSH bg_brush = GetSysColorBrush(COLOR_WINDOW);
- FillRect(hdc, rect, bg_brush);
- DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintMenuArrow(ThemeName theme,
- HDC hdc,
- int part_id,
- int state_id,
- RECT* rect,
- MenuArrowDirection arrow_direction,
- ControlState control_state) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_) {
- if (arrow_direction == RIGHT_POINTING_ARROW) {
- return draw_theme_(handle, hdc, part_id, state_id, rect, 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.
- Rect r(*rect);
- base::win::ScopedHDC mem_dc(CreateCompatibleDC(hdc));
- base::win::ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(),
- r.height()));
- HGDIOBJ old_bitmap = SelectObject(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, part_id,
- 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);
- SelectObject(mem_dc, old_bitmap);
- 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 state;
- if (arrow_direction == RIGHT_POINTING_ARROW)
- state = DFCS_MENUARROW;
- else
- state = DFCS_MENUARROWRIGHT;
- return PaintFrameControl(hdc, rect, DFC_MENU, state, control_state);
-}
-
-HRESULT NativeTheme::PaintMenuBackground(ThemeName theme,
- HDC hdc,
- int part_id,
- int state_id,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_) {
- HRESULT result = draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- FrameRect(hdc, rect, GetSysColorBrush(COLOR_3DSHADOW));
- return result;
- }
-
- FillRect(hdc, rect, GetSysColorBrush(COLOR_MENU));
- DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintMenuCheckBackground(ThemeName theme,
- HDC hdc,
- int part_id,
- int state_id,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- // Nothing to do for background.
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintMenuCheck(ThemeName theme,
- HDC hdc,
- int part_id,
- int state_id,
- RECT* rect,
- ControlState control_state) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_) {
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- }
- return PaintFrameControl(hdc, rect, DFC_MENU, DFCS_MENUCHECK, control_state);
-}
-
-HRESULT NativeTheme::PaintMenuGutter(HDC hdc,
- int part_id,
- int state_id,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- return E_NOTIMPL;
-}
-
-HRESULT NativeTheme::PaintMenuItemBackground(ThemeName theme,
- HDC hdc,
- int part_id,
- int state_id,
- bool selected,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- if (selected)
- FillRect(hdc, rect, GetSysColorBrush(COLOR_HIGHLIGHT));
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintMenuList(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENULIST);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
-
- // Draw it manually.
- DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | classic_state);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintMenuSeparator(HDC hdc,
- int part_id,
- int state_id,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(MENU);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- DrawEdge(hdc, rect, EDGE_ETCHED, BF_TOP);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintScrollbarArrow(HDC hdc,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(SCROLLBAR);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, SBP_ARROWBTN, state_id, rect, NULL);
-
- // Draw it manually.
- DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintScrollbarTrack(
- HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* target_rect,
- RECT* align_rect,
- skia::PlatformCanvas* canvas) const {
- HANDLE handle = GetThemeHandle(SCROLLBAR);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, target_rect, 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, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1));
- } else {
- SkPaint paint;
- SetCheckerboardShader(&paint, *align_rect);
- canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint);
- }
- if (classic_state & DFCS_PUSHED)
- InvertRect(hdc, target_rect);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintScrollbarThumb(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(SCROLLBAR);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
-
- // Draw it manually.
- if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT))
- DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
- // Classic mode doesn't have a gripper.
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintSpinButton(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(SPIN);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
- DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintStatusGripper(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect) const {
- HANDLE handle = GetThemeHandle(STATUS);
- 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, NULL);
- }
-
- // Draw a windows classic scrollbar gripper.
- DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const {
- HANDLE handle = GetThemeHandle(TAB);
- if (handle && draw_theme_)
- return draw_theme_(handle, hdc, TABP_BODY, 0, rect, NULL);
-
- // Classic just renders a flat color background.
- FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1));
- return S_OK;
-}
-
-HRESULT NativeTheme::PaintTrackbar(HDC hdc,
- int part_id,
- int state_id,
- int classic_state,
- RECT* rect,
- skia::PlatformCanvas* canvas) const {
- // 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 channel_rect = *rect;
- 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, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE);
- } else {
- // Split rect into top and bottom pieces.
- RECT top_section = *rect;
- RECT bottom_section = *rect;
- 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 (classic_state & DFCS_PUSHED) {
- SkPaint paint;
- SetCheckerboardShader(&paint, *rect);
-
- // 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;
-}
-
-// <-a->
-// [ ***** ]
-// ____ | |
-// <-a-> <------b----->
-// a: object_width
-// b: frame_width
-// *: animating object
-//
-// - the animation goes from "[" to "]" repeatedly.
-// - the animation offset is at first "|"
-//
-static 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;
-}
-
-static RECT InsetRect(const RECT* rect, int size) {
- gfx::Rect result(*rect);
- result.Inset(size, size);
- return result.ToRECT();
-}
-
-HRESULT NativeTheme::PaintProgressBar(HDC hdc,
- RECT* bar_rect,
- RECT* value_rect,
- bool determinate,
- double animated_seconds,
- skia::PlatformCanvas* canvas) 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;
-
- 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 (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,
- 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,
- 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 NativeTheme::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 DTBGOPTS omit_border_options = {
- sizeof(DTBGOPTS),
- DTBG_OMITBORDER,
- {0,0,0,0}
- };
- 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;
-}
-
-bool NativeTheme::IsThemingActive() const {
- if (is_theme_active_)
- return !!is_theme_active_();
- return false;
-}
-
-HRESULT NativeTheme::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 NativeTheme::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 NativeTheme::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;
-}
-
-HRESULT NativeTheme::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;
-}
-
-Size NativeTheme::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 Size(border, border);
- else
- return Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
-}
-
-
-void NativeTheme::DisableTheming() const {
- if (!set_theme_properties_)
- return;
- set_theme_properties_(0);
-}
-
-HRESULT NativeTheme::PaintFrameControl(HDC hdc,
- RECT* rect,
- UINT type,
- UINT state,
- ControlState control_state) const {
- const int width = rect->right - rect->left;
- const int height = rect->bottom - rect->top;
-
- // 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::ScopedHDC bitmap_dc(CreateCompatibleDC(NULL));
- HGDIOBJ org_bitmap = SelectObject(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 CONTROL_HIGHLIGHTED:
- bg_color_key = COLOR_HIGHLIGHT;
- text_color_key = COLOR_HIGHLIGHTTEXT;
- break;
- case CONTROL_NORMAL:
- bg_color_key = COLOR_MENU;
- text_color_key = COLOR_MENUTEXT;
- break;
- case CONTROL_DISABLED:
- bg_color_key = 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->left, rect->top, width, height, bitmap_dc, 0, 0, SRCCOPY);
- SetBkColor(hdc, old_bg_color);
- SetTextColor(hdc, old_text_color);
-
- SelectObject(bitmap_dc, org_bitmap);
-
- return S_OK;
-}
-
-void NativeTheme::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 NativeTheme::IsClassicTheme(ThemeName name) const {
- if (!theme_dll_)
- return true;
-
- return !GetThemeHandle(name);
-}
-
-HANDLE NativeTheme::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 gfx
« no previous file with comments | « gfx/native_theme_win.h ('k') | gfx/native_theme_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698