diff options
author | dpranke@google.com <dpranke@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-14 21:19:21 +0000 |
---|---|---|
committer | dpranke@google.com <dpranke@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-14 21:19:21 +0000 |
commit | cf37da383867e81a5998fb06f5bca52dc92552c7 (patch) | |
tree | f5cd435729061d74f739cadd0d51a09019c849c2 /webkit/tools/test_shell | |
parent | a1b9f5d1be682acc27767c121e282b2353510b48 (diff) | |
download | chromium_src-cf37da383867e81a5998fb06f5bca52dc92552c7.zip chromium_src-cf37da383867e81a5998fb06f5bca52dc92552c7.tar.gz chromium_src-cf37da383867e81a5998fb06f5bca52dc92552c7.tar.bz2 |
This change adds a new "generic" theme to the Windows implementation of
test_shell, so that we can render controls in a platform-verion-independent
manner, allowing us to use (almost) a single set of baselines for all
versions of Windows.
test_shell is modified to accept three new switches: --ux-theme (for the
default or "new" XP/Vista theming engine), --classic-theme (for the older
"Classic" theming engine), and --generic-theme (for the new Skia-based
test theme). Specifying --layout-tests will default to --classic-theme,
otherwise --ux-theme is the default (this is compatible with existing
test_shell behavior). Once the new version-independent baselines are
checked in, we will flip this behavior so --layout-tests defaults to
--generic-theme as well.
This change adds test_shell_webtheme{engine,control}.{cc,h} as Windows-only
build files, and adds documentation to webkit/api/public/win/WebThemeEngine.
It also adds a chromium-win-xp platform baseline directory (currently empty)
and modifies the layout_test/layout_package/platform_utils_win.py baseline
search path to confirm to WebKit's directory search logic (vista and win7
look just in chromium-win, but XP looks in chromium-win-xp first, followed by
chromium-win).
BUG=none
R=darin,pkasting
TEST=none
Review URL: http://codereview.chromium.org/192021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26161 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/tools/test_shell')
-rw-r--r-- | webkit/tools/test_shell/test_shell.gyp | 5 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_main.cc | 17 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_switches.cc | 11 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_switches.h | 3 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webkit_init.h | 29 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webthemecontrol.cc | 395 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webthemecontrol.h | 170 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webthemeengine.cc | 536 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell_webthemeengine.h | 64 |
9 files changed, 1224 insertions, 6 deletions
diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp index 585e38d..e1648f7 100644 --- a/webkit/tools/test_shell/test_shell.gyp +++ b/webkit/tools/test_shell/test_shell.gyp @@ -85,6 +85,10 @@ 'test_shell_switches.h', 'test_shell_win.cc', 'test_shell_webkit_init.h', + 'test_shell_webthemecontrol.h', + 'test_shell_webthemecontrol.cc', + 'test_shell_webthemeengine.h', + 'test_shell_webthemeengine.cc', 'test_web_worker.h', 'test_webview_delegate.cc', 'test_webview_delegate.h', @@ -178,6 +182,7 @@ }, { # else: OS!=win 'sources/': [ ['exclude', '_win\\.cc$'], + ['exclude', '_webtheme(control|engine)\.(cc|h)$'], ], 'sources!': [ 'drag_delegate.cc', diff --git a/webkit/tools/test_shell/test_shell_main.cc b/webkit/tools/test_shell/test_shell_main.cc index 8f18386..ff280f4 100644 --- a/webkit/tools/test_shell/test_shell_main.cc +++ b/webkit/tools/test_shell/test_shell_main.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <iostream> - #include "base/at_exit.h" #include "base/basictypes.h" #include "base/command_line.h" @@ -80,6 +78,11 @@ int main(int argc, char* argv[]) { parsed_command_line.HasSwitch(test_shell::kLayoutTests)); bool layout_test_mode = parsed_command_line.HasSwitch(test_shell::kLayoutTests); + bool ux_theme = parsed_command_line.HasSwitch(test_shell::kUxTheme); + bool generic_theme = + parsed_command_line.HasSwitch(test_shell::kGenericTheme); + bool classic_theme = (layout_test_mode && !ux_theme && !generic_theme) || + parsed_command_line.HasSwitch(test_shell::kClassicTheme); bool enable_gp_fault_error_box = false; enable_gp_fault_error_box = @@ -156,9 +159,15 @@ int main(int argc, char* argv[]) { TestShell::SetAllowScriptsToCloseWindows(); // Disable user themes for layout tests so pixel tests are consistent. - if (layout_test_mode) { +#if defined(OS_WIN) + TestShellWebTheme::Engine engine; +#endif + if (classic_theme) platform.SelectUnifiedTheme(); - } +#if defined(OS_WIN) + if (generic_theme) + test_shell_webkit_init.setThemeEngine(&engine); +#endif if (parsed_command_line.HasSwitch(test_shell::kTestShellTimeOut)) { const std::wstring timeout_str = parsed_command_line.GetSwitchValue( diff --git a/webkit/tools/test_shell/test_shell_switches.cc b/webkit/tools/test_shell/test_shell_switches.cc index 0884929..26a79cb 100644 --- a/webkit/tools/test_shell/test_shell_switches.cc +++ b/webkit/tools/test_shell/test_shell_switches.cc @@ -14,6 +14,17 @@ const wchar_t kNoErrorDialogs[] = L"noerrdialogs"; const wchar_t kLayoutTests[] = L"layout-tests"; const wchar_t kCrashDumps[] = L"crash-dumps"; // Enable crash dumps +// Causes the test_shell to run with a generic theme (part of layout_tests). +const wchar_t kGenericTheme[] = L"generic-theme"; + +// This causes the test_shell to run with the classic theme. +// Passing --layout-tests enables this by default. +const wchar_t kClassicTheme[] = L"classic-theme"; + +// This causes the test_shell to run with the new windows theming engine +// enabled. This is the default unless --layout-tests is specified. +const wchar_t kUxTheme[] = L"ux-theme"; + // Command line flags that control the tests when layout-tests is specified. const wchar_t kNoTree[] = L"notree"; // Don't dump the render tree. const wchar_t kDumpPixels[] = L"pixel-tests"; // Enable pixel tests. diff --git a/webkit/tools/test_shell/test_shell_switches.h b/webkit/tools/test_shell/test_shell_switches.h index be995d1..d07398b 100644 --- a/webkit/tools/test_shell/test_shell_switches.h +++ b/webkit/tools/test_shell/test_shell_switches.h @@ -12,6 +12,9 @@ namespace test_shell { extern const wchar_t kCrashDumps[]; extern const wchar_t kDumpPixels[]; extern const wchar_t kLayoutTests[]; +extern const wchar_t kGenericTheme[]; +extern const wchar_t kClassicTheme[]; +extern const wchar_t kUxTheme[]; extern const wchar_t kNoErrorDialogs[]; extern const wchar_t kNoTree[]; extern const wchar_t kTestShellTimeOut[]; diff --git a/webkit/tools/test_shell/test_shell_webkit_init.h b/webkit/tools/test_shell/test_shell_webkit_init.h index 354d949..cc25ec7 100644 --- a/webkit/tools/test_shell/test_shell_webkit_init.h +++ b/webkit/tools/test_shell/test_shell_webkit_init.h @@ -29,9 +29,14 @@ #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" #include "v8/include/v8.h" +#if defined(OS_WIN) +#include "webkit/api/public/win/WebThemeEngine.h" +#include "webkit/tools/test_shell/test_shell_webthemeengine.h" +#endif + class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { public: - TestShellWebKitInit(bool layout_test_mode) { + explicit TestShellWebKitInit(bool layout_test_mode) { v8::V8::SetCounterFunction(StatsTable::FindLocation); WebKit::initialize(this); @@ -56,6 +61,11 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { // content during the run. Upon exit that directory is deleted. if (appcache_dir_.CreateUniqueTempDir()) SimpleAppCacheSystem::InitializeOnUIThread(appcache_dir_.path()); + +#if defined(OS_WIN) + // Ensure we pick up the default theme engine. + setThemeEngine(NULL); +#endif } ~TestShellWebKitInit() { @@ -84,7 +94,8 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { return false; } - virtual bool getFileSize(const WebKit::WebString& path, long long& result) { + virtual bool getFileSize(const WebKit::WebString& path, + long long& result) { return file_util::GetFileSize( FilePath(webkit_glue::WebStringToFilePathString(path)), reinterpret_cast<int64*>(&result)); @@ -158,12 +169,26 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { return SimpleAppCacheSystem::CreateApplicationCacheHost(client); } +#if defined(OS_WIN) + void setThemeEngine(WebKit::WebThemeEngine* engine) { + active_theme_engine_ = engine ? engine : WebKitClientImpl::themeEngine(); + } + + virtual WebKit::WebThemeEngine *themeEngine() { + return active_theme_engine_; + } +#endif + private: webkit_glue::SimpleWebMimeRegistryImpl mime_registry_; MockWebClipboardImpl mock_clipboard_; webkit_glue::WebClipboardImpl real_clipboard_; ScopedTempDir appcache_dir_; SimpleAppCacheSystem appcache_system_; + +#if defined(OS_WIN) + WebKit::WebThemeEngine* active_theme_engine_; +#endif }; #endif // WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBKIT_INIT_H_ diff --git a/webkit/tools/test_shell/test_shell_webthemecontrol.cc b/webkit/tools/test_shell/test_shell_webthemecontrol.cc new file mode 100644 index 0000000..1d806f3 --- /dev/null +++ b/webkit/tools/test_shell/test_shell_webthemecontrol.cc @@ -0,0 +1,395 @@ +// Copyright (c) 2009 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. + +// This file implements a simple generic version of the WebKitThemeEngine, +// which is used to draw all the native controls on a web page. We use this +// file when running in layout test mode in order to remove any +// platform-specific rendering differences due to themes, colors, etc. +// + +#include "webkit/tools/test_shell/test_shell_webthemecontrol.h" + +#include "base/logging.h" +#include "skia/ext/platform_canvas.h" +#include "skia/ext/skia_utils_win.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkPath.h" + +namespace TestShellWebTheme { + +const SkColor kEdgeColor = SkColorSetRGB(0, 0, 0); +const SkColor kReadOnlyColor = SkColorSetRGB(0xe9, 0xc2, 0xa6); +const SkColor kFgColor = SkColorSetRGB(0, 0, 0); + +const SkColor kBgColors[] = { + SkColorSetRGB(0, 0, 0), // Unknown + SkColorSetRGB(0xc9, 0xc9, 0xc9), // Disabled + SkColorSetRGB(0xf3, 0xe0, 0xd0), // Readonly + SkColorSetRGB(0x89, 0xc4, 0xff), // Normal + SkColorSetRGB(0x43, 0xf9, 0xff), // Hot + SkColorSetRGB(0x20, 0xf6, 0xcc), // Focused + SkColorSetRGB(0x00, 0xf3, 0xac), // Hover + SkColorSetRGB(0xa9, 0xff, 0x12) // Pressed +}; + +Control::Control(skia::PlatformCanvas *canvas, const SkIRect &irect, + Type ctype, State cstate) + : canvas_(canvas), + irect_(irect), + type_(ctype), + state_(cstate), + left_(irect.fLeft), + right_(irect.fRight), + top_(irect.fTop), + bottom_(irect.fBottom), + height_(irect.height()), + width_(irect.width()), + edge_color_(kEdgeColor), + bg_color_(kBgColors[cstate]), + fg_color_(kFgColor) { +} + +Control::~Control() { +} + +void Control::box(const SkIRect &rect, SkColor fill_color) { + SkPaint paint; + + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(fill_color); + canvas_->drawIRect(rect, paint); + + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawIRect(rect, paint); +} + +void Control::line(int x0, int y0, int x1, int y1, SkColor color) { + SkPaint paint; + paint.setColor(color); + canvas_->drawLine(SkIntToScalar(x0), SkIntToScalar(y0), + SkIntToScalar(x1), SkIntToScalar(y1), + paint); +} + +void Control::triangle(int x0, int y0, + int x1, int y1, + int x2, int y2, + SkColor color) { + SkPath path; + SkPaint paint; + + paint.setColor(color); + paint.setStyle(SkPaint::kFill_Style); + path.incReserve(4); + path.moveTo(SkIntToScalar(x0), SkIntToScalar(y0)); + path.lineTo(SkIntToScalar(x1), SkIntToScalar(y1)); + path.lineTo(SkIntToScalar(x2), SkIntToScalar(y2)); + path.close(); + canvas_->drawPath(path, paint); + + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawPath(path, paint); +} + +void Control::roundRect(SkColor color) { + SkRect rect; + SkScalar radius = SkIntToScalar(5); + SkPaint paint; + + rect.set(irect_); + paint.setColor(color); + paint.setStyle(SkPaint::kFill_Style); + canvas_->drawRoundRect(rect, radius, radius, paint); + + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawRoundRect(rect, radius, radius, paint); +} + +void Control::oval(SkColor color) { + SkRect rect; + SkPaint paint; + + rect.set(irect_); + paint.setColor(color); + paint.setStyle(SkPaint::kFill_Style); + canvas_->drawOval(rect, paint); + + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawOval(rect, paint); +} + +void Control::circle(SkScalar radius, SkColor color) { + SkScalar cy = SkIntToScalar(top_ + height_ / 2); + SkScalar cx = SkIntToScalar(left_ + width_ / 2); + SkPaint paint; + + paint.setColor(color); + paint.setStyle(SkPaint::kFill_Style); + canvas_->drawCircle(cx, cy, radius, paint); + + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawCircle(cx, cy, radius, paint); +} + +void Control::nested_boxes(int indent_left, int indent_top, + int indent_right, int indent_bottom, + SkColor outer_color, SkColor inner_color) { + SkIRect lirect; + box(irect_, outer_color); + lirect.set(irect_.fLeft + indent_left, irect_.fTop + indent_top, + irect_.fRight - indent_right, irect_.fBottom - indent_bottom); + box(lirect, inner_color); +} + + +void Control::markState() { + // The horizontal lines in a read only control are spaced by this amount. + const int kReadOnlyLineOffset = 5; + + // The length of a triangle side for the corner marks. + const int kTriangleSize = 5; + + switch (state_) { + case kUnknown_State: // FALLTHROUGH + case kDisabled_State: // FALLTHROUGH + case kNormal_State: + // Don't visually mark these states (color is enough). + break; + case kReadOnly_State: + // Drawing lines across the control. + for (int i = top_ + kReadOnlyLineOffset; i < bottom_ ; + i += kReadOnlyLineOffset) { + line(left_ + 1, i, right_ - 1, i, kReadOnlyColor); + } + break; + case kHot_State: + // Draw a triangle in the upper left corner of the control. + triangle(left_, top_, + left_ + kTriangleSize, top_, + left_, top_ + kTriangleSize, edge_color_); + break; + case kHover_State: + // Draw a triangle in the upper right corner of the control. + triangle(right_, top_, + right_, top_ + kTriangleSize, + right_ - kTriangleSize, top_, edge_color_); + break; + case kFocused_State: + // Draw a triangle in the bottom right corner of the control. + triangle(right_, bottom_, + right_ - kTriangleSize, bottom_, + right_, bottom_ - kTriangleSize, edge_color_); + break; + case kPressed_State: + // Draw a triangle in the bottom left corner of the control. + triangle(left_, bottom_, + left_, bottom_ - kTriangleSize, + left_ + kTriangleSize, bottom_, edge_color_); + break; + default: + NOTREACHED(); + break; + } +} + +void Control::draw() { + int half_width = width_ / 2; + int half_height = height_ / 2; + int quarter_width = width_ / 4; + int quarter_height = height_ / 4; + + // Indent amounts for the check in a checkbox or radio button. + const int kCheckIndent = 3; + + // Indent amounts for short and long sides of the scrollbar notches. + const int kNotchLongOffset = 1; + const int kNotchShortOffset = 4; + const int kNoOffset = 0; + int short_offset; + int long_offset; + + // Indent amounts for the short and long sides of a scroll thumb box. + const int kThumbLongIndent = 0; + const int kThumbShortIndent = 2; + + // Indents for the crosshatch on a scroll grip. + const int kGripLongIndent = 3; + const int kGripShortIndent = 5; + + // Indents for the the slider track. + const int kSliderIndent = 2; + + canvas_->beginPlatformPaint(); + switch (type_) { + case kUnknown_Type: + NOTREACHED(); + break; + case kTextField_Type: + // We render this by hand outside of this function. + NOTREACHED(); + break; + case kPushButton_Type: + // push buttons render as a rounded rectangle + roundRect(bg_color_); + break; + case kUncheckedBox_Type: + // Unchecked boxes are simply plain boxes. + box(irect_, bg_color_); + break; + case kCheckedBox_Type: + nested_boxes(kCheckIndent, kCheckIndent, kCheckIndent, kCheckIndent, + bg_color_, fg_color_); + break; + case kUncheckedRadio_Type: + circle(SkIntToScalar(half_height), bg_color_); + break; + case kCheckedRadio_Type: + circle(SkIntToScalar(half_height), bg_color_); + circle(SkIntToScalar(half_height - kCheckIndent), fg_color_); + break; + case kHorizontalScrollTrackBack_Type: + // Draw a box with a notch at the left. + long_offset = half_height - kNotchLongOffset; + short_offset = width_ - kNotchShortOffset; + nested_boxes(kNoOffset, long_offset, short_offset, long_offset, + bg_color_, edge_color_); + break; + case kHorizontalScrollTrackForward_Type: + // Draw a box with a notch at the right. + long_offset = half_height - kNotchLongOffset; + short_offset = width_ - kNotchShortOffset; + nested_boxes(short_offset, long_offset, kNoOffset, long_offset, + bg_color_, fg_color_); + break; + case kVerticalScrollTrackBack_Type: + // Draw a box with a notch at the top. + long_offset = half_width - kNotchLongOffset; + short_offset = height_ - kNotchShortOffset; + nested_boxes(long_offset, kNoOffset, long_offset, short_offset, + bg_color_, fg_color_); + break; + case kVerticalScrollTrackForward_Type: + // Draw a box with a notch at the bottom. + long_offset = half_width - kNotchLongOffset; + short_offset = height_ - kNotchShortOffset; + nested_boxes(long_offset, short_offset, long_offset, kNoOffset, + bg_color_, fg_color_); + break; + case kHorizontalScrollThumb_Type: + // Draw a narrower box on top of the outside box. + nested_boxes(kThumbLongIndent, kThumbShortIndent, kThumbLongIndent, + kThumbShortIndent, bg_color_, bg_color_); + break; + case kVerticalScrollThumb_Type: + // Draw a shorter box on top of the outside box. + nested_boxes(kThumbShortIndent, kThumbLongIndent, kThumbShortIndent, + kThumbLongIndent, bg_color_, bg_color_); + break; + case kHorizontalSliderThumb_Type: + // Slider thumbs are ovals. + oval(bg_color_); + break; + case kHorizontalScrollGrip_Type: + // Draw a horizontal crosshatch for the grip. + long_offset = half_width - kGripLongIndent; + line(left_ + kGripLongIndent, top_ + half_height, + right_ - kGripLongIndent, top_ + half_height, fg_color_); + line(left_ + long_offset, top_ + kGripShortIndent, + left_ + long_offset, bottom_ - kGripShortIndent, fg_color_); + line(right_ - long_offset, top_ + kGripShortIndent, + right_ - long_offset, bottom_ - kGripShortIndent, fg_color_); + break; + case kVerticalScrollGrip_Type: + // Draw a vertical crosshatch for the grip. + long_offset = half_height - kGripLongIndent; + line(left_ + half_width, top_ + kGripLongIndent, + left_ + half_width, bottom_ - kGripLongIndent, fg_color_); + line(left_ + kGripShortIndent, top_ + long_offset, + right_ - kGripShortIndent, top_ + long_offset, fg_color_); + line(left_ + kGripShortIndent, bottom_ - long_offset, + right_ - kGripShortIndent, bottom_ - long_offset, fg_color_); + break; + case kLeftArrow_Type: + // Draw a left arrow inside a box. + box(irect_, bg_color_); + triangle(right_ - quarter_width, top_ + quarter_height, + right_ - quarter_width, bottom_ - quarter_height, + left_ + quarter_width, top_ + half_height, fg_color_); + break; + case kRightArrow_Type: + // Draw a left arrow inside a box. + box(irect_, bg_color_); + triangle(left_ + quarter_width, top_ + quarter_height, + right_ - quarter_width, top_ + half_height, + left_ + quarter_width, bottom_ - quarter_height, fg_color_); + break; + case kUpArrow_Type: + // Draw an up arrow inside a box. + box(irect_, bg_color_); + triangle(left_ + quarter_width, bottom_ - quarter_height, + left_ + half_width, top_ + quarter_height, + right_ - quarter_width, bottom_ - quarter_height, fg_color_); + break; + case kDownArrow_Type: + // Draw a down arrow inside a box. + box(irect_, bg_color_); + triangle(left_ + quarter_width, top_ + quarter_height, + right_ - quarter_width, top_ + quarter_height, + left_ + half_width, bottom_ - quarter_height, fg_color_); + break; + case kHorizontalSliderTrack_Type: + // Draw a narrow rect for the track plus box hatches on the ends. + SkIRect lirect; + lirect = irect_; + lirect.inset(kNoOffset, half_height - kSliderIndent); + box(lirect, bg_color_); + line(left_, top_, left_, bottom_, edge_color_); + line(right_, top_, right_, bottom_, edge_color_); + break; + case kDropDownButton_Type: + // Draw a box with a big down arrow on top. + box(irect_, bg_color_); + triangle(left_ + quarter_width, top_, + right_ - quarter_width, top_, + left_ + half_width, bottom_, fg_color_); + break; + default: + NOTREACHED(); + break; + } + + markState(); + canvas_->endPlatformPaint(); +} + +// Because rendering a text field is dependent on input +// parameters the other controls don't have, we render it directly +// rather than trying to overcomplicate draw() further. +void Control::drawTextField(bool draw_edges, bool fill_content_area, + SkColor color) { + SkPaint paint; + + canvas_->beginPlatformPaint(); + if (fill_content_area) { + paint.setColor(color); + paint.setStyle(SkPaint::kFill_Style); + canvas_->drawIRect(irect_, paint); + } + if (draw_edges) { + paint.setColor(edge_color_); + paint.setStyle(SkPaint::kStroke_Style); + canvas_->drawIRect(irect_, paint); + } + + markState(); + canvas_->endPlatformPaint(); +} + +} // namespace TestShellWebTheme + diff --git a/webkit/tools/test_shell/test_shell_webthemecontrol.h b/webkit/tools/test_shell/test_shell_webthemecontrol.h new file mode 100644 index 0000000..bb439af --- /dev/null +++ b/webkit/tools/test_shell/test_shell_webthemecontrol.h @@ -0,0 +1,170 @@ +// Copyright (c) 2009 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. + +// TestShellWebTheme::Control implements the generic rendering of controls +// needed by TestShellWebTheme::Engine. See the comments in that class +// header file for why this class is needed and used. +// +// This class implements a generic set of widgets using Skia. The widgets +// are optimized for testability, not a pleasing appearance. +// + +#ifndef WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMECONTROL_H_ +#define WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMECONTROL_H_ + +#include "base/basictypes.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkRect.h" + +namespace TestShellWebTheme { + +class Control { + public: + // This list of states mostly mirrors the list in + // third_party/WebKit/WebCore/platform/ThemeTypes.h but is maintained + // separately since that isn't public and also to minimize dependencies. + // Note that the WebKit ThemeTypes seem to imply that a control can be + // in multiple states simultaneously but WebThemeEngine only allows for + // a single state at a time. + // + // Some definitions for the various states: + // Disabled - indicates that a control can't be modified or selected + // (corresponds to HTML 'disabled' attribute) + // ReadOnly - indicates that a control can't be modified but can be + // selected + // Normal - the normal state of control on the page when it isn't + // focused or otherwise active + // Hot - when the mouse is hovering over a part of the control, + // all the other parts are considered "hot" + // Hover - when the mouse is directly over a control (the CSS + // :hover pseudo-class) + // Focused - when the control has the keyboard focus + // Pressed - when the control is being triggered (by a mousedown or + // a key event). + enum State { + kUnknown_State = 0, + kDisabled_State, + kReadOnly_State, + kNormal_State, + kHot_State, + kHover_State, + kFocused_State, + kPressed_State + }; + + // This list of types mostly mirrors the list in + // third_party/WebKit/WebCore/platform/ThemeTypes.h but is maintained + // separately since that isn't public and also to minimize dependencies. + // + // Note that what the user might think of as a single control can be + // made up of multiple parts. For example, a single scroll bar contains + // six clickable parts - two arrows, the "thumb" indicating the current + // position on the bar, the other two parts of the bar (before and after + // the thumb) and the "gripper" on the thumb itself. + // + enum Type { + kUnknown_Type = 0, + kTextField_Type, + kPushButton_Type, + kUncheckedBox_Type, + kCheckedBox_Type, + kUncheckedRadio_Type, + kCheckedRadio_Type, + kHorizontalScrollTrackBack_Type, + kHorizontalScrollTrackForward_Type, + kHorizontalScrollThumb_Type, + kHorizontalScrollGrip_Type, + kVerticalScrollTrackBack_Type, + kVerticalScrollTrackForward_Type, + kVerticalScrollThumb_Type, + kVerticalScrollGrip_Type, + kLeftArrow_Type, + kRightArrow_Type, + kUpArrow_Type, + kDownArrow_Type, + kHorizontalSliderTrack_Type, + kHorizontalSliderThumb_Type, + kDropDownButton_Type + }; + + // canvas is the canvas to draw onto, and rect gives the size of the + // control. ctype and cstate specify the type and state of the control. + Control(skia::PlatformCanvas *canvas, const SkIRect &rect, + Type ctype, State cstate); + ~Control(); + + // Draws the control. + void draw(); + + // Use this for TextField controls instead, because the logic + // for drawing them is dependent on what WebKit tells us to do. + // If draw_edges is true, draw an edge around the control. If + // fill_content_area is true, fill the content area with the given color. + void drawTextField(bool draw_edges, bool fill_content_area, SkColor color); + + private: + // Draws a box of size specified by irect, filled with the given color. + // The box will have a border drawn in the default edge color. + void box(const SkIRect &irect, SkColor color); + + + // Draws a triangle of size specified by the three pairs of coordinates, + // filled with the given color. The box will have an edge drawn in the + // default edge color. + void triangle(int x0, int y0, int x1, int y1, int x2, int y2, + SkColor color); + + // Draws a rectangle the size of the control with rounded corners, filled + // with the specified color (and with a border in the default edge color). + void roundRect(SkColor color); + + // Draws an oval the size of the control, filled with the specified color + // and with a border in the default edge color. + void oval(SkColor color); + + // Draws a circle centered in the control with the specified radius, + // filled with the specified color, and with a border draw in the + // default edge color. + void circle(SkScalar radius, SkColor color); + + // Draws a box the size of the control, filled with the outer_color and + // with a border in the default edge color, and then draws another box + // indented on all four sides by the specified amounts, filled with the + // inner color and with a border in the default edge color. + void nested_boxes(int indent_left, int indent_top, + int indent_right, int indent_bottom, + SkColor outer_color, SkColor inner_color); + + // Draws a line between the two points in the given color. + void line(int x0, int y0, int x1, int y1, SkColor color); + + // Draws a distinctive mark on the control for each state, so that the + // state of the control can be determined without needing to know which + // color is which. + void markState(); + + skia::PlatformCanvas* canvas_; + const SkIRect irect_; + const Type type_; + const State state_; + const SkColor edge_color_; + const SkColor bg_color_; + const SkColor fg_color_; + + // The following are convenience accessors for irect_. + const int left_; + const int right_; + const int top_; + const int bottom_; + const int width_; + const int height_; + + DISALLOW_COPY_AND_ASSIGN(Control); +}; + +} // namespace TestShellWebTheme + +#endif // WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMECONTROL_H_ + diff --git a/webkit/tools/test_shell/test_shell_webthemeengine.cc b/webkit/tools/test_shell/test_shell_webthemeengine.cc new file mode 100644 index 0000000..95c7d75 --- /dev/null +++ b/webkit/tools/test_shell/test_shell_webthemeengine.cc @@ -0,0 +1,536 @@ +// Copyright (c) 2009 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. + +// This file implements a simple generic version of the WebKitThemeEngine, +// Since WebThemeEngine is unfortunately defined in terms of the Windows +// Theme parameters and values, we need to translate all the values into +// generic equivalents that we can more easily understand. This file does +// that translation (acting as a Facade design pattern) and then uses +// TestShellWebTheme::Control for the actual rendering of the widgets. +// + +#include "webkit/tools/test_shell/test_shell_webthemeengine.h" + +// Although all this code is generic, we include these headers +// to pull in the Windows #defines for the parts and states of +// the controls. +#include <vsstyle.h> +#include <windows.h> + +#include "base/logging.h" +#include "webkit/api/public/WebCanvas.h" +#include "webkit/api/public/WebRect.h" +#include "webkit/tools/test_shell/test_shell_webthemecontrol.h" +#include "third_party/skia/include/core/SkRect.h" + +#ifndef CHECK_EQ +#define CHECK_EQ(a, b) CHECK((a) == (b)) +#endif + +// We define this for clarity, although there really should be a DFCS_NORMAL +// in winuser.h. +namespace { + const int kDFCSNormal = 0x0000; +} + +using WebKit::WebCanvas; +using WebKit::WebColor; +using WebKit::WebRect; + +namespace TestShellWebTheme { + +SkIRect webRectToSkIRect(const WebRect &web_rect) { + SkIRect irect; + irect.set(web_rect.x, web_rect.y, web_rect.x + web_rect.width, + web_rect.y + web_rect.height); + return irect; +} + +void drawControl(WebCanvas *canvas, const WebRect &rect, Control::Type ctype, + Control::State cstate) { + Control control(canvas, webRectToSkIRect(rect), ctype, cstate); + control.draw(); +} + +void drawTextField(WebCanvas *canvas, const WebRect &rect, + Control::Type ctype, Control::State cstate, + bool draw_edges, bool fill_content_area, WebColor color) { + Control control(canvas, webRectToSkIRect(rect), ctype, cstate); + control.drawTextField(draw_edges, fill_content_area, color); +} + +void Engine::paintButton(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + if (part == BP_CHECKBOX) { + switch (state) { + case CBS_UNCHECKEDNORMAL: + CHECK_EQ(classic_state, kDFCSNormal); + ctype = Control::kUncheckedBox_Type; + cstate = Control::kNormal_State; + break; + case CBS_UNCHECKEDHOT: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_HOT); + ctype = Control::kUncheckedBox_Type; + cstate = Control::kHot_State; + break; + case CBS_UNCHECKEDPRESSED: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_PUSHED); + ctype = Control::kUncheckedBox_Type; + cstate = Control::kPressed_State; + break; + case CBS_UNCHECKEDDISABLED: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_INACTIVE); + ctype = Control::kUncheckedBox_Type; + cstate = Control::kDisabled_State; + break; + case CBS_CHECKEDNORMAL: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_CHECKED); + ctype = Control::kCheckedBox_Type; + cstate = Control::kNormal_State; + break; + case CBS_CHECKEDHOT: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_HOT); + ctype = Control::kCheckedBox_Type; + cstate = Control::kHot_State; + break; + case CBS_CHECKEDPRESSED: + CHECK_EQ(classic_state, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_PUSHED); + ctype = Control::kCheckedBox_Type; + cstate = Control::kPressed_State; + break; + case CBS_CHECKEDDISABLED: + CHECK_EQ(classic_state, + DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_INACTIVE); + ctype = Control::kCheckedBox_Type; + cstate = Control::kDisabled_State; + break; + default: + NOTREACHED(); + break; + } + } else if (BP_RADIOBUTTON == part) { + switch (state) { + case RBS_UNCHECKEDNORMAL: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO); + ctype = Control::kUncheckedRadio_Type; + cstate = Control::kNormal_State; + break; + case RBS_UNCHECKEDHOT: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_HOT); + ctype = Control::kUncheckedRadio_Type; + cstate = Control::kHot_State; + break; + case RBS_UNCHECKEDPRESSED: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_PUSHED); + ctype = Control::kUncheckedRadio_Type; + cstate = Control::kPressed_State; + break; + case RBS_UNCHECKEDDISABLED: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_INACTIVE); + ctype = Control::kUncheckedRadio_Type; + cstate = Control::kDisabled_State; + break; + case RBS_CHECKEDNORMAL: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_CHECKED); + ctype = Control::kCheckedRadio_Type; + cstate = Control::kNormal_State; + break; + case RBS_CHECKEDHOT: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_CHECKED | DFCS_HOT); + ctype = Control::kCheckedRadio_Type; + cstate = Control::kHot_State; + break; + case RBS_CHECKEDPRESSED: + CHECK_EQ(classic_state, DFCS_BUTTONRADIO | DFCS_CHECKED | DFCS_PUSHED); + ctype = Control::kCheckedRadio_Type; + cstate = Control::kPressed_State; + break; + case RBS_CHECKEDDISABLED: + CHECK_EQ(classic_state, + DFCS_BUTTONRADIO | DFCS_CHECKED | DFCS_INACTIVE); + ctype = Control::kCheckedRadio_Type; + cstate = Control::kDisabled_State; + break; + default: + NOTREACHED(); + break; + } + } else if (BP_PUSHBUTTON == part) { + switch (state) { + case PBS_NORMAL: + CHECK_EQ(classic_state, DFCS_BUTTONPUSH); + ctype = Control::kPushButton_Type; + cstate = Control::kNormal_State; + break; + case PBS_HOT: + CHECK_EQ(classic_state, DFCS_BUTTONPUSH | DFCS_HOT); + ctype = Control::kPushButton_Type; + cstate = Control::kHot_State; + break; + case PBS_PRESSED: + CHECK_EQ(classic_state, DFCS_BUTTONPUSH | DFCS_PUSHED); + ctype = Control::kPushButton_Type; + cstate = Control::kPressed_State; + break; + case PBS_DISABLED: + CHECK_EQ(classic_state, DFCS_BUTTONPUSH | DFCS_INACTIVE); + ctype = Control::kPushButton_Type; + cstate = Control::kDisabled_State; + break; + case PBS_DEFAULTED: + CHECK_EQ(classic_state, DFCS_BUTTONPUSH); + ctype = Control::kPushButton_Type; + cstate = Control::kFocused_State; + break; + default: + NOTREACHED(); + break; + } + } else { + NOTREACHED(); + } + + drawControl(canvas, rect, ctype, cstate); +} + + +void Engine::paintMenuList(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + if (CP_DROPDOWNBUTTON == part) { + ctype = Control::kDropDownButton_Type; + switch (state) { + case CBXS_NORMAL: + CHECK_EQ(classic_state, DFCS_MENUARROW); + cstate = Control::kNormal_State; + break; + case CBXS_HOT: + CHECK_EQ(classic_state, DFCS_MENUARROW | DFCS_HOT); + cstate = Control::kHover_State; + break; + case CBXS_PRESSED: + CHECK_EQ(classic_state, DFCS_MENUARROW | DFCS_PUSHED); + cstate = Control::kPressed_State; + break; + case CBXS_DISABLED: + CHECK_EQ(classic_state, DFCS_MENUARROW | DFCS_INACTIVE); + cstate = Control::kDisabled_State; + break; + default: + CHECK(false); + break; + } + } else { + CHECK(false); + } + + drawControl(canvas, rect, ctype, cstate); +} + +void Engine::paintScrollbarArrow(WebCanvas* canvas, int state, + int classic_state, const WebRect& rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + switch (state) { + case ABS_UPNORMAL: + CHECK_EQ(classic_state, DFCS_SCROLLUP); + ctype = Control::kUpArrow_Type; + cstate = Control::kNormal_State; + break; + case ABS_DOWNNORMAL: + CHECK_EQ(classic_state, DFCS_SCROLLDOWN); + ctype = Control::kDownArrow_Type; + cstate = Control::kNormal_State; + break; + case ABS_LEFTNORMAL: + CHECK_EQ(classic_state, DFCS_SCROLLLEFT); + ctype = Control::kLeftArrow_Type; + cstate = Control::kNormal_State; + break; + case ABS_RIGHTNORMAL: + CHECK_EQ(classic_state, DFCS_SCROLLRIGHT); + ctype = Control::kRightArrow_Type; + cstate = Control::kNormal_State; + break; + case ABS_UPHOT: + CHECK_EQ(classic_state, DFCS_SCROLLUP | DFCS_HOT); + ctype = Control::kUpArrow_Type; + cstate = Control::kHot_State; + break; + case ABS_DOWNHOT: + CHECK_EQ(classic_state, DFCS_SCROLLDOWN | DFCS_HOT); + ctype = Control::kDownArrow_Type; + cstate = Control::kHot_State; + break; + case ABS_LEFTHOT: + CHECK_EQ(classic_state, DFCS_SCROLLLEFT | DFCS_HOT); + ctype = Control::kLeftArrow_Type; + cstate = Control::kHot_State; + break; + case ABS_RIGHTHOT: + CHECK_EQ(classic_state, DFCS_SCROLLRIGHT | DFCS_HOT); + ctype = Control::kRightArrow_Type; + cstate = Control::kHot_State; + break; + case ABS_UPHOVER: + CHECK_EQ(classic_state, DFCS_SCROLLUP); + ctype = Control::kUpArrow_Type; + cstate = Control::kHover_State; + break; + case ABS_DOWNHOVER: + CHECK_EQ(classic_state, DFCS_SCROLLDOWN); + ctype = Control::kDownArrow_Type; + cstate = Control::kHover_State; + break; + case ABS_LEFTHOVER: + CHECK_EQ(classic_state, DFCS_SCROLLLEFT); + ctype = Control::kLeftArrow_Type; + cstate = Control::kHover_State; + break; + case ABS_RIGHTHOVER: + CHECK_EQ(classic_state, DFCS_SCROLLRIGHT); + ctype = Control::kRightArrow_Type; + cstate = Control::kHover_State; + break; + case ABS_UPPRESSED: + CHECK_EQ(classic_state, DFCS_SCROLLUP | DFCS_PUSHED | DFCS_FLAT); + ctype = Control::kUpArrow_Type; + cstate = Control::kPressed_State; + break; + case ABS_DOWNPRESSED: + CHECK_EQ(classic_state, DFCS_SCROLLDOWN | DFCS_PUSHED | DFCS_FLAT); + ctype = Control::kDownArrow_Type; + cstate = Control::kPressed_State; + break; + case ABS_LEFTPRESSED: + CHECK_EQ(classic_state, DFCS_SCROLLLEFT | DFCS_PUSHED | DFCS_FLAT); + ctype = Control::kLeftArrow_Type; + cstate = Control::kPressed_State; + break; + case ABS_RIGHTPRESSED: + CHECK_EQ(classic_state, DFCS_SCROLLRIGHT | DFCS_PUSHED | DFCS_FLAT); + ctype = Control::kRightArrow_Type; + cstate = Control::kPressed_State; + break; + case ABS_UPDISABLED: + CHECK_EQ(classic_state, DFCS_SCROLLUP | DFCS_INACTIVE); + ctype = Control::kUpArrow_Type; + cstate = Control::kDisabled_State; + break; + case ABS_DOWNDISABLED: + CHECK_EQ(classic_state, DFCS_SCROLLDOWN | DFCS_INACTIVE); + ctype = Control::kDownArrow_Type; + cstate = Control::kDisabled_State; + break; + case ABS_LEFTDISABLED: + CHECK_EQ(classic_state, DFCS_SCROLLLEFT | DFCS_INACTIVE); + ctype = Control::kLeftArrow_Type; + cstate = Control::kDisabled_State; + break; + case ABS_RIGHTDISABLED: + CHECK_EQ(classic_state, DFCS_SCROLLRIGHT | DFCS_INACTIVE); + ctype = Control::kRightArrow_Type; + cstate = Control::kDisabled_State; + break; + default: + NOTREACHED(); + break; + } + + drawControl(canvas, rect, ctype, cstate); +} + +void Engine::paintScrollbarThumb(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + switch (part) { + case SBP_THUMBBTNHORZ: + ctype = Control::kHorizontalScrollThumb_Type; + break; + case SBP_THUMBBTNVERT: + ctype = Control::kVerticalScrollThumb_Type; + break; + case SBP_GRIPPERHORZ: + ctype = Control::kHorizontalScrollGrip_Type; + break; + case SBP_GRIPPERVERT: + ctype = Control::kVerticalScrollGrip_Type; + break; + default: + NOTREACHED(); + break; + } + + switch (state) { + case SCRBS_NORMAL: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kNormal_State; + break; + case SCRBS_HOT: + CHECK_EQ(classic_state, DFCS_HOT); + cstate = Control::kHot_State; + break; + case SCRBS_HOVER: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kHover_State; + break; + case SCRBS_PRESSED: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kPressed_State; + break; + case SCRBS_DISABLED: + NOTREACHED(); // This should never happen in practice. + break; + default: + NOTREACHED(); + break; + } + + drawControl(canvas, rect, ctype, cstate); +} + +void Engine::paintScrollbarTrack(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect, + const WebRect& align_rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + switch (part) { + case SBP_UPPERTRACKHORZ: + ctype = Control::kHorizontalScrollTrackBack_Type; + break; + case SBP_LOWERTRACKHORZ: + ctype = Control::kHorizontalScrollTrackForward_Type; + break; + case SBP_UPPERTRACKVERT: + ctype = Control::kVerticalScrollTrackBack_Type; + break; + case SBP_LOWERTRACKVERT: + ctype = Control::kVerticalScrollTrackForward_Type; + break; + default: + NOTREACHED(); + break; + } + + switch (state) { + case SCRBS_NORMAL: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kNormal_State; + break; + case SCRBS_HOT: + NOTREACHED(); // This should never happen in practice. + break; + case SCRBS_HOVER: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kHover_State; + break; + case SCRBS_PRESSED: + NOTREACHED(); // This should never happen in practice. + break; + case SCRBS_DISABLED: + CHECK_EQ(classic_state, DFCS_INACTIVE); + cstate = Control::kDisabled_State; + break; + default: + CHECK(false); + break; + } + + drawControl(canvas, rect, ctype, cstate); +} + +void Engine::paintTextField(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect, + WebColor color, bool fill_content_area, + bool draw_edges) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + CHECK_EQ(EP_EDITTEXT, part); + ctype = Control::kTextField_Type; + + switch (state) { + case ETS_NORMAL: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kNormal_State; + break; + case ETS_HOT: + CHECK_EQ(classic_state, DFCS_HOT); + cstate = Control::kHot_State; + break; + case ETS_DISABLED: + CHECK_EQ(classic_state, DFCS_INACTIVE); + cstate = Control::kDisabled_State; + break; + case ETS_SELECTED: + CHECK_EQ(classic_state, DFCS_PUSHED); + cstate = Control::kPressed_State; + break; + case ETS_FOCUSED: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kFocused_State; + break; + case ETS_READONLY: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kReadOnly_State; + break; + default: + NOTREACHED(); + break; + } + + drawTextField(canvas, rect, ctype, cstate, draw_edges, fill_content_area, + color); +} + +void Engine::paintTrackbar(WebCanvas* canvas, int part, int state, + int classic_state, const WebRect& rect) { + Control::Type ctype = Control::kUnknown_Type; + Control::State cstate = Control::kUnknown_State; + + if (TKP_THUMBBOTTOM == part) { + ctype = Control::kHorizontalSliderThumb_Type; + switch (state) { + case TUS_NORMAL: + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kNormal_State; + break; + case TUS_HOT: + CHECK_EQ(classic_state, DFCS_HOT); + cstate = Control::kHot_State; + break; + case TUS_DISABLED: + CHECK_EQ(classic_state, DFCS_INACTIVE); + cstate = Control::kDisabled_State; + break; + case TUS_PRESSED: + CHECK_EQ(classic_state, DFCS_PUSHED); + cstate = Control::kPressed_State; + break; + default: + NOTREACHED(); + break; + } + } else if (TKP_TRACK == part) { + ctype = Control::kHorizontalSliderTrack_Type; + CHECK_EQ(part, TUS_NORMAL); + CHECK_EQ(classic_state, kDFCSNormal); + cstate = Control::kNormal_State; + } else { + NOTREACHED(); + } + + drawControl(canvas, rect, ctype, cstate); +} + +} // namespace TestShellWebTheme diff --git a/webkit/tools/test_shell/test_shell_webthemeengine.h b/webkit/tools/test_shell/test_shell_webthemeengine.h new file mode 100644 index 0000000..c4b1fce --- /dev/null +++ b/webkit/tools/test_shell/test_shell_webthemeengine.h @@ -0,0 +1,64 @@ +// Copyright (c) 2009 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. + +// TestShellWebTheme::Engine implements the WebThemeEngine +// API used by the Windows version of Chromium to render native form +// controls like checkboxes, radio buttons, and scroll bars. The normal +// implementation (native_theme) renders the controls using either the +// UXTheme theming engine present in XP, Vista, and Win 7, or the "classic" +// theme used if that theme is selected in the Desktop settings. +// Unfortunately, both of these themes render controls differently on the +// different versions of Windows. +// +// In order to ensure maximum consistency of baselines across the different +// Windows versions, we provide a simple implementation for test_shell here +// instead. These controls are actually platform-independent (they're rendered +// using Skia) and could be used on Linux and the Mac as well, should we +// choose to do so at some point. +// + +#ifndef WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMEENGINE_H_ +#define WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMEENGINE_H_ + +#include "base/basictypes.h" +#include "webkit/api/public/win/WebThemeEngine.h" + +namespace TestShellWebTheme { + +class Engine : public WebKit::WebThemeEngine { + public: + Engine() {} + + // WebThemeEngine methods: + virtual void paintButton( + WebKit::WebCanvas*, int part, int state, int classic_state, + const WebKit::WebRect&); + virtual void paintMenuList( + WebKit::WebCanvas*, int part, int state, int classic_state, + const WebKit::WebRect&); + virtual void paintScrollbarArrow( + WebKit::WebCanvas*, int state, int classic_state, + const WebKit::WebRect&); + virtual void paintScrollbarThumb( + WebKit::WebCanvas*, int part, int state, int classic_state, + const WebKit::WebRect&); + virtual void paintScrollbarTrack( + WebKit::WebCanvas*, int part, int state, int classic_state, + const WebKit::WebRect&, const WebKit::WebRect& align_rect); + virtual void paintTextField( + 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&); + + private: + DISALLOW_COPY_AND_ASSIGN(Engine); +}; + +} // namespace TestShellWebTheme + +#endif // WEBKIT_TOOLS_TEST_SHELL_TEST_SHELL_WEBTHEMEENGINE_H_ + |