diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 23:30:47 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-20 23:30:47 +0000 |
commit | 49fdb5a9291f52ce995a2e16c4f1fe6cfdef3edb (patch) | |
tree | 6cf2ef095ff7af44dd21ca691f9d5f0523095265 | |
parent | 3362262e25c76beabd31a5e7e3e2cfedfe1f5ac1 (diff) | |
download | chromium_src-49fdb5a9291f52ce995a2e16c4f1fe6cfdef3edb.zip chromium_src-49fdb5a9291f52ce995a2e16c4f1fe6cfdef3edb.tar.gz chromium_src-49fdb5a9291f52ce995a2e16c4f1fe6cfdef3edb.tar.bz2 |
Chromium side of trackbar drawing. This is needed to support <input type="range">.
This code will not be called until I land the upstream hooks to RenderThemeChromiumWin.cpp to use it.
BUG=8931
Review URL: http://codereview.chromium.org/42451
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12231 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/gfx/native_theme.cc | 138 | ||||
-rw-r--r-- | base/gfx/native_theme.h | 8 | ||||
-rw-r--r-- | webkit/glue/webthemeengine_impl_win.cc | 12 | ||||
-rw-r--r-- | webkit/glue/webthemeengine_impl_win.h | 3 |
4 files changed, 141 insertions, 20 deletions
diff --git a/base/gfx/native_theme.cc b/base/gfx/native_theme.cc index 54b8a75..39ca39d 100644 --- a/base/gfx/native_theme.cc +++ b/base/gfx/native_theme.cc @@ -17,6 +17,38 @@ #include "skia/ext/skia_utils_win.h" #include "skia/include/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); + paint->setShader(shader)->safeUnref(); +} + +} // namespace + namespace gfx { /* static */ @@ -310,27 +342,8 @@ HRESULT NativeTheme::PaintScrollbarTrack( (colorScrollbar != GetSysColor(COLOR_WINDOW))) { FillRect(hdc, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1)); } else { - // Create a 2x2 checkerboard pattern using the 3D face and highlight - // colors. - SkColor face = skia::COLORREFToSkColor(color3DFace); - SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT)); - SkColor buffer[] = { face, highlight, highlight, face }; - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2); - bitmap.setPixels(buffer); - SkShader* shader = SkShader::CreateBitmapShader(bitmap, - SkShader::kRepeat_TileMode, - SkShader::kRepeat_TileMode); - - // Draw that pattern into the target rect, setting the origin to the top - // left corner of the scrollbar track (so the checked rect below the thumb - // aligns properly with the portion above the thumb). - SkMatrix matrix; - matrix.setTranslate(SkIntToScalar(align_rect->left), - SkIntToScalar(align_rect->top)); - shader->setLocalMatrix(matrix); SkPaint paint; - paint.setShader(shader)->unref(); + SetCheckerboardShader(&paint, *align_rect); canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint); } if (classic_state & DFCS_PUSHED) @@ -383,6 +396,88 @@ HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const { return S_OK; } +HRESULT NativeTheme::PaintTrackbar(HDC hdc, + int part_id, + int state_id, + int classic_state, + RECT* rect, + skia::PlatformCanvasWin* 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; +} + HRESULT NativeTheme::PaintTextField(HDC hdc, int part_id, int state_id, @@ -599,6 +694,9 @@ HANDLE NativeTheme::GetThemeHandle(ThemeName theme_name) const 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; diff --git a/base/gfx/native_theme.h b/base/gfx/native_theme.h index 2e923d4..519bf94 100644 --- a/base/gfx/native_theme.h +++ b/base/gfx/native_theme.h @@ -41,6 +41,7 @@ class NativeTheme { STATUS, TAB, TEXTFIELD, + TRACKBAR, WINDOW, LAST }; @@ -199,6 +200,13 @@ class NativeTheme { bool fill_content_area, bool draw_edges) const; + HRESULT PaintTrackbar(HDC hdc, + int part_id, + int state_id, + int classic_state, + RECT* rect, + skia::PlatformCanvasWin* canvas) const; + bool IsThemingActive() const; HRESULT GetThemePartSize(ThemeName themeName, diff --git a/webkit/glue/webthemeengine_impl_win.cc b/webkit/glue/webthemeengine_impl_win.cc index 50e7bd7..dd775b0 100644 --- a/webkit/glue/webthemeengine_impl_win.cc +++ b/webkit/glue/webthemeengine_impl_win.cc @@ -102,4 +102,16 @@ void WebThemeEngineImpl::paintTextField( canvas->endPlatformPaint(); } +void WebThemeEngineImpl::paintTrackbar( + WebCanvas* canvas, int part, int state, int classic_state, + const WebRect& rect) { + HDC hdc = canvas->beginPlatformPaint(); + + RECT native_rect = WebRectToRECT(rect); + gfx::NativeTheme::instance()->PaintTrackbar( + hdc, part, state, classic_state, &native_rect, canvas); + + canvas->endPlatformPaint(); +} + } // namespace webkit_glue diff --git a/webkit/glue/webthemeengine_impl_win.h b/webkit/glue/webthemeengine_impl_win.h index c284527..866e7b8 100644 --- a/webkit/glue/webthemeengine_impl_win.h +++ b/webkit/glue/webthemeengine_impl_win.h @@ -31,6 +31,9 @@ class WebThemeEngineImpl : public WebKit::WebThemeEngine { WebKit::WebCanvas*, int part, int state, int classic_state, const WebKit::WebRect&, WebKit::WebColor, bool fill_content_area, bool draw_edges); + virtual void paintTrackbar( + WebKit::WebCanvas*, int part, int state, int classic_state, + const WebKit::WebRect&); }; } // namespace webkit_glue |