summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 23:30:47 +0000
committerpkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-20 23:30:47 +0000
commit49fdb5a9291f52ce995a2e16c4f1fe6cfdef3edb (patch)
tree6cf2ef095ff7af44dd21ca691f9d5f0523095265
parent3362262e25c76beabd31a5e7e3e2cfedfe1f5ac1 (diff)
downloadchromium_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.cc138
-rw-r--r--base/gfx/native_theme.h8
-rw-r--r--webkit/glue/webthemeengine_impl_win.cc12
-rw-r--r--webkit/glue/webthemeengine_impl_win.h3
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