summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorglen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-09 01:07:42 +0000
committerglen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-09 01:07:42 +0000
commit4a19063d1459a4c9c8c4c50ed86eb9048f69ea3f (patch)
tree69a1e9f78b3a5fa8b909cfab336826b09c44235f
parent5085ee0b4bfbe4625e63ee6975bb95702e13e0aa (diff)
downloadchromium_src-4a19063d1459a4c9c8c4c50ed86eb9048f69ea3f.zip
chromium_src-4a19063d1459a4c9c8c4c50ed86eb9048f69ea3f.tar.gz
chromium_src-4a19063d1459a4c9c8c4c50ed86eb9048f69ea3f.tar.bz2
This is the first pass at themes.
This CL is paired with http://codereview.chromium.org/67284 This CL (for commit purposes) includes http://codereview.chromium.org/67284 BUG=4463,11232,11233,11234,11235 Review URL: http://codereview.chromium.org/99030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15704 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/DEPS29
-rw-r--r--app/app.vcproj36
-rw-r--r--app/resource_bundle.cc46
-rw-r--r--app/resource_bundle.h16
-rw-r--r--app/theme_provider.h33
-rw-r--r--chrome/app/generated_resources.grd7
-rw-r--r--chrome/app/theme/app_top_center.pngbin81 -> 118 bytes
-rw-r--r--chrome/app/theme/app_top_left.pngbin107 -> 136 bytes
-rw-r--r--chrome/app/theme/app_top_right.pngbin110 -> 136 bytes
-rw-r--r--chrome/app/theme/back.pngbin1100 -> 974 bytes
-rw-r--r--chrome/app/theme/back_d.pngbin754 -> 837 bytes
-rw-r--r--chrome/app/theme/constrained_bottom_center.pngbin216 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_bottom_left_corner.pngbin170 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_bottom_right_corner.pngbin157 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_left_side.pngbin119 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_right_side.pngbin119 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_top_center.pngbin2449 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_top_left_corner.pngbin849 -> 0 bytes
-rw-r--r--chrome/app/theme/constrained_top_right_corner.pngbin864 -> 0 bytes
-rw-r--r--chrome/app/theme/content_bottom_center.pngbin113 -> 117 bytes
-rw-r--r--chrome/app/theme/content_bottom_left_corner.pngbin131 -> 129 bytes
-rw-r--r--chrome/app/theme/content_bottom_right_corner.pngbin131 -> 131 bytes
-rw-r--r--chrome/app/theme/content_left_side.pngbin114 -> 116 bytes
-rw-r--r--chrome/app/theme/content_right_side.pngbin114 -> 114 bytes
-rw-r--r--chrome/app/theme/content_top_center.pngbin176 -> 129 bytes
-rw-r--r--chrome/app/theme/content_top_left_corner.pngbin202 -> 167 bytes
-rw-r--r--chrome/app/theme/content_top_right_corner.pngbin212 -> 161 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_center.pngbin128 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_center_otr.pngbin128 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_left_corner.pngbin136 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_left_corner_otr.pngbin136 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_right_corner.pngbin125 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_bottom_right_corner_otr.pngbin125 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_left_side.pngbin118 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_left_side_otr.pngbin117 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_right_side.pngbin118 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_right_side_otr.pngbin114 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_center.pngbin1810 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_center_otr.pngbin1256 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_left_corner.pngbin511 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_left_corner_otr.pngbin468 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_right_corner.pngbin515 -> 0 bytes
-rw-r--r--chrome/app/theme/dewindow_top_right_corner_otr.pngbin428 -> 0 bytes
-rw-r--r--chrome/app/theme/forward.pngbin1067 -> 936 bytes
-rw-r--r--chrome/app/theme/forward_d.pngbin772 -> 808 bytes
-rw-r--r--chrome/app/theme/go.pngbin1004 -> 823 bytes
-rw-r--r--chrome/app/theme/locationbg.pngbin154 -> 174 bytes
-rw-r--r--chrome/app/theme/menu_chrome.pngbin1211 -> 1032 bytes
-rw-r--r--chrome/app/theme/menu_page.pngbin1033 -> 846 bytes
-rw-r--r--chrome/app/theme/notused.pngbin0 -> 299 bytes
-rw-r--r--chrome/app/theme/ntp_background.pngbin0 -> 1885 bytes
-rw-r--r--chrome/app/theme/reload.pngbin1470 -> 1345 bytes
-rw-r--r--chrome/app/theme/reload_d.pngbin1110 -> 1204 bytes
-rw-r--r--chrome/app/theme/star.pngbin1405 -> 1276 bytes
-rw-r--r--chrome/app/theme/star_d.pngbin1094 -> 1142 bytes
-rw-r--r--chrome/app/theme/starred.pngbin1405 -> 1283 bytes
-rw-r--r--chrome/app/theme/stop.pngbin1157 -> 1003 bytes
-rw-r--r--chrome/app/theme/tab_active_center.pngbin146 -> 133 bytes
-rw-r--r--chrome/app/theme/tab_active_left.pngbin633 -> 575 bytes
-rw-r--r--chrome/app/theme/tab_active_right.pngbin738 -> 434 bytes
-rw-r--r--chrome/app/theme/tab_hover_center.pngbin414 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_hover_left.pngbin608 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_hover_right.pngbin689 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_center.pngbin446 -> 171 bytes
-rw-r--r--chrome/app/theme/tab_inactive_center_otr.pngbin367 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_center_v.pngbin207 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_left.pngbin612 -> 551 bytes
-rw-r--r--chrome/app/theme/tab_inactive_left_otr.pngbin567 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_left_v.pngbin559 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_right.pngbin607 -> 391 bytes
-rw-r--r--chrome/app/theme/tab_inactive_right_otr.pngbin602 -> 0 bytes
-rw-r--r--chrome/app/theme/tab_inactive_right_v.pngbin502 -> 0 bytes
-rw-r--r--chrome/app/theme/theme_frame_default.pngbin0 -> 1113 bytes
-rw-r--r--chrome/app/theme/theme_frame_default_inactive.pngbin0 -> 773 bytes
-rw-r--r--chrome/app/theme/theme_frame_default_incognito.pngbin0 -> 887 bytes
-rw-r--r--chrome/app/theme/theme_frame_default_incognito_inactive.pngbin0 -> 855 bytes
-rw-r--r--chrome/app/theme/theme_resources.grd59
-rw-r--r--chrome/app/theme/theme_tab_background.pngbin0 -> 911 bytes
-rw-r--r--chrome/app/theme/theme_tab_background_glass.pngbin0 -> 226 bytes
-rw-r--r--chrome/app/theme/theme_tab_background_incognito.pngbin0 -> 718 bytes
-rw-r--r--chrome/app/theme/theme_toolbar_default.pngbin0 -> 452 bytes
-rw-r--r--chrome/app/theme/window_bottom_center.pngbin229 -> 131 bytes
-rw-r--r--chrome/app/theme/window_bottom_center_otr.pngbin128 -> 0 bytes
-rw-r--r--chrome/app/theme/window_bottom_left_corner.pngbin160 -> 139 bytes
-rw-r--r--chrome/app/theme/window_bottom_left_corner_otr.pngbin136 -> 0 bytes
-rw-r--r--chrome/app/theme/window_bottom_right_corner.pngbin151 -> 129 bytes
-rw-r--r--chrome/app/theme/window_bottom_right_corner_otr.pngbin125 -> 0 bytes
-rw-r--r--chrome/app/theme/window_left_side.pngbin118 -> 116 bytes
-rw-r--r--chrome/app/theme/window_left_side_otr.pngbin120 -> 0 bytes
-rw-r--r--chrome/app/theme/window_right_side.pngbin122 -> 115 bytes
-rw-r--r--chrome/app/theme/window_right_side_otr.pngbin121 -> 0 bytes
-rw-r--r--chrome/app/theme/window_top_center.pngbin2724 -> 135 bytes
-rw-r--r--chrome/app/theme/window_top_center_otr.pngbin1595 -> 0 bytes
-rw-r--r--chrome/app/theme/window_top_left_corner.pngbin590 -> 191 bytes
-rw-r--r--chrome/app/theme/window_top_left_corner_otr.pngbin509 -> 0 bytes
-rw-r--r--chrome/app/theme/window_top_right_corner.pngbin589 -> 182 bytes
-rw-r--r--chrome/app/theme/window_top_right_corner_otr.pngbin513 -> 0 bytes
-rw-r--r--chrome/browser/browser.vcproj16
-rw-r--r--chrome/browser/browser_init.cc1
-rw-r--r--chrome/browser/browser_theme_provider.cc527
-rw-r--r--chrome/browser/browser_theme_provider.h125
-rw-r--r--chrome/browser/browser_window.h4
-rw-r--r--chrome/browser/dom_ui/dom_ui.cc7
-rw-r--r--chrome/browser/dom_ui/dom_ui.h5
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.cc37
-rw-r--r--chrome/browser/dom_ui/dom_ui_theme_source.h30
-rw-r--r--chrome/browser/dom_ui/new_tab_ui.cc6
-rw-r--r--chrome/browser/extensions/extension.cc117
-rw-r--r--chrome/browser/extensions/extension.h32
-rw-r--r--chrome/browser/extensions/extensions_service.cc53
-rw-r--r--chrome/browser/extensions/extensions_service.h11
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc77
-rw-r--r--chrome/browser/extensions/extensions_ui.cc2
-rw-r--r--chrome/browser/external_tab_container.h1
-rw-r--r--chrome/browser/profile.cc66
-rw-r--r--chrome/browser/profile.h21
-rw-r--r--chrome/browser/resources/new_tab.html2
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc48
-rw-r--r--chrome/browser/views/constrained_window_impl.cc92
-rw-r--r--chrome/browser/views/frame/browser_frame.cc15
-rw-r--r--chrome/browser/views/frame/browser_frame.h9
-rw-r--r--chrome/browser/views/frame/browser_view.cc7
-rw-r--r--chrome/browser/views/frame/browser_view.h1
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.cc101
-rw-r--r--chrome/browser/views/frame/glass_browser_frame_view.h2
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.cc412
-rw-r--r--chrome/browser/views/frame/opaque_browser_frame_view.h15
-rw-r--r--chrome/browser/views/infobars/infobars.cc3
-rw-r--r--chrome/browser/views/location_bar_view.cc2
-rw-r--r--chrome/browser/views/options/content_page_view.cc75
-rw-r--r--chrome/browser/views/options/content_page_view.h17
-rw-r--r--chrome/browser/views/options/cookies_view.cc1
-rw-r--r--chrome/browser/views/tabs/tab_renderer.cc196
-rw-r--r--chrome/browser/views/tabs/tab_renderer.h20
-rw-r--r--chrome/browser/views/toolbar_view.cc199
-rw-r--r--chrome/browser/views/toolbar_view.h4
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/common/notification_type.h3
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h4
-rw-r--r--chrome/common/url_constants.cc1
-rw-r--r--chrome/common/url_constants.h1
-rwxr-xr-xchrome/renderer/extensions/bindings_utils.h1
-rw-r--r--chrome/test/data/extensions/theme.crxbin0 -> 27546 bytes
-rw-r--r--chrome/test/test_browser_window.h1
-rw-r--r--chrome/test/testing_profile.h6
-rw-r--r--skia/ext/image_operations.cc29
-rw-r--r--skia/ext/image_operations.h3
-rw-r--r--skia/ext/image_operations_unittest.cc4
-rw-r--r--skia/ext/skia_utils.cc58
-rw-r--r--skia/ext/skia_utils.h27
-rw-r--r--skia/ext/skia_utils_unittest.cc22
-rw-r--r--views/view.cc5
-rw-r--r--views/view.h4
-rw-r--r--views/views.vcproj30
-rw-r--r--views/widget/default_theme_provider.cc20
-rw-r--r--views/widget/default_theme_provider.h30
-rw-r--r--views/widget/widget.h13
-rw-r--r--views/widget/widget_win.cc18
-rw-r--r--views/widget/widget_win.h5
-rw-r--r--views/window/custom_frame_view.cc272
-rw-r--r--views/window/custom_frame_view.h8
162 files changed, 2116 insertions, 1039 deletions
diff --git a/app/DEPS b/app/DEPS
index 8770ca2..cf364f4 100644
--- a/app/DEPS
+++ b/app/DEPS
@@ -1,19 +1,16 @@
-include_rules = [
+include_rules = [
# TODO(beng): Modify this link to be more specific about what resource
# headers are included once app gets its own strings.
- "+grit",
- "+net",
- # TODO(beng): Sever these links once we have extracted all deps from
- # chrome/common.
- "+chrome/common/chrome_paths.h",
- "+chrome/common/chrome_switches.h",
- "+chrome/common/gtk_util.h",
+ "+grit",
+ "+net",
+ # TODO(beng): Sever these links once we have extracted all deps from
+ # chrome/common.
+ "+chrome/common/chrome_paths.h",
+ "+chrome/common/chrome_switches.h",
+ "+chrome/common/gtk_util.h",
- # TODO(beng): l10n_util_unittest.cc:
- "+chrome/test/data/resource.h",
-
- # TODO(beng): resource_bundle.cc: Sever this link after glen fixes it.
- "+chrome/browser/extensions/extension.h",
-
- "+skia",
-]
+ # TODO(beng): l10n_util_unittest.cc:
+ "+chrome/test/data/resource.h",
+
+ "+skia",
+]
diff --git a/app/app.vcproj b/app/app.vcproj
index 507a28a..d940bf9 100644
--- a/app/app.vcproj
+++ b/app/app.vcproj
@@ -145,14 +145,14 @@
>
</File>
<File
- RelativePath=".\gfx\color_utils.cc"
- >
- </File>
- <File
- RelativePath=".\gfx\color_utils.h"
- >
- </File>
- <File
+ RelativePath=".\gfx\color_utils.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\gfx\color_utils.h"
+ >
+ </File>
+ <File
RelativePath=".\gfx\favicon_size.h"
>
</File>
@@ -176,14 +176,14 @@
RelativePath=".\gfx\path_win.cc"
>
</File>
- <File
- RelativePath=".\gfx\text_elider.cc"
- >
- </File>
- <File
- RelativePath=".\gfx\text_elider.h"
- >
- </File>
+ <File
+ RelativePath=".\gfx\text_elider.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\gfx\text_elider.h"
+ >
+ </File>
</Filter>
<File
RelativePath=".\animation.cc"
@@ -250,6 +250,10 @@
>
</File>
<File
+ RelativePath=".\theme_provider.h"
+ >
+ </File>
+ <File
RelativePath=".\throb_animation.cc"
>
</File>
diff --git a/app/resource_bundle.cc b/app/resource_bundle.cc
index c3d6923..85fd0b9 100644
--- a/app/resource_bundle.cc
+++ b/app/resource_bundle.cc
@@ -15,6 +15,22 @@
ResourceBundle* ResourceBundle::g_shared_instance_ = NULL;
/* static */
+// TODO(glen): Finish moving these into theme provider (dialogs still
+// depend on these colors).
+const SkColor ResourceBundle::frame_color =
+ SkColorSetRGB(77, 139, 217);
+const SkColor ResourceBundle::frame_color_inactive =
+ SkColorSetRGB(184, 209, 240);
+const SkColor ResourceBundle::frame_color_incognito =
+ SkColorSetRGB(83, 106, 139);
+const SkColor ResourceBundle::frame_color_incognito_inactive =
+ SkColorSetRGB(126, 139, 156);
+const SkColor ResourceBundle::toolbar_color =
+ SkColorSetRGB(210, 225, 246);
+const SkColor ResourceBundle::toolbar_separator_color =
+ SkColorSetRGB(182, 186, 192);
+
+/* static */
void ResourceBundle::InitSharedInstance(const std::wstring& pref_locale) {
DCHECK(g_shared_instance_ == NULL) << "ResourceBundle initialized twice";
g_shared_instance_ = new ResourceBundle();
@@ -51,39 +67,11 @@ void ResourceBundle::FreeImages() {
skia_images_.clear();
}
-void ResourceBundle::SetThemeExtension(const Extension& e) {
- theme_extension_.reset(new Extension(e));
-}
-
/* static */
SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) {
std::vector<unsigned char> raw_data, png_data;
bool success = false;
- // First check to see if we have a registered theme extension and whether
- // it can handle this resource.
- // TODO(erikkay): It would be nice to use something less brittle than
- // resource_id here.
- if (g_shared_instance_->theme_extension_.get()) {
- FilePath path =
- g_shared_instance_->theme_extension_->GetThemeResourcePath(resource_id);
- if (!path.empty()) {
- net::FileStream file;
- int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
- if (file.Open(path, flags) == net::OK) {
- int64 avail = file.Available();
- if (avail > 0 && avail < INT_MAX) {
- size_t size = static_cast<size_t>(avail);
- raw_data.resize(size);
- char* data = reinterpret_cast<char*>(&(raw_data.front()));
- if (file.ReadUntilComplete(data, size) == avail) {
- success= true;
- } else {
- raw_data.resize(0);
- }
- }
- }
- }
- }
+
if (!success)
success = LoadResourceBytes(data_handle, resource_id, &raw_data);
if (!success)
diff --git a/app/resource_bundle.h b/app/resource_bundle.h
index e939edc..1ed44b0 100644
--- a/app/resource_bundle.h
+++ b/app/resource_bundle.h
@@ -18,7 +18,7 @@
#include "base/file_path.h"
#include "base/lock.h"
#include "base/scoped_ptr.h"
-#include "chrome/browser/extensions/extension.h"
+#include "base/string16.h"
#if defined(OS_LINUX) || defined(OS_MACOSX)
namespace base {
@@ -29,8 +29,8 @@ class DataPack;
typedef struct _GdkPixbuf GdkPixbuf;
#endif
class ChromeFont;
-class Extension;
class SkBitmap;
+typedef uint32 SkColor;
class StringPiece;
// ResourceBundle is a central facility to load images and other resources,
@@ -123,8 +123,14 @@ class ResourceBundle {
GdkPixbuf* GetPixbufNamed(int resource_id);
#endif
- // Sets an Extension object that can handle theme resource requests.
- void SetThemeExtension(const Extension& e);
+ // TODO(glen): Move these into theme provider (dialogs still depend on
+ // ResourceBundle).
+ static const SkColor frame_color;
+ static const SkColor frame_color_inactive;
+ static const SkColor frame_color_incognito;
+ static const SkColor frame_color_incognito_inactive;
+ static const SkColor toolbar_color;
+ static const SkColor toolbar_separator_color;
private:
// We define a DataHandle typedef to abstract across how data is stored
@@ -195,8 +201,6 @@ class ResourceBundle {
static ResourceBundle* g_shared_instance_;
- scoped_ptr<Extension> theme_extension_;
-
DISALLOW_EVIL_CONSTRUCTORS(ResourceBundle);
};
diff --git a/app/theme_provider.h b/app/theme_provider.h
new file mode 100644
index 0000000..ebc94c6
--- /dev/null
+++ b/app/theme_provider.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef APP_THEME_PROVIDER_H_
+#define APP_THEME_PROVIDER_H_
+
+#include "skia/include/SkColor.h"
+
+class SkBitmap;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// ThemeProvider
+//
+// ThemeProvider is an abstract class that defines the API that should be
+// implemented to provide bitmaps and color information for a given theme.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class ThemeProvider {
+ public:
+ virtual ~ThemeProvider() { }
+
+ // Get the bitmap specified by |id|. An implementation of ThemeProvider should
+ // have its own source of ids (e.g. an enum, or external resource bundle).
+ virtual SkBitmap* GetBitmapNamed(int id) = 0;
+
+ // Get the color specified by |id|.
+ virtual SkColor GetColor(int id) = 0;
+};
+
+#endif // APP_THEME_PROVIDER_H_
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index c192afb..05c02db 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3099,6 +3099,13 @@ each locale. -->
Save text from forms to make them easier to fill out
</message>
+ <message name="IDS_THEMES_GROUP_NAME" desc="The title of the themes group">
+ Themes:
+ </message>
+ <message name="IDS_THEMES_RESET_BUTTON" desc="The button to reset your theme">
+ Reset to default theme
+ </message>
+
<message name="IDS_OPTIONS_FONTSANDLANGUAGES_GROUP_NAME" desc="The label of the 'Fonts and Languages' group">
Fonts and Languages:
</message>
diff --git a/chrome/app/theme/app_top_center.png b/chrome/app/theme/app_top_center.png
index 863ff19..46f8f96 100644
--- a/chrome/app/theme/app_top_center.png
+++ b/chrome/app/theme/app_top_center.png
Binary files differ
diff --git a/chrome/app/theme/app_top_left.png b/chrome/app/theme/app_top_left.png
index 79723bc..78dc306f 100644
--- a/chrome/app/theme/app_top_left.png
+++ b/chrome/app/theme/app_top_left.png
Binary files differ
diff --git a/chrome/app/theme/app_top_right.png b/chrome/app/theme/app_top_right.png
index b00c3ea..df3b9a3 100644
--- a/chrome/app/theme/app_top_right.png
+++ b/chrome/app/theme/app_top_right.png
Binary files differ
diff --git a/chrome/app/theme/back.png b/chrome/app/theme/back.png
index 4f7a2d2..b983fca 100644
--- a/chrome/app/theme/back.png
+++ b/chrome/app/theme/back.png
Binary files differ
diff --git a/chrome/app/theme/back_d.png b/chrome/app/theme/back_d.png
index b216b18..1b51a59 100644
--- a/chrome/app/theme/back_d.png
+++ b/chrome/app/theme/back_d.png
Binary files differ
diff --git a/chrome/app/theme/constrained_bottom_center.png b/chrome/app/theme/constrained_bottom_center.png
deleted file mode 100644
index e1014b5..0000000
--- a/chrome/app/theme/constrained_bottom_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_bottom_left_corner.png b/chrome/app/theme/constrained_bottom_left_corner.png
deleted file mode 100644
index 4ba2342..0000000
--- a/chrome/app/theme/constrained_bottom_left_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_bottom_right_corner.png b/chrome/app/theme/constrained_bottom_right_corner.png
deleted file mode 100644
index 8221cc3..0000000
--- a/chrome/app/theme/constrained_bottom_right_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_left_side.png b/chrome/app/theme/constrained_left_side.png
deleted file mode 100644
index 0a00529..0000000
--- a/chrome/app/theme/constrained_left_side.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_right_side.png b/chrome/app/theme/constrained_right_side.png
deleted file mode 100644
index 0d97721..0000000
--- a/chrome/app/theme/constrained_right_side.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_top_center.png b/chrome/app/theme/constrained_top_center.png
deleted file mode 100644
index 89ab107..0000000
--- a/chrome/app/theme/constrained_top_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_top_left_corner.png b/chrome/app/theme/constrained_top_left_corner.png
deleted file mode 100644
index b0ec4a9..0000000
--- a/chrome/app/theme/constrained_top_left_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/constrained_top_right_corner.png b/chrome/app/theme/constrained_top_right_corner.png
deleted file mode 100644
index 7dd550e..0000000
--- a/chrome/app/theme/constrained_top_right_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/content_bottom_center.png b/chrome/app/theme/content_bottom_center.png
index a9bdb3d..efce9cf 100644
--- a/chrome/app/theme/content_bottom_center.png
+++ b/chrome/app/theme/content_bottom_center.png
Binary files differ
diff --git a/chrome/app/theme/content_bottom_left_corner.png b/chrome/app/theme/content_bottom_left_corner.png
index 0f0d629..db7b04f 100644
--- a/chrome/app/theme/content_bottom_left_corner.png
+++ b/chrome/app/theme/content_bottom_left_corner.png
Binary files differ
diff --git a/chrome/app/theme/content_bottom_right_corner.png b/chrome/app/theme/content_bottom_right_corner.png
index 77fe4ac..d4c0136 100644
--- a/chrome/app/theme/content_bottom_right_corner.png
+++ b/chrome/app/theme/content_bottom_right_corner.png
Binary files differ
diff --git a/chrome/app/theme/content_left_side.png b/chrome/app/theme/content_left_side.png
index e952fcb..93bc64b 100644
--- a/chrome/app/theme/content_left_side.png
+++ b/chrome/app/theme/content_left_side.png
Binary files differ
diff --git a/chrome/app/theme/content_right_side.png b/chrome/app/theme/content_right_side.png
index 35e3d74..598858b 100644
--- a/chrome/app/theme/content_right_side.png
+++ b/chrome/app/theme/content_right_side.png
Binary files differ
diff --git a/chrome/app/theme/content_top_center.png b/chrome/app/theme/content_top_center.png
index 07cd04a..4bd39e3 100644
--- a/chrome/app/theme/content_top_center.png
+++ b/chrome/app/theme/content_top_center.png
Binary files differ
diff --git a/chrome/app/theme/content_top_left_corner.png b/chrome/app/theme/content_top_left_corner.png
index 3ca40b6..2baaf4e 100644
--- a/chrome/app/theme/content_top_left_corner.png
+++ b/chrome/app/theme/content_top_left_corner.png
Binary files differ
diff --git a/chrome/app/theme/content_top_right_corner.png b/chrome/app/theme/content_top_right_corner.png
index 91fe2de..25fd15a 100644
--- a/chrome/app/theme/content_top_right_corner.png
+++ b/chrome/app/theme/content_top_right_corner.png
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_center.png b/chrome/app/theme/dewindow_bottom_center.png
deleted file mode 100644
index 78c0409..0000000
--- a/chrome/app/theme/dewindow_bottom_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_center_otr.png b/chrome/app/theme/dewindow_bottom_center_otr.png
deleted file mode 100644
index 8fa9f44..0000000
--- a/chrome/app/theme/dewindow_bottom_center_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_left_corner.png b/chrome/app/theme/dewindow_bottom_left_corner.png
deleted file mode 100644
index d961eaf..0000000
--- a/chrome/app/theme/dewindow_bottom_left_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_left_corner_otr.png b/chrome/app/theme/dewindow_bottom_left_corner_otr.png
deleted file mode 100644
index 934aaf9..0000000
--- a/chrome/app/theme/dewindow_bottom_left_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_right_corner.png b/chrome/app/theme/dewindow_bottom_right_corner.png
deleted file mode 100644
index e5a2e3d..0000000
--- a/chrome/app/theme/dewindow_bottom_right_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_bottom_right_corner_otr.png b/chrome/app/theme/dewindow_bottom_right_corner_otr.png
deleted file mode 100644
index a262d91..0000000
--- a/chrome/app/theme/dewindow_bottom_right_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_left_side.png b/chrome/app/theme/dewindow_left_side.png
deleted file mode 100644
index f84abc3..0000000
--- a/chrome/app/theme/dewindow_left_side.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_left_side_otr.png b/chrome/app/theme/dewindow_left_side_otr.png
deleted file mode 100644
index 4b0fbce..0000000
--- a/chrome/app/theme/dewindow_left_side_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_right_side.png b/chrome/app/theme/dewindow_right_side.png
deleted file mode 100644
index 3e79e27..0000000
--- a/chrome/app/theme/dewindow_right_side.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_right_side_otr.png b/chrome/app/theme/dewindow_right_side_otr.png
deleted file mode 100644
index bf64f90..0000000
--- a/chrome/app/theme/dewindow_right_side_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_center.png b/chrome/app/theme/dewindow_top_center.png
deleted file mode 100644
index 6a5ba27..0000000
--- a/chrome/app/theme/dewindow_top_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_center_otr.png b/chrome/app/theme/dewindow_top_center_otr.png
deleted file mode 100644
index 6b9baf1..0000000
--- a/chrome/app/theme/dewindow_top_center_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_left_corner.png b/chrome/app/theme/dewindow_top_left_corner.png
deleted file mode 100644
index d7af76f..0000000
--- a/chrome/app/theme/dewindow_top_left_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_left_corner_otr.png b/chrome/app/theme/dewindow_top_left_corner_otr.png
deleted file mode 100644
index c8ca568..0000000
--- a/chrome/app/theme/dewindow_top_left_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_right_corner.png b/chrome/app/theme/dewindow_top_right_corner.png
deleted file mode 100644
index ca6659c..0000000
--- a/chrome/app/theme/dewindow_top_right_corner.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/dewindow_top_right_corner_otr.png b/chrome/app/theme/dewindow_top_right_corner_otr.png
deleted file mode 100644
index 3a4300b..0000000
--- a/chrome/app/theme/dewindow_top_right_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/forward.png b/chrome/app/theme/forward.png
index a2dd01d..a1ae190 100644
--- a/chrome/app/theme/forward.png
+++ b/chrome/app/theme/forward.png
Binary files differ
diff --git a/chrome/app/theme/forward_d.png b/chrome/app/theme/forward_d.png
index d4a1426..28012fe 100644
--- a/chrome/app/theme/forward_d.png
+++ b/chrome/app/theme/forward_d.png
Binary files differ
diff --git a/chrome/app/theme/go.png b/chrome/app/theme/go.png
index 571fb75..c4df2164 100644
--- a/chrome/app/theme/go.png
+++ b/chrome/app/theme/go.png
Binary files differ
diff --git a/chrome/app/theme/locationbg.png b/chrome/app/theme/locationbg.png
index 875e47d..974b443 100644
--- a/chrome/app/theme/locationbg.png
+++ b/chrome/app/theme/locationbg.png
Binary files differ
diff --git a/chrome/app/theme/menu_chrome.png b/chrome/app/theme/menu_chrome.png
index aabd07d..6fc9f5c 100644
--- a/chrome/app/theme/menu_chrome.png
+++ b/chrome/app/theme/menu_chrome.png
Binary files differ
diff --git a/chrome/app/theme/menu_page.png b/chrome/app/theme/menu_page.png
index 10b8def..75897ef 100644
--- a/chrome/app/theme/menu_page.png
+++ b/chrome/app/theme/menu_page.png
Binary files differ
diff --git a/chrome/app/theme/notused.png b/chrome/app/theme/notused.png
new file mode 100644
index 0000000..42ad610
--- /dev/null
+++ b/chrome/app/theme/notused.png
Binary files differ
diff --git a/chrome/app/theme/ntp_background.png b/chrome/app/theme/ntp_background.png
new file mode 100644
index 0000000..fb75b9f
--- /dev/null
+++ b/chrome/app/theme/ntp_background.png
Binary files differ
diff --git a/chrome/app/theme/reload.png b/chrome/app/theme/reload.png
index 20ab352..f63d5188 100644
--- a/chrome/app/theme/reload.png
+++ b/chrome/app/theme/reload.png
Binary files differ
diff --git a/chrome/app/theme/reload_d.png b/chrome/app/theme/reload_d.png
index 15a6a1e..ec5811a 100644
--- a/chrome/app/theme/reload_d.png
+++ b/chrome/app/theme/reload_d.png
Binary files differ
diff --git a/chrome/app/theme/star.png b/chrome/app/theme/star.png
index 6284d4a..987aa04 100644
--- a/chrome/app/theme/star.png
+++ b/chrome/app/theme/star.png
Binary files differ
diff --git a/chrome/app/theme/star_d.png b/chrome/app/theme/star_d.png
index a6111a5..cf23eda 100644
--- a/chrome/app/theme/star_d.png
+++ b/chrome/app/theme/star_d.png
Binary files differ
diff --git a/chrome/app/theme/starred.png b/chrome/app/theme/starred.png
index 1b20148..bf0ba85 100644
--- a/chrome/app/theme/starred.png
+++ b/chrome/app/theme/starred.png
Binary files differ
diff --git a/chrome/app/theme/stop.png b/chrome/app/theme/stop.png
index 8b91fca..f25d62a 100644
--- a/chrome/app/theme/stop.png
+++ b/chrome/app/theme/stop.png
Binary files differ
diff --git a/chrome/app/theme/tab_active_center.png b/chrome/app/theme/tab_active_center.png
index 653b8fe..24b9a64 100644
--- a/chrome/app/theme/tab_active_center.png
+++ b/chrome/app/theme/tab_active_center.png
Binary files differ
diff --git a/chrome/app/theme/tab_active_left.png b/chrome/app/theme/tab_active_left.png
index 65d627c..b926a48 100644
--- a/chrome/app/theme/tab_active_left.png
+++ b/chrome/app/theme/tab_active_left.png
Binary files differ
diff --git a/chrome/app/theme/tab_active_right.png b/chrome/app/theme/tab_active_right.png
index b7d6134..bec77a2 100644
--- a/chrome/app/theme/tab_active_right.png
+++ b/chrome/app/theme/tab_active_right.png
Binary files differ
diff --git a/chrome/app/theme/tab_hover_center.png b/chrome/app/theme/tab_hover_center.png
deleted file mode 100644
index 4a639da..0000000
--- a/chrome/app/theme/tab_hover_center.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_hover_left.png b/chrome/app/theme/tab_hover_left.png
deleted file mode 100644
index cedd81d..0000000
--- a/chrome/app/theme/tab_hover_left.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_hover_right.png b/chrome/app/theme/tab_hover_right.png
deleted file mode 100644
index 3bda1fd..0000000
--- a/chrome/app/theme/tab_hover_right.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_center.png b/chrome/app/theme/tab_inactive_center.png
index 1cb0ce2..50b6826 100644
--- a/chrome/app/theme/tab_inactive_center.png
+++ b/chrome/app/theme/tab_inactive_center.png
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_center_otr.png b/chrome/app/theme/tab_inactive_center_otr.png
deleted file mode 100644
index 781635c..0000000
--- a/chrome/app/theme/tab_inactive_center_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_center_v.png b/chrome/app/theme/tab_inactive_center_v.png
deleted file mode 100644
index bdc9591..0000000
--- a/chrome/app/theme/tab_inactive_center_v.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_left.png b/chrome/app/theme/tab_inactive_left.png
index 31fc0ca..67f0bbc 100644
--- a/chrome/app/theme/tab_inactive_left.png
+++ b/chrome/app/theme/tab_inactive_left.png
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_left_otr.png b/chrome/app/theme/tab_inactive_left_otr.png
deleted file mode 100644
index 99c5af5..0000000
--- a/chrome/app/theme/tab_inactive_left_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_left_v.png b/chrome/app/theme/tab_inactive_left_v.png
deleted file mode 100644
index cf9477f..0000000
--- a/chrome/app/theme/tab_inactive_left_v.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_right.png b/chrome/app/theme/tab_inactive_right.png
index 3fce47d..fae4add 100644
--- a/chrome/app/theme/tab_inactive_right.png
+++ b/chrome/app/theme/tab_inactive_right.png
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_right_otr.png b/chrome/app/theme/tab_inactive_right_otr.png
deleted file mode 100644
index 6b5bc26..0000000
--- a/chrome/app/theme/tab_inactive_right_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/tab_inactive_right_v.png b/chrome/app/theme/tab_inactive_right_v.png
deleted file mode 100644
index 82aac4d..0000000
--- a/chrome/app/theme/tab_inactive_right_v.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/theme_frame_default.png b/chrome/app/theme/theme_frame_default.png
new file mode 100644
index 0000000..3f4f7e9
--- /dev/null
+++ b/chrome/app/theme/theme_frame_default.png
Binary files differ
diff --git a/chrome/app/theme/theme_frame_default_inactive.png b/chrome/app/theme/theme_frame_default_inactive.png
new file mode 100644
index 0000000..a1eff41
--- /dev/null
+++ b/chrome/app/theme/theme_frame_default_inactive.png
Binary files differ
diff --git a/chrome/app/theme/theme_frame_default_incognito.png b/chrome/app/theme/theme_frame_default_incognito.png
new file mode 100644
index 0000000..179ea6c
--- /dev/null
+++ b/chrome/app/theme/theme_frame_default_incognito.png
Binary files differ
diff --git a/chrome/app/theme/theme_frame_default_incognito_inactive.png b/chrome/app/theme/theme_frame_default_incognito_inactive.png
new file mode 100644
index 0000000..a86b08c
--- /dev/null
+++ b/chrome/app/theme/theme_frame_default_incognito_inactive.png
Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index ee1f619..c89f5db 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -75,9 +75,6 @@
<include name="IDR_TAB_INACTIVE_CENTER" file="tab_inactive_center.png" type="BINDATA" />
<include name="IDR_TAB_INACTIVE_LEFT" file="tab_inactive_left.png" type="BINDATA" />
<include name="IDR_TAB_INACTIVE_RIGHT" file="tab_inactive_right.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_LEFT_OTR" file="tab_inactive_left_otr.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_CENTER_OTR" file="tab_inactive_center_otr.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_RIGHT_OTR" file="tab_inactive_right_otr.png" type="BINDATA" />
<include name="IDR_THROBBER" file="throbber.png" type="BINDATA" />
<include name="IDR_WINDOW_BOTTOM_CENTER" file="window_bottom_center.png" type="BINDATA" />
<include name="IDR_WINDOW_BOTTOM_LEFT_CORNER" file="window_bottom_left_corner.png" type="BINDATA" />
@@ -87,36 +84,9 @@
<include name="IDR_WINDOW_TOP_CENTER" file="window_top_center.png" type="BINDATA" />
<include name="IDR_WINDOW_TOP_LEFT_CORNER" file="window_top_left_corner.png" type="BINDATA" />
<include name="IDR_WINDOW_TOP_RIGHT_CORNER" file="window_top_right_corner.png" type="BINDATA" />
- <include name="IDR_WINDOW_BOTTOM_CENTER_OTR" file="window_bottom_center_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_BOTTOM_LEFT_CORNER_OTR" file="window_bottom_left_corner_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_BOTTOM_RIGHT_CORNER_OTR" file="window_bottom_right_corner_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_LEFT_SIDE_OTR" file="window_left_side_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_RIGHT_SIDE_OTR" file="window_right_side_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_TOP_CENTER_OTR" file="window_top_center_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_TOP_LEFT_CORNER_OTR" file="window_top_left_corner_otr.png" type="BINDATA" />
- <include name="IDR_WINDOW_TOP_RIGHT_CORNER_OTR" file="window_top_right_corner_otr.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_CENTER_V" file="tab_inactive_center_v.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_LEFT_V" file="tab_inactive_left_v.png" type="BINDATA" />
- <include name="IDR_TAB_INACTIVE_RIGHT_V" file="tab_inactive_right_v.png" type="BINDATA" />
<include name="IDR_RESTORE" file="restore.png" type="BINDATA" />
<include name="IDR_RESTORE_H" file="restore_h.png" type="BINDATA" />
<include name="IDR_RESTORE_P" file="restore_p.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_CENTER" file="dewindow_bottom_center.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_LEFT_CORNER" file="dewindow_bottom_left_corner.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_RIGHT_CORNER" file="dewindow_bottom_right_corner.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_LEFT_SIDE" file="dewindow_left_side.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_RIGHT_SIDE" file="dewindow_right_side.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_CENTER" file="dewindow_top_center.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_LEFT_CORNER" file="dewindow_top_left_corner.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_RIGHT_CORNER" file="dewindow_top_right_corner.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_CENTER_OTR" file="dewindow_bottom_center_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_LEFT_CORNER_OTR" file="dewindow_bottom_left_corner_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_BOTTOM_RIGHT_CORNER_OTR" file="dewindow_bottom_right_corner_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_LEFT_SIDE_OTR" file="dewindow_left_side_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_RIGHT_SIDE_OTR" file="dewindow_right_side_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_CENTER_OTR" file="dewindow_top_center_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_LEFT_CORNER_OTR" file="dewindow_top_left_corner_otr.png" type="BINDATA" />
- <include name="IDR_DEWINDOW_TOP_RIGHT_CORNER_OTR" file="dewindow_top_right_corner_otr.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM" file="download_button_center_bottom.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_H" file="download_button_center_bottom_h.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_BUTTON_CENTER_BOTTOM_P" file="download_button_center_bottom_p.png" type="BINDATA" />
@@ -161,14 +131,6 @@
<include name="IDR_DOWNLOAD_PROGRESS_BACKGROUND_32" file="download_progress_background32.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_PROGRESS_FOREGROUND_32" file="download_progress_foreground32.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_ICON" file="download_icon.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_BOTTOM_CENTER" file="constrained_bottom_center.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_BOTTOM_LEFT_CORNER" file="constrained_bottom_left_corner.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER" file="constrained_bottom_right_corner.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_LEFT_SIDE" file="constrained_left_side.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_RIGHT_SIDE" file="constrained_right_side.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_TOP_CENTER" file="constrained_top_center.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_TOP_LEFT_CORNER" file="constrained_top_left_corner.png" type="BINDATA" />
- <include name="IDR_CONSTRAINED_TOP_RIGHT_CORNER" file="constrained_top_right_corner.png" type="BINDATA" />
<include name="IDR_FIND_BOX_BACKGROUND" file="find_box_bg.png" type="BINDATA" />
<include name="IDR_FIND_BOX_BACKGROUND_LEFT" file="find_box_bg_left.png" type="BINDATA" />
<include name="IDR_FIND_BOX_BACKGROUND_LEFT_RTL" file="find_box_bg_left_rtl.png" type="BINDATA" />
@@ -292,9 +254,6 @@
<include name="IDR_MENU_PAGE_RTL" file="menu_page_rtl.png" type="BINDATA" />
<include name="IDR_MENU_CHROME_RTL" file="menu_chrome_rtl.png" type="BINDATA" />
<include name="IDR_DOWNLOAD_ANIMATION_BEGIN" file="download_animation_begin.png" type="BINDATA" />
- <include name="IDR_TAB_HOVER_LEFT" file="tab_hover_left.png" type="BINDATA" />
- <include name="IDR_TAB_HOVER_CENTER" file="tab_hover_center.png" type="BINDATA" />
- <include name="IDR_TAB_HOVER_RIGHT" file="tab_hover_right.png" type="BINDATA" />
<include name="IDR_FOLDER_CLOSED_RTL" file="folder_closed_rtl.png" type="BINDATA" />
<include name="IDR_FOLDER_OPEN_RTL" file="folder_open_rtl.png" type="BINDATA" />
<include name="IDR_BOOKMARK_BAR_FOLDER" file="bookmark_bar_folder.png" type="BINDATA" />
@@ -306,6 +265,8 @@
<include name="IDR_BOOKMARK_MANAGER_RECENT_ICON" file="bookmark_manager_recent.png" type="BINDATA" />
<include name="IDR_BOOKMARK_MANAGER_SEARCH_ICON" file="bookmark_manager_search.png" type="BINDATA" />
<include name="IDR_MENU_DROPARROW" file="menu_droparrow.png" type="BINDATA" />
+ <include name="IDR_TAB_ALPHA_LEFT" file="tab_alpha_left.png" type="BINDATA" />
+ <include name="IDR_TAB_ALPHA_RIGHT" file="tab_alpha_right.png" type="BINDATA" />
<include name="IDR_DOCK_MAX" file="dock_tab_max.png" type="BINDATA" />
<include name="IDR_DOCK_HIGH" file="dock_tab_high.png" type="BINDATA" />
<include name="IDR_DOCK_WIDE" file="dock_tab_wide.png" type="BINDATA" />
@@ -335,6 +296,16 @@
<include name="IDR_O2_STAR_SELECTED_DARK" file="o2_star_selected_dark.png" type="BINDATA" />
<include name="IDR_CLOSED_WINDOW" file="closed_window.png" type="BINDATA" />
+ <include name="IDR_THEME_FRAME" file="theme_frame_default.png" type="BINDATA" />
+ <include name="IDR_THEME_FRAME_INACTIVE" file="theme_frame_default_inactive.png" type="BINDATA" />
+ <include name="IDR_THEME_FRAME_INCOGNITO" file="theme_frame_default_incognito.png" type="BINDATA" />
+ <include name="IDR_THEME_FRAME_INCOGNITO_INACTIVE" file="theme_frame_default_incognito_inactive.png" type="BINDATA" />
+ <include name="IDR_THEME_TOOLBAR" file="theme_toolbar_default.png" type="BINDATA" />
+ <include name="IDR_THEME_TAB_BACKGROUND" file="theme_tab_background.png" type="BINDATA" />
+ <include name="IDR_THEME_TAB_BACKGROUND_INCOGNITO" file="theme_tab_background_incognito.png" type="BINDATA" />
+ <include name="IDR_THEME_TAB_BACKGROUND_V" file="theme_tab_background_glass.png" type="BINDATA" />
+ <include name="IDR_THEME_NEWTAB_BACKGROUND" file="ntp_background.png" type="BINDATA" />
+
<if expr="pp_ifdef('_google_chrome')">
<include name="IDR_ABOUT_BACKGROUND" file="google_chrome/about_background.png" type="BINDATA" />
<include name="IDR_ABOUT_BACKGROUND_RTL" file="google_chrome/about_background_rtl.png" type="BINDATA" />
@@ -359,5 +330,11 @@
<include name="IDR_PRODUCT_ICON_32" file="chromium/chromium_icon_32.png" type="BINDATA" />
</if>
</includes>
+ <messages>
+ <message name="IDS_COLOR_FRAME" use_name_for_id="true">frame</message>
+ <message name="IDS_COLOR_TOOLBAR" use_name_for_id="true">toolbar</message>
+ <message name="IDS_COLOR_TEXT_TAB" use_name_for_id="true">text_tab</message>
+ <message name="IDS_TINT_BUTTONS" use_name_for_id="true">buttons</message>
+ </messages>
</release>
</grit>
diff --git a/chrome/app/theme/theme_tab_background.png b/chrome/app/theme/theme_tab_background.png
new file mode 100644
index 0000000..d043bc3
--- /dev/null
+++ b/chrome/app/theme/theme_tab_background.png
Binary files differ
diff --git a/chrome/app/theme/theme_tab_background_glass.png b/chrome/app/theme/theme_tab_background_glass.png
new file mode 100644
index 0000000..df43d6f
--- /dev/null
+++ b/chrome/app/theme/theme_tab_background_glass.png
Binary files differ
diff --git a/chrome/app/theme/theme_tab_background_incognito.png b/chrome/app/theme/theme_tab_background_incognito.png
new file mode 100644
index 0000000..042c243
--- /dev/null
+++ b/chrome/app/theme/theme_tab_background_incognito.png
Binary files differ
diff --git a/chrome/app/theme/theme_toolbar_default.png b/chrome/app/theme/theme_toolbar_default.png
new file mode 100644
index 0000000..21678f8
--- /dev/null
+++ b/chrome/app/theme/theme_toolbar_default.png
Binary files differ
diff --git a/chrome/app/theme/window_bottom_center.png b/chrome/app/theme/window_bottom_center.png
index e6a191c..3fb76f1 100644
--- a/chrome/app/theme/window_bottom_center.png
+++ b/chrome/app/theme/window_bottom_center.png
Binary files differ
diff --git a/chrome/app/theme/window_bottom_center_otr.png b/chrome/app/theme/window_bottom_center_otr.png
deleted file mode 100644
index 8d6cdb0..0000000
--- a/chrome/app/theme/window_bottom_center_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_bottom_left_corner.png b/chrome/app/theme/window_bottom_left_corner.png
index db9cb72..1d3c066 100644
--- a/chrome/app/theme/window_bottom_left_corner.png
+++ b/chrome/app/theme/window_bottom_left_corner.png
Binary files differ
diff --git a/chrome/app/theme/window_bottom_left_corner_otr.png b/chrome/app/theme/window_bottom_left_corner_otr.png
deleted file mode 100644
index 803f2b8..0000000
--- a/chrome/app/theme/window_bottom_left_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_bottom_right_corner.png b/chrome/app/theme/window_bottom_right_corner.png
index f0522a3..83cf5b9 100644
--- a/chrome/app/theme/window_bottom_right_corner.png
+++ b/chrome/app/theme/window_bottom_right_corner.png
Binary files differ
diff --git a/chrome/app/theme/window_bottom_right_corner_otr.png b/chrome/app/theme/window_bottom_right_corner_otr.png
deleted file mode 100644
index b21c63f..0000000
--- a/chrome/app/theme/window_bottom_right_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_left_side.png b/chrome/app/theme/window_left_side.png
index d614d2c..2553d1b 100644
--- a/chrome/app/theme/window_left_side.png
+++ b/chrome/app/theme/window_left_side.png
Binary files differ
diff --git a/chrome/app/theme/window_left_side_otr.png b/chrome/app/theme/window_left_side_otr.png
deleted file mode 100644
index f632f049..0000000
--- a/chrome/app/theme/window_left_side_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_right_side.png b/chrome/app/theme/window_right_side.png
index 97939ef..c89b47b 100644
--- a/chrome/app/theme/window_right_side.png
+++ b/chrome/app/theme/window_right_side.png
Binary files differ
diff --git a/chrome/app/theme/window_right_side_otr.png b/chrome/app/theme/window_right_side_otr.png
deleted file mode 100644
index ac6bdc1..0000000
--- a/chrome/app/theme/window_right_side_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_top_center.png b/chrome/app/theme/window_top_center.png
index 8e13cc2..e2c393e 100644
--- a/chrome/app/theme/window_top_center.png
+++ b/chrome/app/theme/window_top_center.png
Binary files differ
diff --git a/chrome/app/theme/window_top_center_otr.png b/chrome/app/theme/window_top_center_otr.png
deleted file mode 100644
index 49b3ab1..0000000
--- a/chrome/app/theme/window_top_center_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_top_left_corner.png b/chrome/app/theme/window_top_left_corner.png
index 89e5f23..4bb52ce 100644
--- a/chrome/app/theme/window_top_left_corner.png
+++ b/chrome/app/theme/window_top_left_corner.png
Binary files differ
diff --git a/chrome/app/theme/window_top_left_corner_otr.png b/chrome/app/theme/window_top_left_corner_otr.png
deleted file mode 100644
index 9521ae0b..0000000
--- a/chrome/app/theme/window_top_left_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/window_top_right_corner.png b/chrome/app/theme/window_top_right_corner.png
index 60686b3..d1da9ca 100644
--- a/chrome/app/theme/window_top_right_corner.png
+++ b/chrome/app/theme/window_top_right_corner.png
Binary files differ
diff --git a/chrome/app/theme/window_top_right_corner_otr.png b/chrome/app/theme/window_top_right_corner_otr.png
deleted file mode 100644
index 0b05ca1..0000000
--- a/chrome/app/theme/window_top_right_corner_otr.png
+++ /dev/null
Binary files differ
diff --git a/chrome/browser/browser.vcproj b/chrome/browser/browser.vcproj
index 91e7a36..7642876 100644
--- a/chrome/browser/browser.vcproj
+++ b/chrome/browser/browser.vcproj
@@ -290,6 +290,14 @@
>
</File>
<File
+ RelativePath=".\browser_theme_provider.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\browser_theme_provider.h"
+ >
+ </File>
+ <File
RelativePath=".\browser_url_handler.cc"
>
</File>
@@ -1542,6 +1550,14 @@
>
</File>
<File
+ RelativePath=".\dom_ui\dom_ui_theme_source.cc"
+ >
+ </File>
+ <File
+ RelativePath=".\dom_ui\dom_ui_theme_source.h"
+ >
+ </File>
+ <File
RelativePath=".\dom_ui\dom_ui_thumbnail_source.cc"
>
</File>
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index fa6a00a..5488ef6 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/first_run.h"
#include "chrome/browser/net/dns_global.h"
#include "chrome/browser/profile.h"
diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc
new file mode 100644
index 0000000..cb68ed0c
--- /dev/null
+++ b/chrome/browser/browser_theme_provider.cc
@@ -0,0 +1,527 @@
+// 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.
+
+#include "browser_theme_provider.h"
+
+#include "base/gfx/png_decoder.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/theme_resources_util.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/pref_service.h"
+#include "grit/theme_resources.h"
+#include "net/base/file_stream.h"
+#include "net/base/net_errors.h"
+#include "skia/ext/image_operations.h"
+#include "skia/ext/skia_utils.h"
+#include "SkBitmap.h"
+
+// Strings used by themes to identify colors for different parts of our UI.
+static const std::string kColorFrame = "frame";
+static const std::string kColorFrameInactive = "frame_inactive";
+static const std::string kColorFrameIncognito = "frame_incognito";
+static const std::string kColorFrameIncognitoInactive =
+ "frame_incognito_inactive";
+static const std::string kColorToolbar = "toolbar";
+static const std::string kColorTabText = "tab_text";
+static const std::string kColorBackgroundTabText = "background_tab_text";
+static const std::string kColorBookmarkText = "bookmark_text";
+static const std::string kColorNTPText = "ntp_text";
+static const std::string kColorNTPLink = "ntp_link";
+static const std::string kColorNTPSection = "ntp_section";
+
+// Strings used by themes to identify tints to apply to different parts of
+// our UI. The frame tints apply to the frame color and produce the
+// COLOR_FRAME* colors.
+static const std::string kTintButtons = "buttons";
+static const std::string kTintFrame = "frame";
+static const std::string kTintFrameInactive = "frame_inactive";
+static const std::string kTintFrameIncognito = "frame_incognito";
+static const std::string kTintFrameIncognitoInactive =
+ "frame_incognito_inactive";
+static const std::string kTintBackgroundTab = "background_tab";
+
+// Default colors.
+static const SkColor kDefaultColorFrame = SkColorSetRGB(77, 139, 217);
+static const SkColor kDefaultColorFrameInactive = SkColorSetRGB(152, 188, 233);
+static const SkColor kDefaultColorFrameIncognito = SkColorSetRGB(83, 106, 139);
+static const SkColor kDefaultColorFrameIncognitoInactive =
+ SkColorSetRGB(126, 139, 156);
+static const SkColor kDefaultColorToolbar = SkColorSetRGB(210, 225, 246);
+static const SkColor kDefaultColorTabText = SkColorSetRGB(0, 0, 0);
+static const SkColor kDefaultColorBackgroundTabText = SkColorSetRGB(64, 64, 64);
+
+// Default tints.
+static const skia::HSL kDefaultTintButtons = { -1, -1, -1 };
+static const skia::HSL kDefaultTintFrame = { -1, -1, -1 };
+static const skia::HSL kDefaultTintFrameInactive = { -1, 0.5f, 0.72f };
+static const skia::HSL kDefaultTintFrameIncognito = { -1, 0.2f, 0.35f };
+static const skia::HSL kDefaultTintFrameIncognitoInactive = { -1, 0.3f, 0.6f };
+static const skia::HSL kDefaultTintBackgroundTab = { -1, 0.5, 0.75 };
+
+// The image resources that will be tinted by the 'button' tint value.
+static const int kToolbarButtonIDs[] = {
+ IDR_BACK, IDR_BACK_D, IDR_BACK_H, IDR_BACK_P,
+ IDR_FORWARD, IDR_FORWARD_D, IDR_FORWARD_H, IDR_FORWARD_P,
+ IDR_RELOAD, IDR_RELOAD_H, IDR_RELOAD_P,
+ IDR_HOME, IDR_HOME_H, IDR_HOME_P,
+ IDR_STAR, IDR_STAR_D, IDR_STAR_H, IDR_STAR_P,
+ IDR_STARRED, IDR_STARRED_H, IDR_STARRED_P,
+ IDR_GO, IDR_GO_H, IDR_GO_P,
+ IDR_STOP, IDR_STOP_H, IDR_STOP_P,
+ IDR_MENU_PAGE, IDR_MENU_PAGE_RTL,
+ IDR_MENU_CHROME, IDR_MENU_CHROME_RTL,
+ IDR_MENU_DROPARROW,
+ IDR_THROBBER,
+};
+
+// A map for kToolbarButtonIDs.
+static std::map<const int, bool> button_images_;
+
+// A map of frame image IDs to the tints for those ids.
+static std::map<const int, int> frame_tints_;
+
+BrowserThemeProvider::BrowserThemeProvider()
+ : rb_(ResourceBundle::GetSharedInstance()) {
+ static bool initialized = false;
+ if (!initialized) {
+ for (int i = 0; i < sizeof(kToolbarButtonIDs); ++i) {
+ button_images_[kToolbarButtonIDs[i]] = true;
+ }
+ frame_tints_[IDR_THEME_FRAME] = TINT_FRAME;
+ frame_tints_[IDR_THEME_FRAME_INACTIVE] = TINT_FRAME_INACTIVE;
+ frame_tints_[IDR_THEME_FRAME_INCOGNITO] = TINT_FRAME_INCOGNITO;
+ frame_tints_[IDR_THEME_FRAME_INCOGNITO_INACTIVE] =
+ TINT_FRAME_INCOGNITO_INACTIVE;
+ }
+}
+
+BrowserThemeProvider::~BrowserThemeProvider() { }
+
+void BrowserThemeProvider::Init(Profile* profile) {
+ profile_ = profile;
+ LoadThemePrefs();
+}
+
+SkBitmap* BrowserThemeProvider::GetBitmapNamed(int id) {
+ // Check to see if we already have the Skia image in the cache.
+ ImageCache::const_iterator found = image_cache_.find(id);
+ if (found != image_cache_.end())
+ return found->second;
+
+ scoped_ptr<SkBitmap> result;
+
+ // Try to load the image from the extension.
+ result.reset(LoadThemeBitmap(id));
+
+ // If the extension doesn't provide the requested image, but has provided
+ // a custom frame, then we may be able to generate the image required.
+ if (!result.get())
+ result.reset(GenerateBitmap(id));
+
+ // If we still don't have an image, load it from resourcebundle.
+ if (!result.get())
+ result.reset(rb_.GetBitmapNamed(id));
+
+ // If the requested image is part of the toolbar button set, and we have
+ // a provided tint for that set, tint it appropriately.
+ if (button_images_.count(id) && tints_.count(kTintButtons)) {
+ SkBitmap* tinted =
+ new SkBitmap(TintBitmap(*result.release(), TINT_BUTTONS));
+ result.reset(tinted);
+ }
+
+ if (result.get()) {
+ // We loaded successfully. Cache the bitmap.
+ image_cache_[id] = result.get();
+ return result.release();
+ } else {
+ NOTREACHED() << "Failed to load a requested image";
+ return NULL;
+ }
+}
+
+SkColor BrowserThemeProvider::GetColor(int id) {
+ // TODO(glen): Figure out if we need to tint these. http://crbug.com/11578
+ switch (id) {
+ case COLOR_FRAME:
+ return (colors_.find(kColorFrame) != colors_.end()) ?
+ colors_[kColorFrame] : kDefaultColorFrame;
+ case COLOR_FRAME_INACTIVE:
+ return (colors_.find(kColorFrameInactive) != colors_.end()) ?
+ colors_[kColorFrameInactive] : kDefaultColorFrameInactive;
+ case COLOR_FRAME_INCOGNITO:
+ return (colors_.find(kColorFrameIncognito) != colors_.end()) ?
+ colors_[kColorFrameIncognito] : kDefaultColorFrameIncognito;
+ case COLOR_FRAME_INCOGNITO_INACTIVE:
+ return (colors_.find(kColorFrameIncognitoInactive) != colors_.end()) ?
+ colors_[kColorFrameIncognitoInactive] :
+ kDefaultColorFrameIncognitoInactive;
+ case COLOR_TOOLBAR:
+ return (colors_.find(kColorToolbar) != colors_.end()) ?
+ colors_[kColorToolbar] : kDefaultColorToolbar;
+ case COLOR_TAB_TEXT:
+ return (colors_.find(kColorTabText) != colors_.end()) ?
+ colors_[kColorTabText] : kDefaultColorTabText;
+ case COLOR_BACKGROUND_TAB_TEXT:
+ return (colors_.find(kColorBackgroundTabText) != colors_.end()) ?
+ colors_[kColorBackgroundTabText] :
+ kDefaultColorBackgroundTabText;
+ default:
+ NOTREACHED() << "Unknown color requested";
+ }
+
+ // Return a debugging red color.
+ return 0xffff0000;
+}
+
+void BrowserThemeProvider::SetTheme(Extension* extension) {
+ // Clear our image cache.
+ image_cache_.clear();
+
+ DCHECK(extension);
+ DCHECK(extension->IsTheme());
+ SetImageData(extension->GetThemeImages(),
+ extension->path());
+ SetColorData(extension->GetThemeColors());
+ SetTintData(extension->GetThemeTints());
+ GenerateFrameColors();
+ GenerateFrameImages();
+
+ SaveImageData(extension->GetThemeImages());
+ SaveColorData();
+ SaveTintData();
+
+ NotifyThemeChanged();
+ UserMetrics::RecordAction(L"Themes_Installed", profile_);
+}
+
+void BrowserThemeProvider::UseDefaultTheme() {
+ // Clear our image cache.
+ image_cache_.clear();
+
+ images_.clear();
+ colors_.clear();
+ tints_.clear();
+
+ SaveImageData(NULL);
+ SaveColorData();
+ SaveTintData();
+
+ NotifyThemeChanged();
+}
+
+SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) {
+ // Attempt to find the image in our theme bundle.
+ std::vector<unsigned char> raw_data, png_data;
+ if (images_.count(id)) {
+ // First check to see if we have a registered theme extension and whether
+ // it can handle this resource.
+ FilePath path = FilePath(UTF8ToWide(images_[id]));
+ if (!path.empty()) {
+ net::FileStream file;
+ int flags = base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ;
+ if (file.Open(path, flags) == net::OK) {
+ int64 avail = file.Available();
+ if (avail > 0 && avail < INT_MAX) {
+ size_t size = static_cast<size_t>(avail);
+ raw_data.resize(size);
+ char* data = reinterpret_cast<char*>(&(raw_data.front()));
+ if (file.ReadUntilComplete(data, size) == avail) {
+ // Decode the PNG.
+ int image_width = 0;
+ int image_height = 0;
+
+ if (!PNGDecoder::Decode(&raw_data.front(), raw_data.size(),
+ PNGDecoder::FORMAT_BGRA, &png_data,
+ &image_width, &image_height)) {
+ NOTREACHED() << "Unable to decode theme image resource " << id;
+ return NULL;
+ }
+
+ return PNGDecoder::CreateSkBitmapFromBGRAFormat(png_data,
+ image_width,
+ image_height);
+ }
+ }
+ } else {
+ // TODO(glen): File no-longer exists, we're out of date. We should
+ // clear the theme (or maybe just the pref that points to this
+ // image).
+ return NULL;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+skia::HSL BrowserThemeProvider::GetTint(int id) {
+ switch (id) {
+ case TINT_FRAME:
+ return (tints_.find(kTintFrame) != tints_.end()) ?
+ tints_[kTintFrame] : kDefaultTintFrame;
+ case TINT_FRAME_INACTIVE:
+ return (tints_.find(kTintFrameInactive) != tints_.end()) ?
+ tints_[kTintFrameInactive] : kDefaultTintFrameInactive;
+ case TINT_FRAME_INCOGNITO:
+ return (tints_.count(kTintFrameIncognito)) ?
+ tints_[kTintFrameIncognito] : kDefaultTintFrameIncognito;
+ case TINT_FRAME_INCOGNITO_INACTIVE:
+ return (tints_.count(kTintFrameIncognitoInactive)) ?
+ tints_[kTintFrameIncognitoInactive] :
+ kDefaultTintFrameIncognitoInactive;
+ case TINT_BUTTONS:
+ return (tints_.find(kTintButtons) != tints_.end()) ?
+ tints_[kTintButtons] :
+ kDefaultTintButtons;
+ case TINT_BACKGROUND_TAB:
+ return (tints_.find(kTintBackgroundTab) != tints_.end()) ?
+ tints_[kTintBackgroundTab] :
+ kDefaultTintBackgroundTab;
+ default:
+ NOTREACHED() << "Unknown tint requested";
+ }
+ skia::HSL result = {-1, -1, -1};
+ return result;
+}
+
+SkBitmap BrowserThemeProvider::TintBitmap(const SkBitmap& bitmap, int hsl_id) {
+ return skia::ImageOperations::CreateHSLShiftedBitmap(bitmap, GetTint(hsl_id));
+}
+
+void BrowserThemeProvider::SetImageData(DictionaryValue* images_value,
+ FilePath images_path) {
+ images_.clear();
+
+ if (images_value) {
+ DictionaryValue::key_iterator iter = images_value->begin_keys();
+ while (iter != images_value->end_keys()) {
+ std::string val;
+ if (images_value->GetString(*iter, &val)) {
+ int id = ThemeResourcesUtil::GetId(WideToUTF8(*iter));
+ if (id != -1) {
+ if (!images_path.empty()) {
+ images_[id] = WideToUTF8(images_path.AppendASCII(val)
+ .ToWStringHack());
+ } else {
+ images_[id] = val;
+ }
+ }
+ }
+ ++iter;
+ }
+ }
+}
+
+void BrowserThemeProvider::SetColorData(DictionaryValue* colors_value) {
+ colors_.clear();
+
+ if (colors_value) {
+ DictionaryValue::key_iterator iter = colors_value->begin_keys();
+ while (iter != colors_value->end_keys()) {
+ ListValue* color_list;
+ if (colors_value->GetList(*iter, &color_list) &&
+ color_list->GetSize() == 3) {
+ int r, g, b;
+ color_list->GetInteger(0, &r);
+ color_list->GetInteger(1, &g);
+ color_list->GetInteger(2, &b);
+ colors_[WideToUTF8(*iter)] = SkColorSetRGB(r, g, b);
+ }
+ ++iter;
+ }
+ }
+}
+
+void BrowserThemeProvider::SetTintData(DictionaryValue* tints_value) {
+ tints_.clear();
+
+ if (tints_value) {
+ DictionaryValue::key_iterator iter = tints_value->begin_keys();
+ while (iter != tints_value->end_keys()) {
+ ListValue* tint_list;
+ if (tints_value->GetList(*iter, &tint_list) &&
+ tint_list->GetSize() == 3) {
+ skia::HSL hsl = { -1, -1, -1 };
+ // TODO(glen): Make this work with integer values.
+ tint_list->GetReal(0, &hsl.h);
+ tint_list->GetReal(1, &hsl.s);
+ tint_list->GetReal(2, &hsl.l);
+ tints_[WideToUTF8(*iter)] = hsl;
+ }
+ ++iter;
+ }
+ }
+}
+
+void BrowserThemeProvider::GenerateFrameColors() {
+ // Generate any secondary frame colors that weren't provided.
+ skia::HSL frame_hsl = { 0, 0, 0 };
+ skia::SkColorToHSL(GetColor(COLOR_FRAME), frame_hsl);
+
+ if (colors_.find(kColorFrame) == colors_.end())
+ colors_[kColorFrame] = HSLShift(frame_hsl, GetTint(TINT_FRAME));
+ if (colors_.find(kColorFrameInactive) == colors_.end()) {
+ colors_[kColorFrameInactive] =
+ HSLShift(frame_hsl, GetTint(TINT_FRAME_INACTIVE));
+ }
+ if (colors_.find(kColorFrameIncognito) == colors_.end()) {
+ colors_[kColorFrameIncognito] =
+ HSLShift(frame_hsl, GetTint(TINT_FRAME_INCOGNITO));
+ }
+ if (colors_.find(kColorFrameIncognitoInactive) == colors_.end()) {
+ colors_[kColorFrameIncognitoInactive] =
+ HSLShift(frame_hsl, GetTint(TINT_FRAME_INCOGNITO_INACTIVE));
+ }
+}
+
+void BrowserThemeProvider::GenerateFrameImages() {
+ std::map<const int, int>::iterator iter = frame_tints_.begin();
+ while (iter != frame_tints_.end()) {
+ int id = iter->first;
+ SkBitmap* frame;
+ // If there's no frame image provided for the specified id, then load
+ // the default provided frame. If that's not provided, skip this whole
+ // thing and just use the default images.
+ int base_id = (id == IDR_THEME_FRAME_INCOGNITO ||
+ id == IDR_THEME_FRAME_INCOGNITO_INACTIVE) ?
+ IDR_THEME_FRAME_INCOGNITO : IDR_THEME_FRAME;
+
+ if (images_.find(id) != images_.end()) {
+ frame = LoadThemeBitmap(id);
+ } else if (base_id != id && images_.find(base_id) != images_.end()) {
+ frame = LoadThemeBitmap(base_id);
+ } else {
+ if (id == IDR_THEME_FRAME_INCOGNITO ||
+ id == IDR_THEME_FRAME_INCOGNITO_INACTIVE)
+ frame = rb_.GetBitmapNamed(IDR_THEME_FRAME_INCOGNITO);
+ else
+ frame = rb_.GetBitmapNamed(IDR_THEME_FRAME);
+ }
+
+ if (frame) {
+ SkBitmap* tinted = new SkBitmap(TintBitmap(*frame, frame_tints_[id]));
+ image_cache_[id] = tinted;
+ }
+ ++iter;
+ }
+}
+
+SkBitmap* BrowserThemeProvider::GenerateBitmap(int id) {
+ if (id == IDR_THEME_TAB_BACKGROUND ||
+ id == IDR_THEME_TAB_BACKGROUND_INCOGNITO) {
+ // The requested image is a background tab. Get a frame to create the
+ // tab against. As themes don't use the glass frame, we don't have to
+ // worry about compositing them together, as our default theme provides
+ // the necessary bitmaps.
+ SkBitmap* frame;
+ if (id == IDR_THEME_TAB_BACKGROUND)
+ frame = image_cache_.find(IDR_THEME_FRAME)->second;
+ else
+ frame = image_cache_.find(IDR_THEME_FRAME_INCOGNITO)->second;
+
+ if (frame) {
+ SkBitmap blurred =
+ skia::ImageOperations::CreateBlurredBitmap(*frame, 5);
+ SkBitmap* bg_tab =
+ new SkBitmap(TintBitmap(blurred, TINT_BACKGROUND_TAB));
+ return bg_tab;
+ }
+ }
+
+ return NULL;
+}
+
+void BrowserThemeProvider::NotifyThemeChanged() {
+ // TODO(glen): If we're in glass and IDR_THEME_FRAME has been provided,
+ // swap us back to opaque frame.
+
+ // Redraw!
+ for (BrowserList::const_iterator browser = BrowserList::begin();
+ browser != BrowserList::end(); ++browser) {
+ (*browser)->window()->UserChangedTheme();
+ }
+}
+
+void BrowserThemeProvider::LoadThemePrefs() {
+ PrefService* prefs = profile_->GetPrefs();
+
+ // Our prefs already have the extension path baked in, so we don't need
+ // to provide it.
+ SetImageData(prefs->GetMutableDictionary(prefs::kCurrentThemeImages),
+ FilePath());
+ SetColorData(prefs->GetMutableDictionary(prefs::kCurrentThemeColors));
+ SetTintData(prefs->GetMutableDictionary(prefs::kCurrentThemeTints));
+ GenerateFrameColors();
+ GenerateFrameImages();
+
+ // TODO(glen): Figure out if any custom prefs were loaded, and if so
+ // UMA-log the fact that a theme was loaded.
+ if (prefs->HasPrefPath(prefs::kCurrentThemeImages) ||
+ prefs->HasPrefPath(prefs::kCurrentThemeColors) ||
+ prefs->HasPrefPath(prefs::kCurrentThemeTints)) {
+ UserMetrics::RecordAction(L"Themes_loaded", profile_);
+ }
+}
+
+void BrowserThemeProvider::SaveImageData(DictionaryValue* images_value) {
+ // Save our images data.
+ DictionaryValue* pref_images =
+ profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeImages);
+ pref_images->Clear();
+
+ DictionaryValue::key_iterator iter = images_value->begin_keys();
+ while (iter != images_value->end_keys()) {
+ std::string val;
+ if (images_value->GetString(*iter, &val)) {
+ int id = ThemeResourcesUtil::GetId(WideToUTF8(*iter));
+ if (id != -1)
+ pref_images->SetString(*iter, images_[id]);
+ }
+ ++iter;
+ }
+}
+
+void BrowserThemeProvider::SaveColorData() {
+ // Save our color data.
+ DictionaryValue* pref_colors =
+ profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeColors);
+ pref_colors->Clear();
+ if (colors_.size()) {
+ ColorMap::iterator iter = colors_.begin();
+ while (iter != colors_.end()) {
+ SkColor rgb = (*iter).second;
+ ListValue* rgb_list = new ListValue();
+ rgb_list->Set(0, Value::CreateIntegerValue(SkColorGetR(rgb)));
+ rgb_list->Set(1, Value::CreateIntegerValue(SkColorGetG(rgb)));
+ rgb_list->Set(2, Value::CreateIntegerValue(SkColorGetB(rgb)));
+ pref_colors->Set(UTF8ToWide((*iter).first), rgb_list);
+ ++iter;
+ }
+ }
+}
+
+void BrowserThemeProvider::SaveTintData() {
+ // Save our tint data.
+ DictionaryValue* pref_tints =
+ profile_->GetPrefs()->GetMutableDictionary(prefs::kCurrentThemeTints);
+ pref_tints->Clear();
+ if (tints_.size()) {
+ TintMap::iterator iter = tints_.begin();
+ while (iter != tints_.end()) {
+ skia::HSL hsl = (*iter).second;
+ ListValue* hsl_list = new ListValue();
+ hsl_list->Set(0, Value::CreateRealValue(hsl.h));
+ hsl_list->Set(1, Value::CreateRealValue(hsl.s));
+ hsl_list->Set(2, Value::CreateRealValue(hsl.l));
+ pref_tints->Set(UTF8ToWide((*iter).first), hsl_list);
+ ++iter;
+ }
+ }
+}
diff --git a/chrome/browser/browser_theme_provider.h b/chrome/browser/browser_theme_provider.h
new file mode 100644
index 0000000..bf16a0d
--- /dev/null
+++ b/chrome/browser/browser_theme_provider.h
@@ -0,0 +1,125 @@
+// 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.
+
+#ifndef CHROME_BROWSER_THEME_PROVIDER_H_
+#define CHROME_BROWSER_THEME_PROVIDER_H_
+
+#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
+#include "base/ref_counted.h"
+#include "skia/ext/skia_utils.h"
+
+class Extension;
+class Profile;
+class DictionaryValue;
+
+class BrowserThemeProvider :
+ public base::RefCountedThreadSafe<BrowserThemeProvider>,
+ public ThemeProvider {
+ public:
+ BrowserThemeProvider();
+ virtual ~BrowserThemeProvider();
+
+ enum {
+ COLOR_FRAME,
+ COLOR_FRAME_INACTIVE,
+ COLOR_FRAME_INCOGNITO,
+ COLOR_FRAME_INCOGNITO_INACTIVE,
+ COLOR_TOOLBAR,
+ COLOR_TAB_TEXT,
+ COLOR_BACKGROUND_TAB_TEXT,
+ COLOR_BOOKMARK_TEXT,
+ COLOR_NTP_TEXT,
+ COLOR_NTP_LINK,
+ COLOR_NTP_SECTION,
+ TINT_BUTTONS,
+ TINT_FRAME,
+ TINT_FRAME_INACTIVE,
+ TINT_FRAME_INCOGNITO,
+ TINT_FRAME_INCOGNITO_INACTIVE,
+ TINT_BACKGROUND_TAB
+ };
+
+ void Init(Profile* profile);
+
+ // ThemeProvider implementation.
+ virtual SkBitmap* GetBitmapNamed(int id);
+ virtual SkColor GetColor(int id);
+
+ // Set the current theme to the theme defined in |extension|.
+ void SetTheme(Extension* extension);
+
+ // Reset the theme to default.
+ void UseDefaultTheme();
+
+ private:
+ typedef std::map<const int, std::string> ImageMap;
+ typedef std::map<const std::string, SkColor> ColorMap;
+ typedef std::map<const std::string, skia::HSL> TintMap;
+
+ // Loads a bitmap from the theme, which may be tinted or
+ // otherwise modified, or an application default.
+ SkBitmap* LoadThemeBitmap(int id);
+
+ // Get the specified tint - |id| is one of the TINT_* enum values.
+ skia::HSL GetTint(int id);
+
+ // Tint |bitmap| with the tint specified by |hsl_id|
+ SkBitmap TintBitmap(const SkBitmap& bitmap, int hsl_id);
+
+ // The following load data from specified dictionaries (either from
+ // preferences or from an extension manifest) and update our theme
+ // data appropriately.
+ // Allow any ResourceBundle image to be overridden. |images| should
+ // contain keys defined in ThemeResourceMap, and values as paths to
+ // the images on-disk.
+ void SetImageData(DictionaryValue* images,
+ FilePath images_path);
+ // Set our theme colors. The keys of |colors| are any of the kColor*
+ // constants, and the values are a three-item list containing 8-bit
+ // RGB values.
+ void SetColorData(DictionaryValue* colors);
+ // Set tint data for our images and colors. The keys of |tints| are
+ // any of the kTint* contstants, and the values are a three-item list
+ // containing real numbers in the range 0-1 (and -1 for 'null').
+ void SetTintData(DictionaryValue* tints);
+
+ // Generate any frame colors that weren't specified.
+ void GenerateFrameColors();
+
+ // Generate any frame images that weren't specified. The resulting images
+ // will be stored in our cache.
+ void GenerateFrameImages();
+
+ // Create any images that aren't pregenerated (e.g. background tab images).
+ SkBitmap* GenerateBitmap(int id);
+
+ // Save our data - when saving images we need the original dictionary
+ // from the extension because it contains the text ids that we want to save.
+ void SaveImageData(DictionaryValue* images);
+ void SaveColorData();
+ void SaveTintData();
+
+ // Let all the browser views know that themes have changed.
+ void NotifyThemeChanged();
+
+ // Load theme data from preferences.
+ void LoadThemePrefs();
+
+ // Cached images. We cache all retrieved and generated bitmaps and keep
+ // track of the pointers.
+ typedef std::map<int, SkBitmap*> ImageCache;
+ ImageCache image_cache_;
+
+ ResourceBundle& rb_;
+ Profile* profile_;
+
+ ImageMap images_;
+ ColorMap colors_;
+ TintMap tints_;
+
+ DISALLOW_COPY_AND_ASSIGN(BrowserThemeProvider);
+};
+
+#endif // CHROME_BROWSER_THEME_PROVIDER_H_
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index 440c66d..c5e2027 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -176,6 +176,10 @@ class BrowserWindow {
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window) = 0;
+ // BrowserThemeProvider calls this when a user has changed his or her theme,
+ // indicating that it's time to redraw everything.
+ virtual void UserChangedTheme() = 0;
+
// Construct a BrowserWindow implementation for the specified |browser|.
static BrowserWindow* CreateBrowserWindow(Browser* browser);
diff --git a/chrome/browser/dom_ui/dom_ui.cc b/chrome/browser/dom_ui/dom_ui.cc
index f8e0405..ff49039 100644
--- a/chrome/browser/dom_ui/dom_ui.cc
+++ b/chrome/browser/dom_ui/dom_ui.cc
@@ -10,7 +10,10 @@
#include "base/stl_util-inl.h"
#include "base/string_util.h"
#include "base/values.h"
+#include "base/win_util.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
DOMUI::DOMUI(TabContents* contents)
: hide_favicon_(false),
@@ -79,6 +82,10 @@ void DOMUI::CallJavascriptFunction(
ExecuteJavascript(javascript);
}
+ThemeProvider* DOMUI::GetThemeProvider() const {
+ return tab_contents_->profile()->GetThemeProvider();
+}
+
void DOMUI::RegisterMessageCallback(const std::string &message,
MessageCallback *callback) {
message_callbacks_.insert(std::make_pair(message, callback));
diff --git a/chrome/browser/dom_ui/dom_ui.h b/chrome/browser/dom_ui/dom_ui.h
index 3c2dc16..fadff05 100644
--- a/chrome/browser/dom_ui/dom_ui.h
+++ b/chrome/browser/dom_ui/dom_ui.h
@@ -21,6 +21,7 @@ class Profile;
class RenderViewHost;
class Value;
class TabContents;
+class ThemeProvider;
// A DOMUI sets up the datasources and message handlers for a given HTML-based
// UI. It is contained by a DOMUIManager.
@@ -44,7 +45,7 @@ class DOMUI {
bool hide_favicon() const {
return hide_favicon_;
}
-
+
// Returns true if the bookmark bar should be forced to being visible,
// overriding the user's preference.
bool force_bookmark_bar_visible() const {
@@ -89,6 +90,8 @@ class DOMUI {
const Value& arg1,
const Value& arg2);
+ ThemeProvider* GetThemeProvider() const;
+
TabContents* tab_contents() { return tab_contents_; }
Profile* GetProfile();
diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.cc b/chrome/browser/dom_ui/dom_ui_theme_source.cc
new file mode 100644
index 0000000..31ff1f8
--- /dev/null
+++ b/chrome/browser/dom_ui/dom_ui_theme_source.cc
@@ -0,0 +1,37 @@
+// 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.
+
+#include "chrome/browser/dom_ui/dom_ui_theme_source.h"
+
+#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
+#include "base/gfx/png_encoder.h"
+#include "base/message_loop.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/theme_resources_util.h"
+#include "chrome/common/url_constants.h"
+#include "grit/theme_resources.h"
+
+DOMUIThemeSource::DOMUIThemeSource(Profile* profile)
+ : DataSource(chrome::kChromeUIThemePath, MessageLoop::current()),
+ profile_(profile) {
+}
+
+void DOMUIThemeSource::StartDataRequest(const std::string& path,
+ int request_id) {
+ ThemeProvider* tp = profile_->GetThemeProvider();
+ if (tp) {
+ int id = ThemeResourcesUtil::GetId(path);
+ if (id != -1) {
+ SkBitmap* image = tp->GetBitmapNamed(id);
+ if (image) {
+ std::vector<unsigned char> png_bytes;
+ PNGEncoder::EncodeBGRASkBitmap(*image, false, &png_bytes);
+
+ scoped_refptr<RefCountedBytes> image_data = new RefCountedBytes(png_bytes);
+ SendResponse(request_id, image_data);
+ }
+ }
+ }
+}
diff --git a/chrome/browser/dom_ui/dom_ui_theme_source.h b/chrome/browser/dom_ui/dom_ui_theme_source.h
new file mode 100644
index 0000000..279042d
--- /dev/null
+++ b/chrome/browser/dom_ui/dom_ui_theme_source.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef CHROME_BROWSER_DOM_UI_DOM_UI_THEME_SOURCE_H_
+#define CHROME_BROWSER_DOM_UI_DOM_UI_THEME_SOURCE_H_
+
+#include "chrome/browser/dom_ui/chrome_url_data_manager.h"
+
+class Profile;
+
+// ThumbnailSource is the gateway between network-level chrome:
+// requests for thumbnails and the history backend that serves these.
+class DOMUIThemeSource : public ChromeURLDataManager::DataSource {
+public:
+ explicit DOMUIThemeSource(Profile* profile);
+
+ // Called when the network layer has requested a resource underneath
+ // the path we registered.
+ virtual void StartDataRequest(const std::string& path, int request_id);
+ virtual std::string GetMimeType(const std::string& path) const {
+ return "image/png";
+ }
+
+private:
+ Profile* profile_;
+ DISALLOW_COPY_AND_ASSIGN(DOMUIThemeSource);
+};
+
+#endif // CHROME_BROWSER_DOM_UI_DOM_UI_THEME_SOURCE_H_
diff --git a/chrome/browser/dom_ui/new_tab_ui.cc b/chrome/browser/dom_ui/new_tab_ui.cc
index d4bdf97..b13fbb2 100644
--- a/chrome/browser/dom_ui/new_tab_ui.cc
+++ b/chrome/browser/dom_ui/new_tab_ui.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/dom_ui/dom_ui_favicon_source.h"
#include "chrome/browser/dom_ui/dom_ui_thumbnail_source.h"
+#include "chrome/browser/dom_ui/dom_ui_theme_source.h"
#include "chrome/browser/dom_ui/history_ui.h"
#include "chrome/browser/history/page_usage_data.h"
#include "chrome/browser/metrics/user_metrics.h"
@@ -1165,6 +1166,11 @@ NewTabUI::NewTabUI(TabContents* contents)
// In testing mode there may not be an I/O thread.
if (g_browser_process->io_thread()) {
+ g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(&chrome_url_data_manager,
+ &ChromeURLDataManager::AddDataSource,
+ new DOMUIThemeSource(GetProfile())));
+
NewTabHTMLSource* html_source = new NewTabHTMLSource();
g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(&chrome_url_data_manager,
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index 0f9c24e..e1533db6 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -30,6 +30,9 @@ const wchar_t* Extension::kPluginsDirKey = L"plugins_dir";
const wchar_t* Extension::kBackgroundKey = L"background_page";
const wchar_t* Extension::kRunAtKey = L"run_at";
const wchar_t* Extension::kThemeKey = L"theme";
+const wchar_t* Extension::kThemeImagesKey = L"images";
+const wchar_t* Extension::kThemeColorsKey = L"colors";
+const wchar_t* Extension::kThemeTintsKey = L"tints";
const wchar_t* Extension::kToolstripsKey = L"toolstrips";
const wchar_t* Extension::kTooltipKey = L"tooltip";
const wchar_t* Extension::kTypeKey = L"type";
@@ -110,6 +113,16 @@ const char* Extension::kMissingFileError =
"At least one js or css file is required for 'content_scripts[*]'.";
const char* Extension::kMissingPageActionIcon =
"Unable to find 'page_actions[*].icon'";
+const char* Extension::kInvalidThemeError =
+ "Invalid value for 'theme'.";
+const char* Extension::kInvalidThemeImagesError =
+ "Invalid value for theme images - images must be strings.";
+const char* Extension::kInvalidThemeImagesMissingError =
+ "Am image specified in the theme is missing.";
+const char* Extension::kInvalidThemeColorsError =
+ "Invalid value for theme colors - colors must be integers";
+const char* Extension::kInvalidThemeTintsError =
+ "Invalid value for theme images - tints must be decimal numbers.";
const size_t Extension::kIdSize = 20; // SHA1 (160 bits) == 20 bytes
@@ -124,7 +137,10 @@ Extension::Extension(const Extension& rhs)
page_actions_(rhs.page_actions_),
plugins_dir_(rhs.plugins_dir_),
zip_hash_(rhs.zip_hash_),
- theme_paths_(rhs.theme_paths_) {
+ theme_images_(rhs.theme_images_),
+ theme_colors_(rhs.theme_colors_),
+ theme_tints_(rhs.theme_tints_),
+ is_theme_(rhs.is_theme_) {
}
Extension::~Extension() {
@@ -149,14 +165,6 @@ GURL Extension::GetResourceURL(const GURL& extension_url,
return ret_val;
}
-FilePath Extension::GetThemeResourcePath(const int resource_id) {
- std::wstring id = IntToWString(resource_id);
- std::string path = theme_paths_[id];
- if (path.size())
- return path_.AppendASCII(path.c_str());
- return FilePath();
-}
-
const PageAction* Extension::GetPageAction(std::string id) const {
PageActionMap::const_iterator it = page_actions_.find(id);
if (it == page_actions_.end())
@@ -500,6 +508,81 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_id,
}
}
+ // Initialize themes. If a theme is included, no other items may be processed
+ // (we currently don't want people bundling themes and extension stuff
+ // together).
+ //
+ // TODO(glen): Error if other items *are* included.
+ is_theme_ = false;
+ if (source.HasKey(kThemeKey)) {
+ DictionaryValue* theme_value;
+ if (!source.GetDictionary(kThemeKey, &theme_value)) {
+ *error = kInvalidThemeError;
+ return false;
+ }
+ is_theme_ = true;
+
+ theme_images_ = new DictionaryValue;
+ DictionaryValue* images_value;
+ if (theme_value->GetDictionary(kThemeImagesKey, &images_value)) {
+ // Validate that the images are all strings
+ DictionaryValue::key_iterator iter = images_value->begin_keys();
+ while (iter != images_value->end_keys()) {
+ std::string val;
+ if (!images_value->GetString(*iter, &val)) {
+ *error = kInvalidThemeImagesError;
+ return false;
+ }
+ ++iter;
+ }
+ theme_images_ = static_cast<DictionaryValue*>(images_value->DeepCopy());
+ }
+
+ theme_colors_ = new DictionaryValue;
+ DictionaryValue* colors_value;
+ if (theme_value->GetDictionary(kThemeColorsKey, &colors_value)) {
+ // Validate that the colors are all three-item lists
+ DictionaryValue::key_iterator iter = colors_value->begin_keys();
+ while (iter != colors_value->end_keys()) {
+ std::string val;
+ int color = 0;
+ ListValue* color_list;
+ if (!colors_value->GetList(*iter, &color_list) ||
+ color_list->GetSize() != 3 ||
+ !color_list->GetInteger(0, &color) ||
+ !color_list->GetInteger(1, &color) ||
+ !color_list->GetInteger(2, &color)) {
+ *error = kInvalidThemeColorsError;
+ return false;
+ }
+ ++iter;
+ }
+ theme_colors_ = static_cast<DictionaryValue*>(colors_value->DeepCopy());
+ }
+
+ theme_tints_ = new DictionaryValue;
+ DictionaryValue* tints_value;
+ if (theme_value->GetDictionary(kThemeTintsKey, &tints_value)) {
+ // Validate that the tints are all reals.
+ DictionaryValue::key_iterator iter = tints_value->begin_keys();
+ while (iter != tints_value->end_keys()) {
+ ListValue* tint_list;
+ double hue = 0;
+ if (!tints_value->GetList(*iter, &tint_list) &&
+ tint_list->GetSize() != 3 ||
+ !tint_list->GetReal(0, &hue) ||
+ !tint_list->GetReal(1, &hue) ||
+ !tint_list->GetReal(2, &hue)) {
+ *error = kInvalidThemeTintsError;
+ return false;
+ }
+ ++iter;
+ }
+ theme_tints_ = static_cast<DictionaryValue*>(tints_value->DeepCopy());
+ }
+ return true;
+ }
+
// Initialize plugins dir (optional).
if (source.HasKey(kPluginsDirKey)) {
std::string plugins_dir;
@@ -538,22 +621,6 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_id,
}
}
- if (source.HasKey(kThemeKey)) {
- DictionaryValue* dict_value;
- if (source.GetDictionary(kThemeKey, &dict_value)) {
- DictionaryValue::key_iterator iter = dict_value->begin_keys();
- while (iter != dict_value->end_keys()) {
- std::string val;
- if (dict_value->GetString(*iter, &val)) {
- std::wstring id = *iter;
- theme_paths_[id] = val;
- }
- ++iter;
- }
- ResourceBundle::GetSharedInstance().SetThemeExtension(*this);
- }
- }
-
// Initialize content scripts (optional).
if (source.HasKey(kContentScriptsKey)) {
ListValue* list_value;
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
index c612203..4e19c9a 100644
--- a/chrome/browser/extensions/extension.h
+++ b/chrome/browser/extensions/extension.h
@@ -18,6 +18,7 @@
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/page_action.h"
#include "googleurl/src/gurl.h"
+#include "SkColor.h"
// Represents a Chromium extension.
class Extension {
@@ -45,6 +46,9 @@ class Extension {
static const wchar_t* kBackgroundKey;
static const wchar_t* kRunAtKey;
static const wchar_t* kThemeKey;
+ static const wchar_t* kThemeImagesKey;
+ static const wchar_t* kThemeColorsKey;
+ static const wchar_t* kThemeTintsKey;
static const wchar_t* kToolstripsKey;
static const wchar_t* kTooltipKey;
static const wchar_t* kTypeKey;
@@ -87,6 +91,11 @@ class Extension {
static const char* kInvalidPermissionError;
static const char* kInvalidPermissionSchemeError;
static const char* kInvalidZipHashError;
+ static const char* kInvalidThemeError;
+ static const char* kInvalidThemeImagesMissingError;
+ static const char* kInvalidThemeImagesError;
+ static const char* kInvalidThemeColorsError;
+ static const char* kInvalidThemeTintsError;
static const char* kMissingFileError;
static const char* kMissingPageActionIcon;
@@ -115,19 +124,17 @@ class Extension {
return GetResourcePath(path(), relative_path);
}
+ DictionaryValue* GetThemeImages() { return theme_images_; }
+ DictionaryValue* GetThemeColors() { return theme_colors_; }
+ DictionaryValue* GetThemeTints() { return theme_tints_; }
+ bool IsTheme() { return is_theme_; }
+
// Initialize the extension from a parsed manifest.
// If |require_id| is true, will return an error if the "id" key is missing
// from the value.
bool InitFromValue(const DictionaryValue& value, bool require_id,
std::string* error);
- // Returns an absolute path to a resource inside of an extension if the
- // extension has a theme defined with the given |resource_id|. Otherwise
- // the path will be empty. Note that this method is not static as it is
- // only intended to be called on an extension which has registered itself
- // as providing a theme.
- FilePath GetThemeResourcePath(const int resource_id);
-
// Retrieves a page action by |id|.
const PageAction* GetPageAction(std::string id) const;
@@ -207,7 +214,16 @@ class Extension {
std::string zip_hash_;
// A map of resource id's to relative file paths.
- std::map<const std::wstring, std::string> theme_paths_;
+ DictionaryValue* theme_images_;
+
+ // A map of color names to colors.
+ DictionaryValue* theme_colors_;
+
+ // A map of color names to colors.
+ DictionaryValue* theme_tints_;
+
+ // Whether the extension is a theme - if it is, certain things are disabled.
+ bool is_theme_;
// The sites this extension has permission to talk to (using XHR, etc).
std::vector<URLPattern> permissions_;
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index da5db0f1..2a152e1 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -183,11 +183,30 @@ void ExtensionsService::OnExtensionInstalled(Extension* extension,
NotificationType::EXTENSION_INSTALLED,
NotificationService::AllSources(),
Details<Extension>(extension));
+
+ // If the extension is a theme, tell the profile (and therefore ThemeProvider)
+ // to apply it.
+ if (extension->IsTheme()) {
+ NotificationService::current()->Notify(
+ NotificationType::THEME_INSTALLED,
+ NotificationService::AllSources(),
+ Details<Extension>(extension));
+ }
+}
+
+void ExtensionsService::OnExtensionVersionReinstalled(const std::string& id) {
+ Extension* extension = GetExtensionByID(id);
+ if (extension && extension->IsTheme()) {
+ NotificationService::current()->Notify(
+ NotificationType::THEME_INSTALLED,
+ NotificationService::AllSources(),
+ Details<Extension>(extension));
+ }
}
Extension* ExtensionsService::GetExtensionByID(std::string id) {
for (ExtensionList::const_iterator iter = extensions_.begin();
- iter != extensions_.end(); ++iter) {
+ iter != extensions_.end(); ++iter) {
if ((*iter)->id() == id)
return *iter;
}
@@ -329,7 +348,24 @@ Extension* ExtensionsServiceBackend::LoadExtension(
return NULL;
}
- // Validate that claimed resources actually exist.
+ // Validate that claimed image resources actually exist.
+ DictionaryValue* images_value = extension->GetThemeImages();
+ if (images_value) {
+ DictionaryValue::key_iterator iter = images_value->begin_keys();
+ while (iter != images_value->end_keys()) {
+ std::string val;
+ images_value->GetString(*iter, &val);
+ const FilePath& path = extension->path().AppendASCII(val);
+ if (!file_util::PathExists(path)) {
+ ReportExtensionLoadError(extension_path,
+ StringPrintf("Could not load '%s' for theme.",
+ WideToUTF8(path.ToWStringHack()).c_str()));
+ return NULL;
+ }
+ ++iter;
+ }
+ }
+ // Validate that claimed script resources actually exist.
for (size_t i = 0; i < extension->content_scripts().size(); ++i) {
const UserScript& script = extension->content_scripts()[i];
@@ -532,8 +568,9 @@ bool ExtensionsServiceBackend::CheckCurrentVersion(
// has actually loaded successfully.
FilePath version_dir = dest_dir.AppendASCII(current_version_str);
if (file_util::PathExists(version_dir)) {
- ReportExtensionInstallError(dest_dir,
- "Existing version is already up to date.");
+ std::string id = WideToASCII(dest_dir.BaseName().ToWStringHack());
+ StringToLowerASCII(&id);
+ ReportExtensionVersionReinstalled(id);
return false;
}
}
@@ -727,6 +764,14 @@ void ExtensionsServiceBackend::ReportExtensionInstallError(
ExtensionErrorReporter::GetInstance()->ReportError(message, alert_on_error_);
}
+void ExtensionsServiceBackend::ReportExtensionVersionReinstalled(
+ const std::string& id) {
+ frontend_->GetMessageLoop()->PostTask(FROM_HERE, NewRunnableMethod(
+ frontend_,
+ &ExtensionsServiceFrontendInterface::OnExtensionVersionReinstalled,
+ id));
+}
+
void ExtensionsServiceBackend::ReportExtensionInstalled(
const FilePath& path, bool update) {
// After it's installed, load it right away with the same settings.
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 9a83c99..31b8f90e 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -51,8 +51,15 @@ class ExtensionsServiceFrontendInterface
// installed extension rather than a new installation.
virtual void OnExtensionInstalled(Extension* extension, bool is_update) = 0;
+ // Called when an existing extension is installed by the user. We may wish to
+ // notify the user about the prior existence of the extension, or take some
+ // action using the fact that the user chose to reinstall the extension as a
+ // signal (for example, setting the default theme to the extension).
+ virtual void OnExtensionVersionReinstalled(const std::string& id) = 0;
+
// Lookup an extension by |id|.
virtual Extension* GetExtensionByID(std::string id) = 0;
+
};
@@ -77,6 +84,7 @@ class ExtensionsService : public ExtensionsServiceFrontendInterface {
virtual void OnExtensionsLoaded(ExtensionList* extensions);
virtual void OnExtensionInstalled(Extension* extension, bool is_update);
virtual Extension* GetExtensionByID(std::string id);
+ virtual void OnExtensionVersionReinstalled(const std::string& id);
// The name of the file that the current active version number is stored in.
static const char* kCurrentVersionFileName;
@@ -176,6 +184,9 @@ class ExtensionsServiceBackend
void ReportExtensionInstallError(const FilePath& extension_path,
const std::string& error);
+ // Notify the frontend that the extension had already been installed.
+ void ReportExtensionVersionReinstalled(const std::string& id);
+
// Notify the frontend that extensions were installed.
// |is_update| is true if this was an update to an existing extension.
void ReportExtensionInstalled(const FilePath& path, bool is_update);
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index e6c27df..dc9be78 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -66,10 +66,19 @@ class ExtensionsServiceTestFrontend
return &extensions_;
}
+ void ClearInstalledReinstalled() {
+ installed_ = NULL;
+ reinstalled_id_ = std::string();
+ }
+
Extension* installed() {
return installed_;
}
+ std::string reinstalled_id() {
+ return reinstalled_id_;
+ }
+
// ExtensionsServiceFrontendInterface
virtual MessageLoop* GetMessageLoop() {
return &message_loop_;
@@ -94,6 +103,10 @@ class ExtensionsServiceTestFrontend
installed_ = extension;
}
+ virtual void OnExtensionVersionReinstalled(const std::string& id) {
+ reinstalled_id_ = id;
+ }
+
virtual Extension* GetExtensionByID(std::string id) {
return NULL;
}
@@ -122,11 +135,11 @@ class ExtensionsServiceTestFrontend
ExtensionErrorReporter::GetInstance()->ClearErrors();
}
-
private:
MessageLoop message_loop_;
ExtensionList extensions_;
Extension* installed_;
+ std::string reinstalled_id_;
};
// make the test a PlatformTest to setup autorelease pools properly on mac
@@ -277,9 +290,6 @@ TEST_F(ExtensionsServiceTest, InstallExtension) {
frontend->TestInstallExtension(path, backend, true);
// TODO(erikkay): verify the contents of the installed extension.
- // Installing the same extension twice should fail.
- frontend->TestInstallExtension(path, backend, false);
-
// 0-length extension file.
path = extensions_path.AppendASCII("not_an_extension.crx");
frontend->TestInstallExtension(path, backend, false);
@@ -300,6 +310,65 @@ TEST_F(ExtensionsServiceTest, InstallExtension) {
// TODO(erikkay): add tests for upgrade cases.
}
+TEST_F(ExtensionsServiceTest, ReinstallExtension) {
+ // In this test, we install two extensions, verify that they both install
+ // correctly, then install the first extension again and verify that it was
+ // not installed, and that VersionReinstalled was called instead.
+ FilePath extensions_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
+ extensions_path = extensions_path.AppendASCII("extensions");
+
+ FilePath install_dir;
+ file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("ext_test"),
+ &install_dir);
+ scoped_refptr<ExtensionsServiceBackend> backend(
+ new ExtensionsServiceBackend(install_dir));
+ scoped_refptr<ExtensionsServiceTestFrontend> frontend(
+ new ExtensionsServiceTestFrontend);
+
+ FilePath path = extensions_path.AppendASCII("good.crx");
+ FilePath path2 = extensions_path.AppendASCII("theme.crx");
+
+ // Verify that our extensions are valid.
+ ASSERT_TRUE(file_util::PathExists(path));
+ ASSERT_TRUE(file_util::PathExists(path2));
+
+ frontend->ClearInstalledReinstalled();
+ // Install an extension.
+ backend->InstallExtension(path,
+ scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get()));
+ frontend->GetMessageLoop()->RunAllPending();
+ std::vector<std::string> errors = GetErrors();
+
+ // Verify that it was installed.
+ EXPECT_TRUE(frontend->installed()) << path.value();
+ EXPECT_EQ(0u, errors.size()) << path.value();
+
+ // Install our second extension.
+ frontend->ClearInstalledReinstalled();
+ backend->InstallExtension(path2,
+ scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get()));
+ frontend->GetMessageLoop()->RunAllPending();
+ errors = GetErrors();
+
+ // Verify that it was installed without reinstall getting called.
+ EXPECT_TRUE(frontend->installed()) << path2.value();
+ EXPECT_TRUE(frontend->reinstalled_id().empty());
+ EXPECT_EQ(0u, errors.size()) << path.value();
+
+ // Install the first extension again.
+ frontend->ClearInstalledReinstalled();
+ backend->InstallExtension(path,
+ scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get()));
+ frontend->GetMessageLoop()->RunAllPending();
+ errors = GetErrors();
+
+ // Verify that reinstall was called and installed was not.
+ EXPECT_FALSE(frontend->installed()) << path.value();
+ EXPECT_FALSE(frontend->reinstalled_id().empty()) << path.value();
+ EXPECT_EQ(0u, errors.size()) << path.value();
+}
+
TEST_F(ExtensionsServiceTest, LoadExtension) {
FilePath extensions_path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path));
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index d74b802..d05e39a 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -9,12 +9,14 @@
#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/common/extensions/user_script.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/jstemplate_builder.h"
#include "chrome/common/url_constants.h"
diff --git a/chrome/browser/external_tab_container.h b/chrome/browser/external_tab_container.h
index c0effce..f3a186d 100644
--- a/chrome/browser/external_tab_container.h
+++ b/chrome/browser/external_tab_container.h
@@ -113,6 +113,7 @@ class ExternalTabContainer : public TabContentsDelegate,
virtual gfx::NativeView GetNativeView() const;
virtual void PaintNow(const gfx::Rect& update_rect);
virtual views::RootView* GetRootView();
+ virtual Widget* GetRootWidget() const { return NULL; }
virtual bool IsVisible() const;
virtual bool IsActive() const;
virtual bool GetAccelerator(int cmd_id,
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 86f32b6..9406216 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -28,6 +28,7 @@
#include "chrome/browser/sessions/tab_restore_service.h"
#include "chrome/browser/spellchecker.h"
#include "chrome/browser/ssl/ssl_host_state.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/visitedlink_master.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/common/chrome_constants.h"
@@ -38,7 +39,6 @@
#include "chrome/common/render_messages.h"
#include "grit/locale_settings.h"
-
using base::Time;
using base::TimeDelta;
@@ -59,6 +59,10 @@ void Profile::RegisterUserPrefs(PrefService* prefs) {
IDS_SPELLCHECK_DICTIONARY);
prefs->RegisterBooleanPref(prefs::kEnableSpellCheck, true);
prefs->RegisterBooleanPref(prefs::kEnableUserScripts, false);
+ prefs->RegisterStringPref(prefs::kCurrentThemeID, L"");
+ prefs->RegisterDictionaryPref(prefs::kCurrentThemeImages);
+ prefs->RegisterDictionaryPref(prefs::kCurrentThemeColors);
+ prefs->RegisterDictionaryPref(prefs::kCurrentThemeTints);
prefs->RegisterBooleanPref(prefs::kEnableExtensions, false);
}
@@ -76,7 +80,7 @@ URLRequestContext* Profile::GetDefaultRequestContext() {
////////////////////////////////////////////////////////////////////////////////
//
// OffTheRecordProfileImpl is a profile subclass that wraps an existing profile
-// to make it suitable for the off the record mode.
+// to make it suitable for the off the record mode.
//
////////////////////////////////////////////////////////////////////////////////
class OffTheRecordProfileImpl : public Profile,
@@ -204,6 +208,22 @@ class OffTheRecordProfileImpl : public Profile,
return (download_manager_.get() != NULL);
}
+ virtual void InitThemes() {
+ GetOriginalProfile()->InitThemes();
+ }
+
+ virtual void SetTheme(Extension* extension) {
+ GetOriginalProfile()->SetTheme(extension);
+ }
+
+ virtual void ClearTheme() {
+ GetOriginalProfile()->ClearTheme();
+ }
+
+ virtual ThemeProvider* GetThemeProvider() {
+ return GetOriginalProfile()->GetThemeProvider();
+ }
+
virtual URLRequestContext* GetRequestContext() {
return request_context_;
}
@@ -341,6 +361,9 @@ class OffTheRecordProfileImpl : public Profile,
// The download manager that only stores downloaded items in memory.
scoped_refptr<DownloadManager> download_manager_;
+ // The download manager that only stores downloaded items in memory.
+ scoped_refptr<BrowserThemeProvider> theme_provider_;
+
// We don't want SSLHostState from the OTR profile to leak back to the main
// profile because then the main profile would learn some of the host names
// the user visited while OTR.
@@ -362,6 +385,7 @@ ProfileImpl::ProfileImpl(const FilePath& path)
history_service_created_(false),
created_web_data_service_(false),
created_download_manager_(false),
+ created_theme_provider_(false),
start_time_(Time::Now()),
spellchecker_(NULL),
shutdown_session_service_(false) {
@@ -387,6 +411,10 @@ ProfileImpl::ProfileImpl(const FilePath& path)
prefs->transient()->SetString(prefs::kHomePage, "about:linux-splash");
prefs->transient()->SetBoolean(prefs::kHomePageIsNewTabPage, false);
#endif
+
+ // Listen for theme installation.
+ NotificationService::current()->AddObserver(this,
+ NotificationType::THEME_INSTALLED, NotificationService::AllSources());
}
void ProfileImpl::InitExtensions() {
@@ -440,6 +468,9 @@ ProfileImpl::~ProfileImpl() {
// before the history is shutdown so it can properly cancel all requests.
download_manager_ = NULL;
+ // The theme provider provides bitmaps to whoever wants them.
+ theme_provider_ = NULL;
+
// Remove pref observers.
PrefService* prefs = GetPrefs();
prefs->RemovePrefObserver(prefs::kSpellCheckDictionary, this);
@@ -449,6 +480,10 @@ ProfileImpl::~ProfileImpl() {
personalization_.reset();
#endif
+ // Remove theme observer.
+ NotificationService::current()->RemoveObserver(this,
+ NotificationType::THEME_INSTALLED, NotificationService::AllSources());
+
// Both HistoryService and WebDataService maintain threads for background
// processing. Its possible each thread still has tasks on it that have
// increased the ref count of the service. In such a situation, when we
@@ -731,6 +766,30 @@ bool ProfileImpl::HasCreatedDownloadManager() const {
return created_download_manager_;
}
+void ProfileImpl::InitThemes() {
+ if (!created_theme_provider_) {
+ scoped_refptr<BrowserThemeProvider> themes(new BrowserThemeProvider);
+ themes->Init(this);
+ created_theme_provider_ = true;
+ theme_provider_.swap(themes);
+ }
+}
+
+void ProfileImpl::SetTheme(Extension* extension) {
+ InitThemes();
+ theme_provider_.get()->SetTheme(extension);
+}
+
+void ProfileImpl::ClearTheme() {
+ InitThemes();
+ theme_provider_.get()->UseDefaultTheme();
+}
+
+ThemeProvider* ProfileImpl::GetThemeProvider() {
+ InitThemes();
+ return theme_provider_.get();
+}
+
SessionService* ProfileImpl::GetSessionService() {
if (!session_service_.get() && !shutdown_session_service_) {
session_service_ = new SessionService(this);
@@ -911,6 +970,9 @@ void ProfileImpl::Observe(NotificationType type,
*pref_name_in == prefs::kEnableSpellCheck) {
InitializeSpellChecker(true);
}
+ } else if (NotificationType::THEME_INSTALLED == type) {
+ Extension* extension = Details<Extension>(details).ptr();
+ SetTheme(extension);
}
}
diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h
index 2a96277..a83d76a 100644
--- a/chrome/browser/profile.h
+++ b/chrome/browser/profile.h
@@ -10,6 +10,7 @@
#include <set>
#include <string>
+#include "app/theme_provider.h"
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/scoped_ptr.h"
@@ -22,6 +23,7 @@
class BookmarkModel;
class ChromeURLRequestContext;
class DownloadManager;
+class Extension;
class ExtensionProcessManager;
class ExtensionsService;
class HistoryService;
@@ -33,6 +35,7 @@ class SSLHostState;
class TabRestoreService;
class TemplateURLFetcher;
class TemplateURLModel;
+class BrowserThemeProvider;
class URLRequestContext;
class UserScriptMaster;
class VisitedLinkMaster;
@@ -162,6 +165,18 @@ class Profile {
virtual DownloadManager* GetDownloadManager() = 0;
virtual bool HasCreatedDownloadManager() const = 0;
+ // Init our themes system.
+ virtual void InitThemes() = 0;
+
+ // Set the theme to the specified extension.
+ virtual void SetTheme(Extension* extension) = 0;
+
+ // Clear the theme and reset it to default.
+ virtual void ClearTheme() = 0;
+
+ // Returns or creates the ThemeProvider associated with this profile
+ virtual ThemeProvider* GetThemeProvider() = 0;
+
// Returns the request context information associated with this profile. Call
// this only on the UI thread, since it can send notifications that should
// happen on the UI thread.
@@ -289,6 +304,10 @@ class ProfileImpl : public Profile,
virtual TemplateURLModel* GetTemplateURLModel();
virtual TemplateURLFetcher* GetTemplateURLFetcher();
virtual DownloadManager* GetDownloadManager();
+ virtual void InitThemes();
+ virtual void SetTheme(Extension* extension);
+ virtual void ClearTheme();
+ virtual ThemeProvider* GetThemeProvider();
virtual bool HasCreatedDownloadManager() const;
virtual URLRequestContext* GetRequestContext();
virtual URLRequestContext* GetRequestContextForMedia();
@@ -363,9 +382,11 @@ class ProfileImpl : public Profile,
scoped_refptr<HistoryService> history_service_;
scoped_refptr<WebDataService> web_data_service_;
scoped_refptr<SessionService> session_service_;
+ scoped_refptr<BrowserThemeProvider> theme_provider_;
bool history_service_created_;
bool created_web_data_service_;
bool created_download_manager_;
+ bool created_theme_provider_;
// Whether or not the last session exited cleanly. This is set only once.
bool last_session_exited_cleanly_;
diff --git a/chrome/browser/resources/new_tab.html b/chrome/browser/resources/new_tab.html
index 2b27e00..5daf5c5 100644
--- a/chrome/browser/resources/new_tab.html
+++ b/chrome/browser/resources/new_tab.html
@@ -133,6 +133,8 @@ logEvent('log start');
body {
background-color:white;
margin:0px;
+ background-image:url(chrome-ui://theme/theme_newtab_background);
+ background-repeat:repeat-x;
}
html[firstview='true'] #main {
opacity:0.0;
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc
index 51beca0a..88264f2 100644
--- a/chrome/browser/views/bookmark_bar_view.cc
+++ b/chrome/browser/views/bookmark_bar_view.cc
@@ -87,7 +87,6 @@ static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252);
// Border colors for the BookmarBarView.
static const SkColor kTopBorderColor = SkColorSetRGB(222, 234, 248);
-static const SkColor kBottomBorderColor = SkColorSetRGB(178, 178, 178);
// Background color for when the bookmarks bar is only being displayed on the
// new tab page - this color should match the background color of the new tab
@@ -222,30 +221,6 @@ class BookmarkButton : public views::TextButton {
return event_utils::IsPossibleDispositionEvent(e);
}
- virtual void Paint(ChromeCanvas *canvas) {
- views::TextButton::Paint(canvas);
-
- PaintAnimation(this, canvas, show_animation_->GetCurrentValue());
- }
-
- static void PaintAnimation(views::View* view,
- ChromeCanvas* canvas,
- double animation_value) {
- // Since we can't change the alpha of the button (it contains un-alphable
- // text), we paint the bar background over the front of the button. As the
- // bar background is a gradient, we have to paint the gradient at the
- // size of the parent (hence all the margin math below). We can't use
- // the parent's actual bounds because they differ from what is painted.
- SkPaint paint;
- paint.setAlpha(static_cast<int>((1.0 - animation_value) * 255));
- paint.setShader(skia::CreateGradientShader(0,
- view->height() + kTopMargin + kBottomMargin,
- kTopBorderColor,
- kBackgroundColor))->safeUnref();
- canvas->FillRectInt(0, -kTopMargin, view->width(),
- view->height() + kTopMargin + kBottomMargin, paint);
- }
-
private:
const GURL& url_;
Profile* profile_;
@@ -283,9 +258,6 @@ class BookmarkFolderButton : public views::MenuButton {
virtual void Paint(ChromeCanvas *canvas) {
views::MenuButton::Paint(canvas, false);
-
- BookmarkButton::PaintAnimation(this, canvas,
- show_animation_->GetCurrentValue());
}
private:
@@ -588,7 +560,8 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) {
canvas->FillRectInt(kNewtabBackgroundColor, 0, 0, width(), height());
// Draw the 'bottom' of the toolbar above our bubble.
- canvas->FillRectInt(kBottomBorderColor, 0, 0, width(), 1);
+ canvas->FillRectInt(ResourceBundle::toolbar_separator_color,
+ 0, 0, width(), 1);
SkRect rect;
@@ -632,15 +605,14 @@ void BookmarkBarView::Paint(ChromeCanvas* canvas) {
SkDoubleToScalar(roundness),
SkDoubleToScalar(roundness), border_paint);
} else {
- SkPaint paint;
- paint.setShader(skia::CreateGradientShader(0,
- height(),
- kTopBorderColor,
- kBackgroundColor))->safeUnref();
- canvas->FillRectInt(0, 0, width(), height(), paint);
-
- canvas->FillRectInt(kTopBorderColor, 0, 0, width(), 1);
- canvas->FillRectInt(kBottomBorderColor, 0, height() - 1, width(), 1);
+ gfx::Rect bounds = GetBounds(views::View::APPLY_MIRRORING_TRANSFORMATION);
+
+ // +1 is for toolbar outdent.
+ canvas->TileImageInt(*GetThemeProvider()->
+ GetBitmapNamed(IDR_THEME_TOOLBAR),
+ bounds.x() + 1, bounds.y(), 0, 0, width(), height());
+ canvas->FillRectInt(ResourceBundle::toolbar_separator_color,
+ 0, height() - 1, width(), 1);
}
}
diff --git a/chrome/browser/views/constrained_window_impl.cc b/chrome/browser/views/constrained_window_impl.cc
index cde0327..9b4ee70 100644
--- a/chrome/browser/views/constrained_window_impl.cc
+++ b/chrome/browser/views/constrained_window_impl.cc
@@ -61,16 +61,23 @@ enum {
FRAME_TOP_LEFT_CORNER,
FRAME_TOP_RIGHT_CORNER,
+ FRAME_WINDOW,
+ FRAME_WINDOW_INACTIVE,
+ FRAME_WINDOW_INCOGNITO,
+ FRAME_WINDOW_INCOGNITO_INACTIVE,
+
FRAME_PART_BITMAP_COUNT // Must be last.
};
static const int kXPFramePartIDs[] = {
0,
IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_CONSTRAINED_BOTTOM_CENTER, IDR_CONSTRAINED_BOTTOM_LEFT_CORNER,
- IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER, IDR_CONSTRAINED_LEFT_SIDE,
- IDR_CONSTRAINED_RIGHT_SIDE, IDR_CONSTRAINED_TOP_CENTER,
- IDR_CONSTRAINED_TOP_LEFT_CORNER, IDR_CONSTRAINED_TOP_RIGHT_CORNER,
+ IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER,
+ IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE,
+ IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER,
+ IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER,
+ IDR_THEME_FRAME, IDR_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INCOGNITO,
+ IDR_THEME_FRAME_INCOGNITO_INACTIVE,
0 };
static const int kVistaFramePartIDs[] = {
0,
@@ -79,14 +86,8 @@ static const int kVistaFramePartIDs[] = {
IDR_CONSTRAINED_BOTTOM_RIGHT_CORNER_V, IDR_CONSTRAINED_LEFT_SIDE_V,
IDR_CONSTRAINED_RIGHT_SIDE_V, IDR_CONSTRAINED_TOP_CENTER_V,
IDR_CONSTRAINED_TOP_LEFT_CORNER_V, IDR_CONSTRAINED_TOP_RIGHT_CORNER_V,
- 0 };
-static const int kOTRFramePartIDs[] = {
- 0,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_WINDOW_BOTTOM_CENTER_OTR, IDR_WINDOW_BOTTOM_LEFT_CORNER_OTR,
- IDR_WINDOW_BOTTOM_RIGHT_CORNER_OTR, IDR_WINDOW_LEFT_SIDE_OTR,
- IDR_WINDOW_RIGHT_SIDE_OTR, IDR_WINDOW_TOP_CENTER_OTR,
- IDR_WINDOW_TOP_LEFT_CORNER_OTR, IDR_WINDOW_TOP_RIGHT_CORNER_OTR,
+ IDR_THEME_FRAME, IDR_THEME_FRAME_INACTIVE, IDR_THEME_FRAME_INCOGNITO,
+ IDR_THEME_FRAME_INCOGNITO_INACTIVE,
0 };
class XPWindowResources : public views::WindowResources {
@@ -149,39 +150,8 @@ class VistaWindowResources : public views::WindowResources {
DISALLOW_EVIL_CONSTRUCTORS(VistaWindowResources);
};
-class OTRWindowResources : public views::WindowResources {
- public:
- OTRWindowResources() {
- InitClass();
- }
- virtual ~OTRWindowResources() {}
-
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part_id) const {
- return bitmaps_[part_id];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
- int id = kOTRFramePartIDs[i];
- if (id != 0)
- bitmaps_[i] = rb.GetBitmapNamed(id);
- }
- initialized = true;
- }
- }
-
- static SkBitmap* bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(OTRWindowResources);
-};
-
SkBitmap* XPWindowResources::bitmaps_[];
SkBitmap* VistaWindowResources::bitmaps_[];
-SkBitmap* OTRWindowResources::bitmaps_[];
////////////////////////////////////////////////////////////////////////////////
// ConstrainedWindowFrameView
@@ -299,7 +269,6 @@ const int kTitleCaptionSpacing = 5;
const int kCaptionTopSpacing = 1;
const SkColor kContentsBorderShadow = SkColorSetARGB(51, 0, 0, 0);
-const SkColor kContentsBorderColor = SkColorSetRGB(219, 235, 255);
}
////////////////////////////////////////////////////////////////////////////////
@@ -479,6 +448,29 @@ void ConstrainedWindowFrameView::PaintFrameBorder(ChromeCanvas* canvas) {
resources_->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
SkBitmap* bottom_edge = resources_->GetPartBitmap(FRAME_BOTTOM_EDGE);
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ SkBitmap* theme_frame = rb.GetBitmapNamed(IDR_THEME_FRAME);
+ SkColor frame_color = ResourceBundle::frame_color;
+
+ // Fill with the frame color first so we have a constant background for
+ // areas not covered by the theme image.
+ canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height());
+ // Now fill down the sides
+ canvas->FillRectInt(frame_color,
+ 0, theme_frame->height(),
+ left_edge->width(), height() - theme_frame->height());
+ canvas->FillRectInt(frame_color,
+ width() - right_edge->width(), theme_frame->height(),
+ right_edge->width(), height() - theme_frame->height());
+ // Now fill the bottom area.
+ canvas->FillRectInt(frame_color,
+ left_edge->width(), height() - bottom_edge->height(),
+ width() - left_edge->width() - right_edge->width(),
+ bottom_edge->height());
+
+ // Draw the theme frame.
+ canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
+
// Top.
canvas->DrawBitmapInt(*top_left_corner, 0, 0);
canvas->TileImageInt(*top_edge, top_left_corner->width(), 0,
@@ -526,7 +518,7 @@ void ConstrainedWindowFrameView::PaintClientEdge(ChromeCanvas* canvas) {
frame_shadow_bounds.y(), frame_shadow_bounds.width(),
frame_shadow_bounds.height());
- canvas->FillRectInt(kContentsBorderColor, client_edge_bounds.x(),
+ canvas->FillRectInt(ResourceBundle::toolbar_color, client_edge_bounds.x(),
client_edge_bounds.y(), client_edge_bounds.width(),
client_edge_bounds.height());
}
@@ -565,14 +557,10 @@ gfx::Rect ConstrainedWindowFrameView::CalculateClientAreaBounds(
}
void ConstrainedWindowFrameView::InitWindowResources() {
- if (container_->owner()->profile()->IsOffTheRecord()) {
- resources_.reset(new OTRWindowResources);
+ if (win_util::ShouldUseVistaFrame()) {
+ resources_.reset(new VistaWindowResources);
} else {
- if (win_util::ShouldUseVistaFrame()) {
- resources_.reset(new VistaWindowResources);
- } else {
- resources_.reset(new XPWindowResources);
- }
+ resources_.reset(new XPWindowResources);
}
}
diff --git a/chrome/browser/views/frame/browser_frame.cc b/chrome/browser/views/frame/browser_frame.cc
index c022b6a..0d39521 100644
--- a/chrome/browser/views/frame/browser_frame.cc
+++ b/chrome/browser/views/frame/browser_frame.cc
@@ -9,6 +9,7 @@
#include "app/resource_bundle.h"
#include "app/win_util.h"
+#include "chrome/browser/profile.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/views/frame/browser_root_view.h"
#include "chrome/browser/views/frame/browser_view.h"
@@ -23,10 +24,11 @@ static const int kClientEdgeThickness = 3;
///////////////////////////////////////////////////////////////////////////////
// BrowserFrame, public:
-BrowserFrame::BrowserFrame(BrowserView* browser_view)
+BrowserFrame::BrowserFrame(BrowserView* browser_view, Profile* profile)
: WindowWin(browser_view),
browser_view_(browser_view),
- frame_initialized_(false) {
+ frame_initialized_(false),
+ profile_(profile) {
browser_view_->set_frame(this);
GetNonClientView()->SetFrameView(CreateFrameViewForWindow());
// Don't focus anything on creation, selecting a tab will set the focus.
@@ -60,6 +62,14 @@ void BrowserFrame::UpdateThrobber(bool running) {
browser_frame_view_->UpdateThrobber(running);
}
+ThemeProvider* BrowserFrame::GetThemeProvider() const {
+ return profile_->GetThemeProvider();
+}
+
+ThemeProvider* BrowserFrame::GetDialogThemeProvider() const {
+ return profile_->GetThemeProvider();
+}
+
#if defined(FRAME_WINDOW)
void BrowserFrame::SetBrowserNonClientFrameView(
BrowserNonClientFrameView* view) {
@@ -221,7 +231,6 @@ void BrowserFrame::UpdateFrameAfterFrameChange() {
UpdateDWMFrame();
}
-
views::RootView* BrowserFrame::CreateRootView() {
return new BrowserRootView(this);
}
diff --git a/chrome/browser/views/frame/browser_frame.h b/chrome/browser/views/frame/browser_frame.h
index 140f25e..792e90e 100644
--- a/chrome/browser/views/frame/browser_frame.h
+++ b/chrome/browser/views/frame/browser_frame.h
@@ -10,6 +10,7 @@
class AeroGlassNonClientView;
class BrowserView;
class NonClientFrameView;
+class Profile;
class TabStrip;
// A specialization of the NonClientFrameView object that provides additional
@@ -34,7 +35,7 @@ class BrowserNonClientFrameView : public views::NonClientFrameView {
//
class BrowserFrame : public views::WindowWin {
public:
- explicit BrowserFrame(BrowserView* browser_view);
+ explicit BrowserFrame(BrowserView* browser_view, Profile* profile);
virtual ~BrowserFrame();
// Initialize the frame. Creates the Window.
@@ -51,6 +52,10 @@ class BrowserFrame : public views::WindowWin {
// Tells the frame to update the throbber.
void UpdateThrobber(bool running);
+ // Overridden from views::Widget.
+ virtual ThemeProvider* GetThemeProvider() const;
+ virtual ThemeProvider* GetDialogThemeProvider() const;
+
BrowserView* browser_view() const { return browser_view_; }
#if defined(FRAME_WINDOW)
@@ -92,6 +97,8 @@ class BrowserFrame : public views::WindowWin {
bool frame_initialized_;
+ Profile* profile_;
+
DISALLOW_EVIL_CONSTRUCTORS(BrowserFrame);
};
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index a3acb80..f2f24b5 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -855,6 +855,11 @@ void BrowserView::ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
html_view->window()->Show();
}
+void BrowserView::UserChangedTheme() {
+ frame_->GetRootView()->ThemeChanged();
+ frame_->GetRootView()->SchedulePaint();
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView, BrowserWindowTesting implementation:
@@ -1662,7 +1667,7 @@ void BrowserView::InitClass() {
// static
BrowserWindow* BrowserWindow::CreateBrowserWindow(Browser* browser) {
BrowserView* browser_view = new BrowserView(browser);
- (new BrowserFrame(browser_view))->Init();
+ (new BrowserFrame(browser_view, browser->profile()))->Init();
return browser_view;
}
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index 7357333..40afbc5 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -201,6 +201,7 @@ class BrowserView : public BrowserWindow,
virtual void ConfirmBrowserCloseWithPendingDownloads();
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window);
+ virtual void UserChangedTheme();
// Overridden from BrowserWindowTesting:
virtual BookmarkBarView* GetBookmarkBarView() const;
diff --git a/chrome/browser/views/frame/glass_browser_frame_view.cc b/chrome/browser/views/frame/glass_browser_frame_view.cc
index bbebd3a..6eaf547 100644
--- a/chrome/browser/views/frame/glass_browser_frame_view.cc
+++ b/chrome/browser/views/frame/glass_browser_frame_view.cc
@@ -6,66 +6,15 @@
#include "app/gfx/chrome_canvas.h"
#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
#include "grit/theme_resources.h"
#include "views/window/client_view.h"
#include "views/window/window_resources.h"
-// An enumeration of bitmap resources used by this window.
-enum {
- // Client Edge Border.
- FRAME_CLIENT_EDGE_TOP_LEFT,
- FRAME_CLIENT_EDGE_TOP,
- FRAME_CLIENT_EDGE_TOP_RIGHT,
- FRAME_CLIENT_EDGE_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM,
- FRAME_CLIENT_EDGE_BOTTOM_LEFT,
- FRAME_CLIENT_EDGE_LEFT,
-
- FRAME_PART_BITMAP_COUNT // Must be last.
-};
-
-class GlassBrowserWindowResources {
- public:
- GlassBrowserWindowResources() {
- InitClass();
- }
- virtual ~GlassBrowserWindowResources() { }
-
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER,
- IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE,
- IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER,
- IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE,
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(kFramePartBitmapIds[i]);
-
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(GlassBrowserWindowResources);
-};
-
// static
-SkBitmap* GlassBrowserWindowResources::standard_frame_bitmaps_[];
-
-GlassBrowserWindowResources* GlassBrowserFrameView::resources_ = NULL;
SkBitmap* GlassBrowserFrameView::distributor_logo_ = NULL;
HICON GlassBrowserFrameView::throbber_icons_[
GlassBrowserFrameView::kThrobberIconCount];
@@ -281,23 +230,34 @@ void GlassBrowserFrameView::PaintDistributorLogo(ChromeCanvas* canvas) {
}
void GlassBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
+ ThemeProvider* tp = GetThemeProvider();
+
gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
gfx::Point toolbar_origin(toolbar_bounds.origin());
View::ConvertPointToView(frame_->GetClientView(), this, &toolbar_origin);
toolbar_bounds.set_origin(toolbar_origin);
+ SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR);
+
+ // Draw the toolbar background, setting src_y of the paint to the tab
+ // strip height as the toolbar background begins at the top of the tabs.
+ canvas->TileImageInt(*theme_toolbar,
+ 0, browser_view_->GetTabStripHeight() - 1,
+ toolbar_bounds.x() - 1, toolbar_bounds.y() + 2,
+ toolbar_bounds.width() + 2, theme_toolbar->height());
+
SkBitmap* toolbar_left =
- resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER);
canvas->DrawBitmapInt(*toolbar_left,
toolbar_bounds.x() - toolbar_left->width(),
toolbar_bounds.y());
SkBitmap* toolbar_center =
- resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER);
canvas->TileImageInt(*toolbar_center, toolbar_bounds.x(), toolbar_bounds.y(),
toolbar_bounds.width(), toolbar_center->height());
- canvas->DrawBitmapInt(*resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT),
+ canvas->DrawBitmapInt(*tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER),
toolbar_bounds.right(), toolbar_bounds.y());
}
@@ -314,35 +274,50 @@ void GlassBrowserFrameView::PaintOTRAvatar(ChromeCanvas* canvas) {
}
void GlassBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+
// The client edges start below the toolbar upper corner images regardless
// of how tall the toolbar itself is.
int client_area_top =
frame_->GetClientView()->y() + browser_view_->GetToolbarBounds().y() +
- resources_->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT)->height();
+ rb.GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height();
gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
int client_area_bottom =
std::max(client_area_top, height() - NonClientBorderThickness());
int client_area_height = client_area_bottom - client_area_top;
- SkBitmap* right = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
+ SkBitmap* right = rb.GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE);
canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
right->width(), client_area_height);
+ // Draw the toolbar color so that the one pixel areas down the sides
+ // show the right color even if not covered by the toolbar image.
+ canvas->DrawRectInt(GetThemeProvider()->
+ GetColor(BrowserThemeProvider::COLOR_TOOLBAR),
+ client_area_bounds.x() - 1, client_area_top,
+ client_area_bounds.width() + 1, client_area_bottom - client_area_top);
+
+ // Draw the content/toolbar separator.
+ canvas->DrawLineInt(ResourceBundle::toolbar_separator_color,
+ client_area_bounds.x(), client_area_top,
+ client_area_bounds.x() + client_area_bounds.width(),
+ client_area_top);
+
canvas->DrawBitmapInt(
- *resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT),
+ *rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER),
client_area_bounds.right(), client_area_bottom);
- SkBitmap* bottom = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
+ SkBitmap* bottom = rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER);
canvas->TileImageInt(*bottom, client_area_bounds.x(),
client_area_bottom, client_area_bounds.width(),
bottom->height());
SkBitmap* bottom_left =
- resources_->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
+ rb.GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER);
canvas->DrawBitmapInt(*bottom_left,
client_area_bounds.x() - bottom_left->width(), client_area_bottom);
- SkBitmap* left = resources_->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
+ SkBitmap* left = rb.GetBitmapNamed(IDR_CONTENT_LEFT_SIDE);
canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
client_area_top, left->width(), client_area_height);
}
@@ -437,8 +412,6 @@ void GlassBrowserFrameView::InitThrobberIcons() {
void GlassBrowserFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
- resources_ = new GlassBrowserWindowResources;
-
#if defined(GOOGLE_CHROME_BUILD)
distributor_logo_ = ResourceBundle::GetSharedInstance().
GetBitmapNamed(IDR_DISTRIBUTOR_LOGO);
diff --git a/chrome/browser/views/frame/glass_browser_frame_view.h b/chrome/browser/views/frame/glass_browser_frame_view.h
index d110fe9..3a00db3 100644
--- a/chrome/browser/views/frame/glass_browser_frame_view.h
+++ b/chrome/browser/views/frame/glass_browser_frame_view.h
@@ -10,7 +10,6 @@
#include "views/window/non_client_view.h"
class BrowserView;
-class GlassBrowserWindowResources;
class SkBitmap;
class GlassBrowserFrameView : public BrowserNonClientFrameView {
@@ -95,7 +94,6 @@ class GlassBrowserFrameView : public BrowserNonClientFrameView {
static void InitClass();
static SkBitmap* distributor_logo_;
- static GlassBrowserWindowResources* resources_;
static const int kThrobberIconCount = 24;
static HICON throbber_icons_[kThrobberIconCount];
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.cc b/chrome/browser/views/frame/opaque_browser_frame_view.cc
index 10c604c..317e307 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.cc
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.cc
@@ -9,7 +9,9 @@
#include "app/gfx/path.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
#include "app/win_util.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tabs/tab_strip.h"
@@ -20,244 +22,7 @@
#include "views/widget/root_view.h"
#include "views/window/window_resources.h"
-// An enumeration of bitmap resources used by this window.
-enum {
- // Window Controls.
- FRAME_CLOSE_BUTTON_ICON,
- FRAME_CLOSE_BUTTON_ICON_H,
- FRAME_CLOSE_BUTTON_ICON_P,
- FRAME_CLOSE_BUTTON_ICON_SA,
- FRAME_CLOSE_BUTTON_ICON_SA_H,
- FRAME_CLOSE_BUTTON_ICON_SA_P,
- FRAME_RESTORE_BUTTON_ICON,
- FRAME_RESTORE_BUTTON_ICON_H,
- FRAME_RESTORE_BUTTON_ICON_P,
- FRAME_MAXIMIZE_BUTTON_ICON,
- FRAME_MAXIMIZE_BUTTON_ICON_H,
- FRAME_MAXIMIZE_BUTTON_ICON_P,
- FRAME_MINIMIZE_BUTTON_ICON,
- FRAME_MINIMIZE_BUTTON_ICON_H,
- FRAME_MINIMIZE_BUTTON_ICON_P,
-
- // Window Frame Border.
- FRAME_BOTTOM_EDGE,
- FRAME_BOTTOM_LEFT_CORNER,
- FRAME_BOTTOM_RIGHT_CORNER,
- FRAME_LEFT_EDGE,
- FRAME_RIGHT_EDGE,
- FRAME_TOP_EDGE,
- FRAME_TOP_LEFT_CORNER,
- FRAME_TOP_RIGHT_CORNER,
-
- // Client Edge Border.
- FRAME_CLIENT_EDGE_TOP_LEFT,
- FRAME_CLIENT_EDGE_TOP,
- FRAME_CLIENT_EDGE_TOP_RIGHT,
- FRAME_CLIENT_EDGE_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM,
- FRAME_CLIENT_EDGE_BOTTOM_LEFT,
- FRAME_CLIENT_EDGE_LEFT,
-
- // No-toolbar client edge.
- FRAME_NO_TOOLBAR_TOP_LEFT,
- FRAME_NO_TOOLBAR_TOP_CENTER,
- FRAME_NO_TOOLBAR_TOP_RIGHT,
-
- FRAME_PART_BITMAP_COUNT // Must be last.
-};
-
-class ActiveWindowResources : public views::WindowResources {
- public:
- ActiveWindowResources() {
- InitClass();
- }
- virtual ~ActiveWindowResources() { }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER,
- IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE,
- IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER,
- IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER,
- IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER,
- IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE,
- IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER,
- IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(kFramePartBitmapIds[i]);
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(ActiveWindowResources);
-};
-
-class InactiveWindowResources : public views::WindowResources {
- public:
- InactiveWindowResources() {
- InitClass();
- }
- virtual ~InactiveWindowResources() { }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_DEWINDOW_BOTTOM_CENTER, IDR_DEWINDOW_BOTTOM_LEFT_CORNER,
- IDR_DEWINDOW_BOTTOM_RIGHT_CORNER, IDR_DEWINDOW_LEFT_SIDE,
- IDR_DEWINDOW_RIGHT_SIDE, IDR_DEWINDOW_TOP_CENTER,
- IDR_DEWINDOW_TOP_LEFT_CORNER, IDR_DEWINDOW_TOP_RIGHT_CORNER,
- IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER,
- IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE,
- IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER,
- IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(kFramePartBitmapIds[i]);
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources);
-};
-
-class OTRActiveWindowResources : public views::WindowResources {
- public:
- OTRActiveWindowResources() {
- InitClass();
- }
- virtual ~OTRActiveWindowResources() { }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_WINDOW_BOTTOM_CENTER_OTR, IDR_WINDOW_BOTTOM_LEFT_CORNER_OTR,
- IDR_WINDOW_BOTTOM_RIGHT_CORNER_OTR, IDR_WINDOW_LEFT_SIDE_OTR,
- IDR_WINDOW_RIGHT_SIDE_OTR, IDR_WINDOW_TOP_CENTER_OTR,
- IDR_WINDOW_TOP_LEFT_CORNER_OTR, IDR_WINDOW_TOP_RIGHT_CORNER_OTR,
- IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER,
- IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE,
- IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER,
- IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(kFramePartBitmapIds[i]);
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(OTRActiveWindowResources);
-};
-
-class OTRInactiveWindowResources : public views::WindowResources {
- public:
- OTRInactiveWindowResources() {
- InitClass();
- }
- virtual ~OTRInactiveWindowResources() { }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(views::FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_DEWINDOW_BOTTOM_CENTER_OTR, IDR_DEWINDOW_BOTTOM_LEFT_CORNER_OTR,
- IDR_DEWINDOW_BOTTOM_RIGHT_CORNER_OTR, IDR_DEWINDOW_LEFT_SIDE_OTR,
- IDR_DEWINDOW_RIGHT_SIDE_OTR, IDR_DEWINDOW_TOP_CENTER_OTR,
- IDR_DEWINDOW_TOP_LEFT_CORNER_OTR,
- IDR_DEWINDOW_TOP_RIGHT_CORNER_OTR,
- IDR_CONTENT_TOP_LEFT_CORNER, IDR_CONTENT_TOP_CENTER,
- IDR_CONTENT_TOP_RIGHT_CORNER, IDR_CONTENT_RIGHT_SIDE,
- IDR_CONTENT_BOTTOM_RIGHT_CORNER, IDR_CONTENT_BOTTOM_CENTER,
- IDR_CONTENT_BOTTOM_LEFT_CORNER, IDR_CONTENT_LEFT_SIDE,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(kFramePartBitmapIds[i]);
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(OTRInactiveWindowResources);
-};
-
// static
-SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[];
-SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
-SkBitmap* OTRActiveWindowResources::standard_frame_bitmaps_[];
-SkBitmap* OTRInactiveWindowResources::standard_frame_bitmaps_[];
-
-views::WindowResources* OpaqueBrowserFrameView::active_resources_ = NULL;
-views::WindowResources* OpaqueBrowserFrameView::inactive_resources_ = NULL;
-views::WindowResources* OpaqueBrowserFrameView::active_otr_resources_ = NULL;
-views::WindowResources* OpaqueBrowserFrameView::inactive_otr_resources_ = NULL;
SkBitmap* OpaqueBrowserFrameView::distributor_logo_ = NULL;
ChromeFont* OpaqueBrowserFrameView::title_font_ = NULL;
@@ -341,68 +106,57 @@ OpaqueBrowserFrameView::OpaqueBrowserFrameView(BrowserFrame* frame,
frame_(frame),
browser_view_(browser_view) {
InitClass();
- if (browser_view->IsOffTheRecord()) {
- if (!active_otr_resources_) {
- // Lazy load OTR resources only when we first show an OTR frame.
- active_otr_resources_ = new OTRActiveWindowResources;
- inactive_otr_resources_ = new OTRInactiveWindowResources;
- }
- current_active_resources_ = active_otr_resources_;
- current_inactive_resources_= inactive_otr_resources_;
- } else {
- current_active_resources_ = active_resources_;
- current_inactive_resources_ = inactive_resources_;
- }
- views::WindowResources* resources = current_active_resources_;
+ ThemeProvider* tp = frame_->GetThemeProvider();
+
minimize_button_->SetImage(
views::CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_MINIMIZE));
minimize_button_->SetImage(
views::CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_MINIMIZE_H));
minimize_button_->SetImage(
views::CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_MINIMIZE_P));
minimize_button_->SetAccessibleName(
l10n_util::GetString(IDS_ACCNAME_MINIMIZE));
AddChildView(minimize_button_);
maximize_button_->SetImage(
views::CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_MAXIMIZE));
maximize_button_->SetImage(
views::CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_MAXIMIZE_H));
maximize_button_->SetImage(
views::CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_MAXIMIZE_P));
maximize_button_->SetAccessibleName(
l10n_util::GetString(IDS_ACCNAME_MAXIMIZE));
AddChildView(maximize_button_);
restore_button_->SetImage(
views::CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_RESTORE));
restore_button_->SetImage(
views::CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_RESTORE_H));
restore_button_->SetImage(
views::CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_RESTORE_P));
restore_button_->SetAccessibleName(
l10n_util::GetString(IDS_ACCNAME_RESTORE));
AddChildView(restore_button_);
close_button_->SetImage(
views::CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_CLOSE));
close_button_->SetImage(
views::CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_CLOSE_H));
close_button_->SetImage(
views::CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_CLOSE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_CLOSE_P));
close_button_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE));
AddChildView(close_button_);
@@ -753,17 +507,61 @@ int OpaqueBrowserFrameView::IconSize(int* title_top_spacing_ptr,
}
void OpaqueBrowserFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
- SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
+ ThemeProvider* tp = GetThemeProvider();
+
+ SkBitmap* top_left_corner = tp->GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
- resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
- SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
- SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE);
- SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE);
+ tp->GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
+ SkBitmap* top_edge = tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER);
+ SkBitmap* right_edge = tp->GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE);
+ SkBitmap* left_edge = tp->GetBitmapNamed(IDR_WINDOW_LEFT_SIDE);
SkBitmap* bottom_left_corner =
- resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER);
+ tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
SkBitmap* bottom_right_corner =
- resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
- SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE);
+ tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
+ SkBitmap* bottom_edge = tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER);
+
+
+ // Window frame mode and color
+ SkBitmap* theme_frame;
+ SkColor frame_color;
+ if (!browser_view_->IsOffTheRecord()) {
+ if (frame_->IsActive()) {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME);
+ frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME);
+ } else {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INACTIVE);
+ frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME_INACTIVE);
+ }
+ } else {
+ if (frame_->IsActive()) {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INCOGNITO);
+ frame_color = tp->GetColor(BrowserThemeProvider::COLOR_FRAME_INCOGNITO);
+ } else {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INCOGNITO_INACTIVE);
+ frame_color = tp->GetColor(
+ BrowserThemeProvider::COLOR_FRAME_INCOGNITO_INACTIVE);
+ }
+ }
+
+ // Fill with the frame color first so we have a constant background for
+ // areas not covered by the theme image.
+ canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height());
+ // Now fill down the sides
+ canvas->FillRectInt(frame_color,
+ 0, theme_frame->height(),
+ left_edge->width(), height() - theme_frame->height());
+ canvas->FillRectInt(frame_color,
+ width() - right_edge->width(), theme_frame->height(),
+ right_edge->width(), height() - theme_frame->height());
+ // Now fill the bottom area.
+ canvas->FillRectInt(frame_color,
+ left_edge->width(), height() - bottom_edge->height(),
+ width() - left_edge->width() - right_edge->width(),
+ bottom_edge->height());
+
+ // Draw the theme frame.
+ canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
// Top.
int top_left_height = std::min(top_left_corner->height(),
@@ -804,8 +602,11 @@ void OpaqueBrowserFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
height() - top_left_height - bottom_left_corner->height());
}
+
void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
- SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
+ ThemeProvider* tp = GetThemeProvider();
+
+ SkBitmap* top_edge = tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER);
canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(),
top_edge->height());
@@ -814,7 +615,7 @@ void OpaqueBrowserFrameView::PaintMaximizedFrameBorder(ChromeCanvas* canvas) {
// edge. The graphic we use for this has a built in client edge, so we clip
// it off the bottom.
SkBitmap* top_center =
- resources()->GetPartBitmap(FRAME_NO_TOOLBAR_TOP_CENTER);
+ tp->GetBitmapNamed(IDR_APP_TOP_CENTER);
int edge_height = top_center->height() - kClientEdgeThickness;
canvas->TileImageInt(*top_center, 0,
frame_->GetClientView()->y() - edge_height, width(), edge_height);
@@ -851,19 +652,32 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
if (!browser_view_->IsToolbarVisible())
return;
+ ThemeProvider* tp = GetThemeProvider();
gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
gfx::Point toolbar_origin(toolbar_bounds.origin());
View::ConvertPointToView(frame_->GetClientView(), this, &toolbar_origin);
toolbar_bounds.set_origin(toolbar_origin);
+ int strip_height = browser_view_->GetTabStripHeight();
+ SkBitmap* theme_toolbar = tp->GetBitmapNamed(IDR_THEME_TOOLBAR);
+
+ canvas->TileImageInt(*theme_toolbar,
+ 0, strip_height - 1, // crop src
+ toolbar_bounds.x() - 1, toolbar_bounds.y() + 2,
+ toolbar_bounds.width() + 2, theme_toolbar->height());
+
+ SkBitmap* toolbar_left =
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER);
+ canvas->DrawBitmapInt(*toolbar_left,
+ toolbar_bounds.x() - toolbar_left->width(),
+ toolbar_bounds.y());
+
// Gross hack: We split the toolbar images into two pieces, since sometimes
// (popup mode) the toolbar isn't tall enough to show the whole image. The
// split happens between the top shadow section and the bottom gradient
// section so that we never break the gradient.
int split_point = kFrameShadowThickness * 2;
int bottom_y = toolbar_bounds.y() + split_point;
- SkBitmap* toolbar_left =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
int bottom_edge_height =
std::min(toolbar_left->height(), toolbar_bounds.height()) - split_point;
@@ -876,7 +690,7 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
toolbar_left->width(), bottom_edge_height, false);
SkBitmap* toolbar_center =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
+ tp->GetBitmapNamed(IDR_CONTENT_TOP_CENTER);
canvas->TileImageInt(*toolbar_center, 0, 0, toolbar_bounds.x(),
toolbar_bounds.y(), toolbar_bounds.width(), split_point);
int bottom_center_height =
@@ -885,8 +699,7 @@ void OpaqueBrowserFrameView::PaintToolbarBackground(ChromeCanvas* canvas) {
toolbar_center->height() - bottom_center_height, toolbar_bounds.x(),
bottom_y, toolbar_bounds.width(), bottom_center_height);
- SkBitmap* toolbar_right =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT);
+ SkBitmap* toolbar_right = tp->GetBitmapNamed(IDR_CONTENT_TOP_RIGHT_CORNER);
canvas->DrawBitmapInt(*toolbar_right, 0, 0, toolbar_right->width(),
split_point, toolbar_bounds.right(), toolbar_bounds.y(),
toolbar_right->width(), split_point, false);
@@ -909,6 +722,7 @@ void OpaqueBrowserFrameView::PaintOTRAvatar(ChromeCanvas* canvas) {
}
void OpaqueBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
+ ThemeProvider* tp = GetThemeProvider();
int client_area_top = frame_->GetClientView()->y();
gfx::Rect client_area_bounds = CalculateClientAreaBounds(width(), height());
@@ -916,9 +730,9 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
// The client edges start below the toolbar or its corner images, whichever
// is shorter.
gfx::Rect toolbar_bounds(browser_view_->GetToolbarBounds());
- client_area_top += toolbar_bounds.y() + std::min(
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT)->height(),
- toolbar_bounds.height());
+ client_area_top += browser_view_->GetToolbarBounds().y() +
+ std::min(tp->GetBitmapNamed(IDR_CONTENT_TOP_LEFT_CORNER)->height(),
+ toolbar_bounds.height());
} else {
// The toolbar isn't going to draw a client edge for us, so draw one
// ourselves.
@@ -926,12 +740,11 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
// shorter than the top left and right bitmaps. We need their top edges to
// line up, and we need the left and right edges to start below the corners'
// bottoms.
- SkBitmap* top_left = resources()->GetPartBitmap(FRAME_NO_TOOLBAR_TOP_LEFT);
- SkBitmap* top_center =
- resources()->GetPartBitmap(FRAME_NO_TOOLBAR_TOP_CENTER);
- SkBitmap* top_right =
- resources()->GetPartBitmap(FRAME_NO_TOOLBAR_TOP_RIGHT);
+ SkBitmap* top_left = tp->GetBitmapNamed(IDR_APP_TOP_LEFT);
+ SkBitmap* top_center = tp->GetBitmapNamed(IDR_APP_TOP_CENTER);
+ SkBitmap* top_right = tp->GetBitmapNamed(IDR_APP_TOP_RIGHT);
int top_edge_y = client_area_top - top_center->height();
+
client_area_top = std::min(top_edge_y + top_left->height(),
height() - NonClientBorderThickness());
int height = client_area_top - top_edge_y;
@@ -945,28 +758,42 @@ void OpaqueBrowserFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
top_right->width(), height, false);
}
+
int client_area_bottom =
std::max(client_area_top, height() - NonClientBorderThickness());
int client_area_height = client_area_bottom - client_area_top;
- SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
+
+ // Draw the toolbar color so that the one pixel areas down the sides
+ // show the right color even if not covered by the toolbar image.
+ canvas->DrawRectInt(ResourceBundle::toolbar_color,
+ client_area_bounds.x() - kClientEdgeThickness, client_area_top,
+ client_area_bounds.width() + kClientEdgeThickness,
+ client_area_bottom - client_area_top);
+
+ // Draw the content/toolbar separator.
+ canvas->DrawLineInt(ResourceBundle::toolbar_separator_color,
+ client_area_bounds.x(), client_area_top,
+ client_area_bounds.x() + client_area_bounds.width(),
+ client_area_top);
+
+ SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE);
canvas->TileImageInt(*right, client_area_bounds.right(), client_area_top,
right->width(), client_area_height);
-
canvas->DrawBitmapInt(
- *resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT),
+ *tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER),
client_area_bounds.right(), client_area_bottom);
- SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
+ SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER);
canvas->TileImageInt(*bottom, client_area_bounds.x(),
client_area_bottom, client_area_bounds.width(),
bottom->height());
SkBitmap* bottom_left =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
+ tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER);
canvas->DrawBitmapInt(*bottom_left,
client_area_bounds.x() - bottom_left->width(), client_area_bottom);
- SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
+ SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE);
canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
client_area_top, left->width(), client_area_height);
}
@@ -1102,9 +929,6 @@ gfx::Rect OpaqueBrowserFrameView::CalculateClientAreaBounds(int width,
void OpaqueBrowserFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
- active_resources_ = new ActiveWindowResources;
- inactive_resources_ = new InactiveWindowResources;
-
#if defined(GOOGLE_CHROME_BUILD)
distributor_logo_ = ResourceBundle::GetSharedInstance().
GetBitmapNamed(IDR_DISTRIBUTOR_LOGO_LIGHT);
diff --git a/chrome/browser/views/frame/opaque_browser_frame_view.h b/chrome/browser/views/frame/opaque_browser_frame_view.h
index 1e917e9..08aee7e 100644
--- a/chrome/browser/views/frame/opaque_browser_frame_view.h
+++ b/chrome/browser/views/frame/opaque_browser_frame_view.h
@@ -16,7 +16,6 @@ class TabContents;
class TabStrip;
namespace views {
class ImageButton;
-class WindowResources;
}
class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
@@ -118,12 +117,6 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
// Returns the bounds of the client area for the specified view size.
gfx::Rect CalculateClientAreaBounds(int width, int height) const;
- // Returns the set of resources to use to paint this view.
- views::WindowResources* resources() const {
- return frame_->IsActive() || paint_as_active() ?
- current_active_resources_ : current_inactive_resources_;
- }
-
// The layout rect of the title, if visible.
gfx::Rect title_bounds_;
@@ -151,20 +144,12 @@ class OpaqueBrowserFrameView : public BrowserNonClientFrameView,
// The bounds of the ClientView.
gfx::Rect client_view_bounds_;
- // The resources currently used to paint this view.
- views::WindowResources* current_active_resources_;
- views::WindowResources* current_inactive_resources_;
-
// The accessible name of this view.
std::wstring accessible_name_;
static void InitClass();
static void InitAppWindowResources();
static SkBitmap* distributor_logo_;
- static views::WindowResources* active_resources_;
- static views::WindowResources* inactive_resources_;
- static views::WindowResources* active_otr_resources_;
- static views::WindowResources* inactive_otr_resources_;
static ChromeFont* title_font_;
DISALLOW_EVIL_CONSTRUCTORS(OpaqueBrowserFrameView);
diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc
index 4a04040..6749dec 100644
--- a/chrome/browser/views/infobars/infobars.cc
+++ b/chrome/browser/views/infobars/infobars.cc
@@ -34,7 +34,6 @@ static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183);
static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145);
static const int kSeparatorLineHeight = 1;
-static const SkColor kSeparatorColor = SkColorSetRGB(165, 165, 165);
namespace {
// Returns a centered y-position of a control of height specified in |prefsize|
@@ -70,7 +69,7 @@ class InfoBarBackground : public views::Background {
gradient_background_->Paint(canvas, view);
// Now paint the separator line.
- canvas->FillRectInt(kSeparatorColor, 0,
+ canvas->FillRectInt(ResourceBundle::toolbar_separator_color, 0,
view->height() - kSeparatorLineHeight, view->width(),
kSeparatorLineHeight);
}
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
index c1354f1..8490c58 100644
--- a/chrome/browser/views/location_bar_view.cc
+++ b/chrome/browser/views/location_bar_view.cc
@@ -16,6 +16,7 @@
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/command_updater.h"
+#include "chrome/browser/extensions/extension.h"
#include "chrome/browser/extensions/extension_browser_event_router.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extensions_service.h"
@@ -27,6 +28,7 @@
#include "chrome/browser/views/info_bubble.h"
#include "chrome/browser/views/first_run_bubble.h"
#include "chrome/browser/views/page_info_window.h"
+#include "chrome/common/page_action.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "views/background.h"
diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc
index 6e3aff2..badd2f6 100644
--- a/chrome/browser/views/options/content_page_view.cc
+++ b/chrome/browser/views/options/content_page_view.cc
@@ -12,6 +12,7 @@
#include "app/gfx/chrome_canvas.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/gfx/native_theme.h"
#include "chrome/browser/browser_process.h"
@@ -19,6 +20,7 @@
#include "chrome/browser/views/options/fonts_languages_window_view.h"
#include "chrome/browser/views/options/options_group_view.h"
#include "chrome/browser/views/options/passwords_exceptions_window_view.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "grit/generated_resources.h"
@@ -181,6 +183,8 @@ ContentPageView::ContentPageView(Profile* profile)
passwords_neversave_radio_(NULL),
fonts_lang_group_(NULL),
fonts_and_languages_label_(NULL),
+ themes_group_(NULL),
+ themes_reset_button_(NULL),
change_content_fonts_button_(NULL),
OptionsPageView(profile) {
}
@@ -257,6 +261,9 @@ void ContentPageView::ButtonPressed(views::Button* sender) {
GetRootWindow(),
gfx::Rect(),
new FontsLanguagesWindowView(profile()))->Show();
+ } else if (sender == themes_reset_button_) {
+ UserMetricsRecordAction(L"Options_ThemesReset", profile()->GetPrefs());
+ profile()->ClearTheme();
}
}
@@ -299,6 +306,14 @@ void ContentPageView::InitControlLayout() {
layout->AddView(form_autofill_group_);
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ if (CommandLine::ForCurrentProcess()->
+ HasSwitch(switches::kEnableExtensions)) {
+ layout->StartRow(0, single_column_view_set_id);
+ InitThemesGroup();
+ layout->AddView(themes_group_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ }
+
// Init member prefs so we can update the controls if prefs change.
default_download_location_.Init(prefs::kDownloadDefaultDirectory,
profile()->GetPrefs(), this);
@@ -445,6 +460,39 @@ void ContentPageView::InitPasswordSavingGroup() {
true);
}
+void ContentPageView::InitFontsLangGroup() {
+ fonts_and_languages_label_ = new views::Label(
+ l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_INFO));
+ fonts_and_languages_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
+ fonts_and_languages_label_->SetMultiLine(true);
+ change_content_fonts_button_ = new views::NativeButton(
+ this,
+ l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_CONFIGUREFONTS_BUTTON));
+
+ using views::GridLayout;
+ using views::ColumnSet;
+
+ views::View* contents = new views::View;
+ GridLayout* layout = new GridLayout(contents);
+ contents->SetLayoutManager(layout);
+
+ const int single_column_view_set_id = 1;
+ ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
+ column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
+ GridLayout::USE_PREF, 0, 0);
+
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(fonts_and_languages_label_);
+ layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
+ layout->StartRow(0, single_column_view_set_id);
+ layout->AddView(change_content_fonts_button_);
+
+ fonts_lang_group_ = new OptionsGroupView(
+ contents,
+ l10n_util::GetString(IDS_OPTIONS_FONTSANDLANGUAGES_GROUP_NAME),
+ L"", true);
+}
+
void ContentPageView::InitFormAutofillGroup() {
form_autofill_checkbox_ = new views::Checkbox(
l10n_util::GetString(IDS_AUTOFILL_SAVEFORMS));
@@ -468,17 +516,12 @@ void ContentPageView::InitFormAutofillGroup() {
form_autofill_group_ = new OptionsGroupView(
contents, l10n_util::GetString(IDS_AUTOFILL_SETTING_WINDOWS_GROUP_NAME),
- L"", false);
+ L"", true);
}
-void ContentPageView::InitFontsLangGroup() {
- fonts_and_languages_label_ = new views::Label(
- l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_INFO));
- fonts_and_languages_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- fonts_and_languages_label_->SetMultiLine(true);
- change_content_fonts_button_ = new views::NativeButton(
- this,
- l10n_util::GetString(IDS_OPTIONS_FONTSETTINGS_CONFIGUREFONTS_BUTTON));
+void ContentPageView::InitThemesGroup() {
+ themes_reset_button_ = new views::NativeButton(this,
+ l10n_util::GetString(IDS_THEMES_RESET_BUTTON));
using views::GridLayout;
using views::ColumnSet;
@@ -490,18 +533,14 @@ void ContentPageView::InitFontsLangGroup() {
const int single_column_view_set_id = 1;
ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
+ GridLayout::USE_PREF, 0, 0);
layout->StartRow(0, single_column_view_set_id);
- layout->AddView(fonts_and_languages_label_);
- layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
- layout->StartRow(0, single_column_view_set_id);
- layout->AddView(change_content_fonts_button_);
+ layout->AddView(themes_reset_button_);
- fonts_lang_group_ = new OptionsGroupView(
- contents,
- l10n_util::GetString(IDS_OPTIONS_FONTSANDLANGUAGES_GROUP_NAME),
- L"", true);
+ themes_group_ = new OptionsGroupView(
+ contents, l10n_util::GetString(IDS_THEMES_GROUP_NAME),
+ L"", false);
}
void ContentPageView::UpdateDownloadDirectoryDisplay() {
diff --git a/chrome/browser/views/options/content_page_view.h b/chrome/browser/views/options/content_page_view.h
index 7d96e00..ff133e3 100644
--- a/chrome/browser/views/options/content_page_view.h
+++ b/chrome/browser/views/options/content_page_view.h
@@ -51,8 +51,9 @@ class ContentPageView : public OptionsPageView,
// Init all the dialog controls.
void InitDownloadLocation();
void InitPasswordSavingGroup();
- void InitFormAutofillGroup();
void InitFontsLangGroup();
+ void InitFormAutofillGroup();
+ void InitThemesGroup();
// Updates the directory displayed in the default download location view with
// the current value of the pref.
@@ -71,20 +72,24 @@ class ContentPageView : public OptionsPageView,
views::RadioButton* passwords_asktosave_radio_;
views::RadioButton* passwords_neversave_radio_;
+ // Controls for the Fonts and Languages group.
+ OptionsGroupView* fonts_lang_group_;
+ views::Label* fonts_and_languages_label_;
+ views::NativeButton* change_content_fonts_button_;
+
// Controls for the Form Autofill group
OptionsGroupView* form_autofill_group_;
views::Checkbox* form_autofill_checkbox_;
+ // Controls for the Themes group
+ OptionsGroupView* themes_group_;
+ views::NativeButton* themes_reset_button_;
+
// Controls for the Popup Blocking group.
OptionsGroupView* popups_group_;
views::RadioButton* popups_show_minimized_radio_;
views::RadioButton* popups_block_all_radio_;
- // Controls for the Fonts and Languages group.
- OptionsGroupView* fonts_lang_group_;
- views::Label* fonts_and_languages_label_;
- views::NativeButton* change_content_fonts_button_;
-
StringPrefMember default_download_location_;
BooleanPrefMember ask_for_save_location_;
BooleanPrefMember ask_to_save_passwords_;
diff --git a/chrome/browser/views/options/cookies_view.cc b/chrome/browser/views/options/cookies_view.cc
index 593487b..cc8d65c 100644
--- a/chrome/browser/views/options/cookies_view.cc
+++ b/chrome/browser/views/options/cookies_view.cc
@@ -10,6 +10,7 @@
#include "app/gfx/color_utils.h"
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
+#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/time_format.h"
#include "chrome/browser/profile.h"
diff --git a/chrome/browser/views/tabs/tab_renderer.cc b/chrome/browser/views/tabs/tab_renderer.cc
index 87d0d01..e7b664b 100644
--- a/chrome/browser/views/tabs/tab_renderer.cc
+++ b/chrome/browser/views/tabs/tab_renderer.cc
@@ -12,6 +12,7 @@
#include "app/resource_bundle.h"
#include "app/win_util.h"
#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
@@ -43,7 +44,6 @@ static const int kPulseDurationMs = 200;
// How opaque to make the hover state (out of 1).
static const double kHoverOpacity = 0.33;
-static const double kHoverOpacityVista = 0.7;
// TODO(beng): (Cleanup) This stuff should move onto the class.
static ChromeFont* title_font = NULL;
@@ -53,6 +53,7 @@ static SkBitmap* close_button_h = NULL;
static SkBitmap* close_button_p = NULL;
static int close_button_height = 0;
static int close_button_width = 0;
+
static SkBitmap* waiting_animation_frames = NULL;
static SkBitmap* loading_animation_frames = NULL;
static SkBitmap* crashed_fav_icon = NULL;
@@ -63,16 +64,16 @@ static SkBitmap* download_icon = NULL;
static int download_icon_width = 0;
static int download_icon_height = 0;
+TabRenderer::TabImage TabRenderer::tab_alpha = {0};
TabRenderer::TabImage TabRenderer::tab_active = {0};
TabRenderer::TabImage TabRenderer::tab_inactive = {0};
-TabRenderer::TabImage TabRenderer::tab_inactive_otr = {0};
-TabRenderer::TabImage TabRenderer::tab_hover = {0};
namespace {
void InitResources() {
static bool initialized = false;
if (!initialized) {
+ // TODO(glen): Allow theming of these.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
title_font = new ChromeFont(rb.GetFont(ResourceBundle::BaseFont));
title_font_height = title_font->height();
@@ -83,7 +84,7 @@ void InitResources() {
close_button_width = close_button_n->width();
close_button_height = close_button_n->height();
- TabRenderer::LoadTabImages(win_util::ShouldUseVistaFrame());
+ TabRenderer::LoadTabImages();
// The loading animation image is a strip of states. Each state must be
// square, so the height must divide the width evenly.
@@ -215,7 +216,8 @@ TabRenderer::TabRenderer()
showing_close_button_(false),
crash_animation_(NULL),
fav_icon_hiding_offset_(0),
- should_display_crashed_favicon_(false) {
+ should_display_crashed_favicon_(false),
+ theme_provider_(NULL) {
InitResources();
// Add the Close Button.
@@ -236,6 +238,24 @@ TabRenderer::~TabRenderer() {
delete crash_animation_;
}
+void TabRenderer::ViewHierarchyChanged(bool is_add, View* parent, View* child) {
+ if (parent->GetThemeProvider())
+ SetThemeProvider(parent->GetThemeProvider());
+}
+
+ThemeProvider* TabRenderer::GetThemeProvider() {
+ ThemeProvider* tp = View::GetThemeProvider();
+ if (tp)
+ return tp;
+
+ if (theme_provider_)
+ return theme_provider_;
+
+ // return contents->profile()->GetThemeProvider();
+ NOTREACHED() << "Unable to find a theme provider";
+ return NULL;
+}
+
void TabRenderer::UpdateData(TabContents* contents, bool loading_only) {
DCHECK(contents);
if (!loading_only) {
@@ -246,6 +266,9 @@ void TabRenderer::UpdateData(TabContents* contents, bool loading_only) {
data_.favicon = contents->GetFavIcon();
}
+ // TODO(glen): Temporary hax.
+ theme_provider_ = contents->profile()->GetThemeProvider();
+
// Loading state also involves whether we show the favicon, since that's where
// we display the throbber.
data_.loading = contents->is_loading();
@@ -411,8 +434,11 @@ void TabRenderer::Paint(ChromeCanvas* canvas) {
Browser::FormatTitleForDisplay(&title);
}
- SkColor title_color = IsSelected() ? kSelectedTitleColor
- : kUnselectedTitleColor;
+ SkColor title_color = GetThemeProvider()->
+ GetColor(IsSelected() ?
+ BrowserThemeProvider::COLOR_TAB_TEXT :
+ BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT);
+
canvas->DrawStringInt(title, *title_font, title_color, title_bounds_.x(),
title_bounds_.y(), title_bounds_.width(),
title_bounds_.height());
@@ -507,8 +533,7 @@ void TabRenderer::OnMouseExited(const views::MouseEvent& e) {
}
void TabRenderer::ThemeChanged() {
- if (GetWindow())
- LoadTabImages(GetWindow()->GetNonClientView()->UseNativeFrame());
+ LoadTabImages();
View::ThemeChanged();
}
@@ -541,33 +566,111 @@ void TabRenderer::PaintTabBackground(ChromeCanvas* canvas) {
Animation* animation = hover_animation_.get();
if (pulse_animation_->IsAnimating())
animation = pulse_animation_.get();
+
+ PaintInactiveTabBackground(canvas);
if (animation->GetCurrentValue() > 0) {
- PaintHoverTabBackground(canvas, animation->GetCurrentValue() *
- (GetWindow()->GetNonClientView()->UseNativeFrame() ?
- kHoverOpacityVista : kHoverOpacity));
- } else {
- PaintInactiveTabBackground(canvas);
+ SkRect bounds;
+ bounds.set(0, 0, SkIntToScalar(width()), SkIntToScalar(height()));
+ canvas->saveLayerAlpha(&bounds,
+ static_cast<int>(animation->GetCurrentValue() * kHoverOpacity * 0xff),
+ SkCanvas::kARGB_ClipLayer_SaveFlag);
+ canvas->drawARGB(0, 255, 255, 255, SkPorterDuff::kClear_Mode);
+ PaintActiveTabBackground(canvas);
+ canvas->restore();
}
}
}
void TabRenderer::PaintInactiveTabBackground(ChromeCanvas* canvas) {
bool is_otr = data_.off_the_record;
- canvas->DrawBitmapInt(is_otr ? *tab_inactive_otr.image_l :
- *tab_inactive.image_l, 0, 0);
- canvas->TileImageInt(is_otr ? *tab_inactive_otr.image_c :
- *tab_inactive.image_c, tab_inactive.l_width, 0,
- width() - tab_inactive.l_width -
- tab_inactive.r_width, height());
- canvas->DrawBitmapInt(is_otr ? *tab_inactive_otr.image_r :
- *tab_inactive.image_r,
+
+ // The tab image needs to be lined up with the background image
+ // so that it feels partially transparent.
+ int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + 1;
+ int offset_y = 20;
+
+ int tab_id;
+ if (GetWidget() &&
+ GetWidget()->GetWindow()->GetNonClientView()->UseNativeFrame()) {
+ tab_id = IDR_THEME_TAB_BACKGROUND_V;
+ } else {
+ tab_id = is_otr ? IDR_THEME_TAB_BACKGROUND_INCOGNITO :
+ IDR_THEME_TAB_BACKGROUND;
+ }
+
+ SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(tab_id);
+
+ // Draw left edge.
+ SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg, offset, offset_y,
+ tab_active.l_width, height());
+ SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap(
+ tab_l, *tab_alpha.image_l);
+ canvas->DrawBitmapInt(theme_l,
+ 0, 0, theme_l.width(), theme_l.height() - 1,
+ 0, 0, theme_l.width(), theme_l.height() - 1,
+ false);
+
+ // Draw right edge.
+ SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg,
+ offset + width() - tab_active.r_width, offset_y,
+ tab_active.r_width, height());
+ SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap(
+ tab_r, *tab_alpha.image_r);
+ canvas->DrawBitmapInt(theme_r,
+ 0, 0, theme_r.width(), theme_r.height() - 1,
+ width() - theme_r.width(), 0, theme_r.width(), theme_r.height() - 1,
+ false);
+
+ // Draw center.
+ canvas->TileImageInt(*tab_bg,
+ offset + tab_active.l_width, 2 + offset_y, // 2 is the drop shadow offset.
+ tab_active.l_width, 2,
+ width() - tab_active.l_width - tab_active.r_width, height() - 3);
+
+ canvas->DrawBitmapInt(*tab_inactive.image_l, 0, 0);
+ canvas->TileImageInt(*tab_inactive.image_c,
+ tab_inactive.l_width, 0,
+ width() - tab_inactive.l_width - tab_inactive.r_width,
+ height());
+ canvas->DrawBitmapInt(*tab_inactive.image_r,
width() - tab_inactive.r_width, 0);
}
void TabRenderer::PaintActiveTabBackground(ChromeCanvas* canvas) {
+ int offset = GetX(views::View::APPLY_MIRRORING_TRANSFORMATION) + 1;
+ ThemeProvider* tp = GetThemeProvider();
+ if (!tp)
+ NOTREACHED() << "Unable to get theme provider";
+
+ SkBitmap* tab_bg = GetThemeProvider()->GetBitmapNamed(IDR_THEME_TOOLBAR);
+
+ // Draw left edge.
+ SkBitmap tab_l = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg, offset, 0, tab_active.l_width, height());
+ SkBitmap theme_l = skia::ImageOperations::CreateMaskedBitmap(
+ tab_l, *tab_alpha.image_l);
+ canvas->DrawBitmapInt(theme_l, 0, 0);
+
+ // Draw right edge.
+ SkBitmap tab_r = skia::ImageOperations::CreateTiledBitmap(
+ *tab_bg,
+ offset + width() - tab_active.r_width, 0,
+ tab_active.r_width, height());
+ SkBitmap theme_r = skia::ImageOperations::CreateMaskedBitmap(
+ tab_r, *tab_alpha.image_r);
+ canvas->DrawBitmapInt(theme_r, width() - tab_active.r_width, 0);
+
+ // Draw center.
+ canvas->TileImageInt(*tab_bg,
+ offset + tab_active.l_width, 2,
+ tab_active.l_width, 2,
+ width() - tab_active.l_width - tab_active.r_width, height() - 2);
+
canvas->DrawBitmapInt(*tab_active.image_l, 0, 0);
canvas->TileImageInt(*tab_active.image_c, tab_active.l_width, 0,
- width() - tab_active.l_width - tab_active.r_width, height());
+ width() - tab_active.l_width - tab_active.r_width, height());
canvas->DrawBitmapInt(*tab_active.image_r, width() - tab_active.r_width, 0);
}
@@ -575,15 +678,11 @@ void TabRenderer::PaintHoverTabBackground(ChromeCanvas* canvas,
double opacity) {
bool is_otr = data_.off_the_record;
SkBitmap left = skia::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr.image_l :
- *tab_inactive.image_l), *tab_hover.image_l, opacity);
+ *tab_inactive.image_l, *tab_active.image_l, opacity);
SkBitmap center = skia::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr.image_c :
- *tab_inactive.image_c), *tab_hover.image_c, opacity);
+ *tab_inactive.image_c, *tab_active.image_c, opacity);
SkBitmap right = skia::ImageOperations::CreateBlendedBitmap(
- (is_otr ? *tab_inactive_otr.image_r :
- *tab_inactive.image_r),
- *tab_hover.image_r, opacity);
+ *tab_inactive.image_r, *tab_active.image_r, opacity);
canvas->DrawBitmapInt(left, 0, 0);
canvas->TileImageInt(center, tab_active.l_width, 0,
@@ -668,41 +767,26 @@ void TabRenderer::ResetCrashedFavIcon() {
}
// static
-void TabRenderer::LoadTabImages(bool use_vista_images) {
+void TabRenderer::LoadTabImages() {
+ // We're not letting people override tab images just yet.
ResourceBundle& rb = ResourceBundle::GetSharedInstance();
+ tab_alpha.image_l = rb.GetBitmapNamed(IDR_TAB_ALPHA_LEFT);
+ tab_alpha.image_r = rb.GetBitmapNamed(IDR_TAB_ALPHA_RIGHT);
+
tab_active.image_l = rb.GetBitmapNamed(IDR_TAB_ACTIVE_LEFT);
tab_active.image_c = rb.GetBitmapNamed(IDR_TAB_ACTIVE_CENTER);
tab_active.image_r = rb.GetBitmapNamed(IDR_TAB_ACTIVE_RIGHT);
tab_active.l_width = tab_active.image_l->width();
tab_active.r_width = tab_active.image_r->width();
- tab_hover.image_l = rb.GetBitmapNamed(IDR_TAB_HOVER_LEFT);
- tab_hover.image_c = rb.GetBitmapNamed(IDR_TAB_HOVER_CENTER);
- tab_hover.image_r = rb.GetBitmapNamed(IDR_TAB_HOVER_RIGHT);
-
- if (use_vista_images) {
- tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
-
- // Our Vista frame doesn't change background color to show OTR,
- // so we continue to use the existing background tabs.
- tab_inactive_otr.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_V);
- tab_inactive_otr.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_V);
- tab_inactive_otr.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_V);
- } else {
- tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
- tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
- tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
-
- tab_inactive_otr.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT_OTR);
- tab_inactive_otr.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER_OTR);
- tab_inactive_otr.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT_OTR);
- }
+ tab_inactive.image_l = rb.GetBitmapNamed(IDR_TAB_INACTIVE_LEFT);
+ tab_inactive.image_c = rb.GetBitmapNamed(IDR_TAB_INACTIVE_CENTER);
+ tab_inactive.image_r = rb.GetBitmapNamed(IDR_TAB_INACTIVE_RIGHT);
tab_inactive.l_width = tab_inactive.image_l->width();
tab_inactive.r_width = tab_inactive.image_r->width();
- // tab_[hover,inactive_otr] width are not used and are initialized to 0
- // during static initialization.
+
+ loading_animation_frames = rb.GetBitmapNamed(IDR_THROBBER);
+ waiting_animation_frames = rb.GetBitmapNamed(IDR_THROBBER_WAITING);
}
diff --git a/chrome/browser/views/tabs/tab_renderer.h b/chrome/browser/views/tabs/tab_renderer.h
index f498c2a..d278fb5 100644
--- a/chrome/browser/views/tabs/tab_renderer.h
+++ b/chrome/browser/views/tabs/tab_renderer.h
@@ -36,6 +36,10 @@ class TabRenderer : public views::View,
TabRenderer();
virtual ~TabRenderer();
+ // Overridden from views:
+ void ViewHierarchyChanged(bool is_add, View* parent, View* child);
+ ThemeProvider* GetThemeProvider();
+
// Updates the data the Tab uses to render itself from the specified
// TabContents.
//
@@ -56,6 +60,13 @@ class TabRenderer : public views::View,
void StartPulse();
void StopPulse();
+ // Set the theme provider - because we get detached, we are frequently
+ // outside of a hierarchy with a theme provider at the top. This should be
+ // called whenever we're detached or attached to a hierarchy.
+ void SetThemeProvider(ThemeProvider* provider) {
+ theme_provider_ = provider;
+ }
+
// Returns the minimum possible size of a single unselected Tab.
static gfx::Size GetMinimumUnselectedSize();
// Returns the minimum possible size of a selected Tab. Selected tabs must
@@ -66,9 +77,8 @@ class TabRenderer : public views::View,
// available.
static gfx::Size GetStandardSize();
- // Loads the images to be used for the tab background. Uses the images for
- // Vista if |use_vista_images| is true.
- static void LoadTabImages(bool use_vista_images);
+ // Loads the images to be used for the tab background.
+ static void LoadTabImages();
protected:
views::ImageButton* close_button() const { return close_button_; }
@@ -166,7 +176,7 @@ class TabRenderer : public views::View,
};
static TabImage tab_active;
static TabImage tab_inactive;
- static TabImage tab_inactive_otr;
+ static TabImage tab_alpha;
static TabImage tab_hover;
// Whether we're showing the icon. It is cached so that we can detect when it
@@ -189,6 +199,8 @@ class TabRenderer : public views::View,
bool should_display_crashed_favicon_;
+ ThemeProvider* theme_provider_;
+
static void InitClass();
static bool initialized_;
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc
index c3c98d2..333dcf4 100644
--- a/chrome/browser/views/toolbar_view.cc
+++ b/chrome/browser/views/toolbar_view.cc
@@ -23,6 +23,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
+#include "chrome/browser/browser_theme_provider.h"
#include "chrome/browser/user_data_manager.h"
#include "chrome/browser/views/bookmark_menu_button.h"
#include "chrome/browser/views/dom_view.h"
@@ -138,86 +139,49 @@ void BrowserToolbarView::SetProfile(Profile* profile) {
}
void BrowserToolbarView::CreateLeftSideControls() {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
-
back_ = new views::ButtonDropDown(this, back_menu_model_.get());
back_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN |
views::Event::EF_MIDDLE_BUTTON_DOWN);
back_->set_tag(IDC_BACK);
back_->SetImageAlignment(views::ImageButton::ALIGN_RIGHT,
views::ImageButton::ALIGN_TOP);
- back_->SetImage(views::CustomButton::BS_NORMAL, rb.GetBitmapNamed(IDR_BACK));
- back_->SetImage(views::CustomButton::BS_HOT, rb.GetBitmapNamed(IDR_BACK_H));
- back_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_BACK_P));
- back_->SetImage(views::CustomButton::BS_DISABLED,
- rb.GetBitmapNamed(IDR_BACK_D));
back_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_BACK));
back_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_BACK));
back_->SetID(VIEW_ID_BACK_BUTTON);
- AddChildView(back_);
forward_ = new views::ButtonDropDown(this, forward_menu_model_.get());
forward_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN |
- views::Event::EF_MIDDLE_BUTTON_DOWN);
+ views::Event::EF_MIDDLE_BUTTON_DOWN);
forward_->set_tag(IDC_FORWARD);
- forward_->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_FORWARD));
- forward_->SetImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_FORWARD_H));
- forward_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_FORWARD_P));
- forward_->SetImage(views::CustomButton::BS_DISABLED,
- rb.GetBitmapNamed(IDR_FORWARD_D));
forward_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_FORWARD));
forward_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_FORWARD));
forward_->SetID(VIEW_ID_FORWARD_BUTTON);
- AddChildView(forward_);
reload_ = new views::ImageButton(this);
reload_->set_tag(IDC_RELOAD);
- reload_->SetImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_RELOAD));
- reload_->SetImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_RELOAD_H));
- reload_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_RELOAD_P));
reload_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_RELOAD));
reload_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_RELOAD));
reload_->SetID(VIEW_ID_RELOAD_BUTTON);
- AddChildView(reload_);
home_ = new views::ImageButton(this);
home_->set_triggerable_event_flags(views::Event::EF_LEFT_BUTTON_DOWN |
views::Event::EF_MIDDLE_BUTTON_DOWN);
home_->set_tag(IDC_HOME);
- home_->SetImage(views::CustomButton::BS_NORMAL, rb.GetBitmapNamed(IDR_HOME));
- home_->SetImage(views::CustomButton::BS_HOT, rb.GetBitmapNamed(IDR_HOME_H));
- home_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_HOME_P));
home_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_HOME));
home_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_HOME));
home_->SetID(VIEW_ID_HOME_BUTTON);
+
+ LoadLeftSideControlsImages();
+
+ AddChildView(back_);
+ AddChildView(forward_);
+ AddChildView(reload_);
AddChildView(home_);
}
void BrowserToolbarView::CreateCenterStack(Profile *profile) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
-
star_ = new ToolbarStarToggle(this, this);
star_->set_tag(IDC_STAR);
- star_->SetImage(views::CustomButton::BS_NORMAL, rb.GetBitmapNamed(IDR_STAR));
- star_->SetImage(views::CustomButton::BS_HOT, rb.GetBitmapNamed(IDR_STAR_H));
- star_->SetImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_STAR_P));
- star_->SetImage(views::CustomButton::BS_DISABLED,
- rb.GetBitmapNamed(IDR_STAR_D));
- star_->SetToggledImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_STARRED));
- star_->SetToggledImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_STARRED_H));
- star_->SetToggledImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_STARRED_P));
star_->SetDragController(this);
star_->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_STAR));
star_->SetToggledTooltipText(l10n_util::GetString(IDS_TOOLTIP_STARRED));
@@ -229,68 +193,37 @@ void BrowserToolbarView::CreateCenterStack(Profile *profile) {
model_, this,
display_mode_ == DISPLAYMODE_LOCATION,
this);
- AddChildView(location_bar_);
- location_bar_->Init();
// The Go button.
go_ = new GoButton(location_bar_, browser_);
- go_->SetImage(views::CustomButton::BS_NORMAL, rb.GetBitmapNamed(IDR_GO));
- go_->SetImage(views::CustomButton::BS_HOT, rb.GetBitmapNamed(IDR_GO_H));
- go_->SetImage(views::CustomButton::BS_PUSHED, rb.GetBitmapNamed(IDR_GO_P));
- go_->SetToggledImage(views::CustomButton::BS_NORMAL,
- rb.GetBitmapNamed(IDR_STOP));
- go_->SetToggledImage(views::CustomButton::BS_HOT,
- rb.GetBitmapNamed(IDR_STOP_H));
- go_->SetToggledImage(views::CustomButton::BS_PUSHED,
- rb.GetBitmapNamed(IDR_STOP_P));
go_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_GO));
go_->SetID(VIEW_ID_GO_BUTTON);
- AddChildView(go_);
-}
-
-void BrowserToolbarView::Update(TabContents* tab, bool should_restore_state) {
- tab_ = tab;
- if (!location_bar_)
- return;
+ LoadCenterStackImages();
- location_bar_->Update(should_restore_state ? tab : NULL);
-}
-
-void BrowserToolbarView::OnInputInProgress(bool in_progress) {
- // The edit should make sure we're only notified when something changes.
- DCHECK(model_->input_in_progress() != in_progress);
-
- model_->set_input_in_progress(in_progress);
- location_bar_->Update(NULL);
+ AddChildView(location_bar_);
+ location_bar_->Init();
+ AddChildView(go_);
}
void BrowserToolbarView::CreateRightSideControls(Profile* profile) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ ThemeProvider* tp = GetThemeProvider();
page_menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
-
- // We use different menu button images if the locale is right-to-left.
- if (UILayoutIsRightToLeft())
- page_menu_->SetIcon(*rb.GetBitmapNamed(IDR_MENU_PAGE_RTL));
- else
- page_menu_->SetIcon(*rb.GetBitmapNamed(IDR_MENU_PAGE));
-
page_menu_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_PAGE));
page_menu_->SetTooltipText(l10n_util::GetString(IDS_PAGEMENU_TOOLTIP));
page_menu_->SetID(VIEW_ID_PAGE_MENU);
- AddChildView(page_menu_);
- app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
- if (UILayoutIsRightToLeft())
- app_menu_->SetIcon(*rb.GetBitmapNamed(IDR_MENU_CHROME_RTL));
- else
- app_menu_->SetIcon(*rb.GetBitmapNamed(IDR_MENU_CHROME));
+ app_menu_ = new views::MenuButton(NULL, std::wstring(), this, false);
app_menu_->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_APP));
app_menu_->SetTooltipText(l10n_util::GetStringF(IDS_APPMENU_TOOLTIP,
l10n_util::GetString(IDS_PRODUCT_NAME)));
app_menu_->SetID(VIEW_ID_APP_MENU);
+
+ LoadRightSideControlsImages();
+
+ AddChildView(page_menu_);
AddChildView(app_menu_);
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kBookmarkMenu)) {
@@ -301,6 +234,96 @@ void BrowserToolbarView::CreateRightSideControls(Profile* profile) {
}
}
+void BrowserToolbarView::LoadLeftSideControlsImages() {
+ ThemeProvider* tp = GetThemeProvider();
+
+ back_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_BACK));
+ back_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_BACK_H));
+ back_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_BACK_P));
+ back_->SetImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_BACK_D));
+
+ forward_->SetImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_FORWARD));
+ forward_->SetImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_FORWARD_H));
+ forward_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_FORWARD_P));
+ forward_->SetImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_FORWARD_D));
+
+ reload_->SetImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_RELOAD));
+ reload_->SetImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_RELOAD_H));
+ reload_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_RELOAD_P));
+
+ home_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_HOME));
+ home_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_HOME_H));
+ home_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_HOME_P));
+}
+
+void BrowserToolbarView::LoadCenterStackImages() {
+ ThemeProvider* tp = GetThemeProvider();
+
+ star_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_STAR));
+ star_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_STAR_H));
+ star_->SetImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_STAR_P));
+ star_->SetImage(views::CustomButton::BS_DISABLED,
+ tp->GetBitmapNamed(IDR_STAR_D));
+ star_->SetToggledImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_STARRED));
+ star_->SetToggledImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_STARRED_H));
+ star_->SetToggledImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_STARRED_P));
+
+ go_->SetImage(views::CustomButton::BS_NORMAL, tp->GetBitmapNamed(IDR_GO));
+ go_->SetImage(views::CustomButton::BS_HOT, tp->GetBitmapNamed(IDR_GO_H));
+ go_->SetImage(views::CustomButton::BS_PUSHED, tp->GetBitmapNamed(IDR_GO_P));
+ go_->SetToggledImage(views::CustomButton::BS_NORMAL,
+ tp->GetBitmapNamed(IDR_STOP));
+ go_->SetToggledImage(views::CustomButton::BS_HOT,
+ tp->GetBitmapNamed(IDR_STOP_H));
+ go_->SetToggledImage(views::CustomButton::BS_PUSHED,
+ tp->GetBitmapNamed(IDR_STOP_P));
+}
+
+void BrowserToolbarView::LoadRightSideControlsImages() {
+ ThemeProvider* tp = GetThemeProvider();
+
+ // We use different menu button images if the locale is right-to-left.
+ if (UILayoutIsRightToLeft())
+ page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE_RTL));
+ else
+ page_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_PAGE));
+ if (UILayoutIsRightToLeft())
+ app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME_RTL));
+ else
+ app_menu_->SetIcon(*tp->GetBitmapNamed(IDR_MENU_CHROME));
+}
+
+void BrowserToolbarView::Update(TabContents* tab, bool should_restore_state) {
+ tab_ = tab;
+
+ if (!location_bar_)
+ return;
+
+ location_bar_->Update(should_restore_state ? tab : NULL);
+}
+
+void BrowserToolbarView::OnInputInProgress(bool in_progress) {
+ // The edit should make sure we're only notified when something changes.
+ DCHECK(model_->input_in_progress() != in_progress);
+
+ model_->set_input_in_progress(in_progress);
+ location_bar_->Update(NULL);
+}
+
void BrowserToolbarView::Layout() {
// If we have not been initialized yet just do nothing.
if (back_ == NULL)
@@ -758,6 +781,12 @@ void BrowserToolbarView::SetAccessibleName(const std::wstring& name) {
accessible_name_.assign(name);
}
+void BrowserToolbarView::ThemeChanged() {
+ LoadLeftSideControlsImages();
+ LoadCenterStackImages();
+ LoadRightSideControlsImages();
+}
+
int BrowserToolbarView::GetNextAccessibleViewIndex(int view_index,
bool nav_left) {
int modifier = 1;
diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h
index c5a9f83..b5f3861 100644
--- a/chrome/browser/views/toolbar_view.h
+++ b/chrome/browser/views/toolbar_view.h
@@ -63,6 +63,7 @@ class BrowserToolbarView : public views::View,
virtual bool GetAccessibleName(std::wstring* name);
virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
virtual void SetAccessibleName(const std::wstring& name);
+ virtual void ThemeChanged();
// Overridden from EncodingMenuControllerDelegate:
virtual bool IsItemChecked(int id) const;
@@ -147,6 +148,9 @@ class BrowserToolbarView : public views::View,
void CreateLeftSideControls();
void CreateCenterStack(Profile* profile);
void CreateRightSideControls(Profile* profile);
+ void LoadLeftSideControlsImages();
+ void LoadCenterStackImages();
+ void LoadRightSideControlsImages();
// Updates the controls to display the security appropriately (highlighted if
// secure).
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 6941455..8878444 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -167,6 +167,7 @@
'../app/resource_bundle_mac.mm',
'../app/slide_animation.cc',
'../app/slide_animation.h',
+ '../app/theme_provider.h',
'../app/throb_animation.cc',
'../app/throb_animation.h',
'../app/win_util.cc',
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index 82d62e0..3364fc1 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -534,6 +534,9 @@ class NotificationType {
// Sent when new extensions are loaded. The details are an ExtensionList*.
EXTENSIONS_LOADED,
+ // Sent when a new theme is installed. The details are an extension.
+ THEME_INSTALLED,
+
// Sent when new extensions are installed. The details are a FilePath.
EXTENSION_INSTALLED,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 266e60b..f414d27 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -246,6 +246,10 @@ const wchar_t kPrintingPageHeaderRight[] = L"printing.page.header.right";
const wchar_t kPrintingPageFooterLeft[] = L"printing.page.footer.left";
const wchar_t kPrintingPageFooterCenter[] = L"printing.page.footer.center";
const wchar_t kPrintingPageFooterRight[] = L"printing.page.footer.right";
+const wchar_t kCurrentThemeID[] = L"extensions.theme.id";
+const wchar_t kCurrentThemeImages[] = L"extensions.theme.images";
+const wchar_t kCurrentThemeColors[] = L"extensions.theme.colors";
+const wchar_t kCurrentThemeTints[] = L"extensions.theme.tints";
// Boolean that indicates whether we should check if we are the default browser
// on start-up.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 92c674d..83fdfd1 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -88,6 +88,10 @@ extern const wchar_t kPrintingPageHeaderRight[];
extern const wchar_t kPrintingPageFooterLeft[];
extern const wchar_t kPrintingPageFooterCenter[];
extern const wchar_t kPrintingPageFooterRight[];
+extern const wchar_t kCurrentThemeID[];
+extern const wchar_t kCurrentThemeImages[];
+extern const wchar_t kCurrentThemeColors[];
+extern const wchar_t kCurrentThemeTints[];
extern const wchar_t kCheckDefaultBrowser[];
// Local state
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc
index e8c9416..316a83a 100644
--- a/chrome/common/url_constants.cc
+++ b/chrome/common/url_constants.cc
@@ -49,5 +49,6 @@ const char kChromeUIHistoryHost[] = "history";
const char kChromeUIInspectorHost[] = "inspector";
const char kChromeUINewTabHost[] = "newtab";
const char kChromeUIThumbnailPath[] = "thumb";
+const char kChromeUIThemePath[] = "theme";
} // namespace chrome
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h
index 21dff62..b06bcb8 100644
--- a/chrome/common/url_constants.h
+++ b/chrome/common/url_constants.h
@@ -56,6 +56,7 @@ extern const char kChromeUIHistoryHost[];
extern const char kChromeUIInspectorHost[];
extern const char kChromeUINewTabHost[];
extern const char kChromeUIThumbnailPath[];
+extern const char kChromeUIThemePath[];
} // namespace chrome
diff --git a/chrome/renderer/extensions/bindings_utils.h b/chrome/renderer/extensions/bindings_utils.h
index f7dbba3..7f336c3 100755
--- a/chrome/renderer/extensions/bindings_utils.h
+++ b/chrome/renderer/extensions/bindings_utils.h
@@ -7,6 +7,7 @@
#include "app/resource_bundle.h"
#include "base/singleton.h"
+#include "base/string_piece.h"
#include <string>
diff --git a/chrome/test/data/extensions/theme.crx b/chrome/test/data/extensions/theme.crx
new file mode 100644
index 0000000..bcdb04c
--- /dev/null
+++ b/chrome/test/data/extensions/theme.crx
Binary files differ
diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h
index d715210..6d7e92e 100644
--- a/chrome/test/test_browser_window.h
+++ b/chrome/test/test_browser_window.h
@@ -62,6 +62,7 @@ class TestBrowserWindow : public BrowserWindow {
virtual void ConfirmBrowserCloseWithPendingDownloads() {}
virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate,
void* parent_window) {}
+ virtual void UserChangedTheme() {}
protected:
virtual void DestroyBrowser() {}
diff --git a/chrome/test/testing_profile.h b/chrome/test/testing_profile.h
index e0bbc0b..310eac8 100644
--- a/chrome/test/testing_profile.h
+++ b/chrome/test/testing_profile.h
@@ -119,6 +119,12 @@ class TestingProfile : public Profile {
virtual bool HasCreatedDownloadManager() const {
return false;
}
+ virtual void InitThemes() { }
+ virtual void SetTheme(Extension* extension) { }
+ virtual void ClearTheme() { }
+ virtual ThemeProvider* GetThemeProvider() {
+ return NULL;
+ }
virtual URLRequestContext* GetRequestContext() {
return NULL;
}
diff --git a/skia/ext/image_operations.cc b/skia/ext/image_operations.cc
index a6ccec4..07fb97b 100644
--- a/skia/ext/image_operations.cc
+++ b/skia/ext/image_operations.cc
@@ -16,7 +16,6 @@
#include "SkBitmap.h"
#include "skia/ext/convolver.h"
#include "skia/include/SkColorPriv.h"
-#include "skia/ext/skia_utils.h"
namespace skia {
@@ -460,7 +459,7 @@ SkBitmap ImageOperations::CreateBlurredBitmap(const SkBitmap& bitmap,
// static
SkBitmap ImageOperations::CreateHSLShiftedBitmap(const SkBitmap& bitmap,
- float hsl_shift[3]) {
+ HSL hsl_shift) {
DCHECK(bitmap.empty() == false);
DCHECK(bitmap.config() == SkBitmap::kARGB_8888_Config);
@@ -494,30 +493,30 @@ SkBitmap ImageOperations::CreateHSLShiftedBitmap(const SkBitmap& bitmap,
static_cast<int>(b * 255.0));
}
- float pixel_hsl[3];
+ HSL pixel_hsl = { 0, 0, 0 };
SkColorToHSL(color, pixel_hsl);
// Replace the hue with the tint's hue.
- if (hsl_shift[0] >= 0)
- pixel_hsl[0] = hsl_shift[0];
+ if (hsl_shift.h >= 0)
+ pixel_hsl.h = hsl_shift.h;
// Change the saturation.
- if (hsl_shift[1] >= 0) {
- if (hsl_shift[1] <= 0.5) {
- pixel_hsl[1] *= hsl_shift[1] * 2.0;
+ if (hsl_shift.s >= 0) {
+ if (hsl_shift.s <= 0.5) {
+ pixel_hsl.s *= hsl_shift.s * 2.0;
} else {
- pixel_hsl[1] = pixel_hsl[1] + (1.0 - pixel_hsl[1]) *
- ((hsl_shift[1] - 0.5) * 2.0);
+ pixel_hsl.s = pixel_hsl.s + (1.0 - pixel_hsl.s) *
+ ((hsl_shift.s - 0.5) * 2.0);
}
}
// Change the lightness.
- if (hsl_shift[2] >= 0) {
- if (hsl_shift[2] <= 0.5) {
- pixel_hsl[2] *= hsl_shift[2] * 2.0;
+ if (hsl_shift.l >= 0) {
+ if (hsl_shift.l <= 0.5) {
+ pixel_hsl.l *= hsl_shift.l * 2.0;
} else {
- pixel_hsl[2] = pixel_hsl[2] + (1.0 - pixel_hsl[2]) *
- ((hsl_shift[2] - 0.5) * 2.0);
+ pixel_hsl.l = pixel_hsl.l + (1.0 - pixel_hsl.l) *
+ ((hsl_shift.l - 0.5) * 2.0);
}
}
diff --git a/skia/ext/image_operations.h b/skia/ext/image_operations.h
index 5c46b36..b5e049d 100644
--- a/skia/ext/image_operations.h
+++ b/skia/ext/image_operations.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/gfx/rect.h"
+#include "skia/ext/skia_utils.h"
#include "SkColor.h"
class SkBitmap;
@@ -80,7 +81,7 @@ class ImageOperations {
// 0.5 = leave unchanged.
// 1 = full lightness (make all pixels white).
static SkBitmap CreateHSLShiftedBitmap(const SkBitmap& bitmap,
- float hsl_shift[3]);
+ HSL hsl_shift);
// Create a bitmap that is cropped from another bitmap. This is special
// because it tiles the original bitmap, so your coordinates can extend
diff --git a/skia/ext/image_operations_unittest.cc b/skia/ext/image_operations_unittest.cc
index 5ed69da..8f7e9be 100644
--- a/skia/ext/image_operations_unittest.cc
+++ b/skia/ext/image_operations_unittest.cc
@@ -309,7 +309,7 @@ TEST(ImageOperations, CreateHSLShiftedBitmapToSame) {
}
}
- float hsl[3] = { -1, -1, -1 };
+ skia::HSL hsl = { -1, -1, -1 };
SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl);
@@ -340,7 +340,7 @@ TEST(ImageOperations, CreateHSLShiftedBitmapHueOnly) {
}
// Shift to red.
- float hsl[3] = { 0, -1, -1 };
+ skia::HSL hsl = { 0, -1, -1 };
SkBitmap shifted = skia::ImageOperations::CreateHSLShiftedBitmap(src, hsl);
diff --git a/skia/ext/skia_utils.cc b/skia/ext/skia_utils.cc
index 1424957..3b5484f 100644
--- a/skia/ext/skia_utils.cc
+++ b/skia/ext/skia_utils.cc
@@ -39,25 +39,25 @@ static inline double calcHue(double temp1, double temp2, double hueVal) {
return temp1;
}
-SkPMColor HSLToSKColor(U8CPU alpha, float hsl[3]) {
- double hue = SkScalarToDouble(hsl[0]);
- double saturation = SkScalarToDouble(hsl[1]);
- double lightness = SkScalarToDouble(hsl[2]);
+SkPMColor HSLToSKColor(U8CPU alpha, HSL hsl) {
+ double hue = hsl.h;
+ double saturation = hsl.s;
+ double lightness = hsl.l;
double scaleFactor = 256.0;
// If there's no color, we don't care about hue and can do everything based
// on brightness.
if (!saturation) {
- U8CPU lightness;
+ U8CPU light;
- if (hsl[2] < 0)
- lightness = 0;
- else if (hsl[2] >= SK_Scalar1)
- lightness = 255;
+ if (lightness < 0)
+ light = 0;
+ else if (lightness >= SK_Scalar1)
+ light = 255;
else
- lightness = SkScalarToFixed(hsl[2]) >> 8;
+ light = SkDoubleToFixed(lightness) >> 8;
- unsigned greyValue = SkAlphaMul(lightness, alpha);
+ unsigned greyValue = SkAlphaMul(light, alpha);
return SkColorSetARGB(alpha, greyValue, greyValue, greyValue);
}
@@ -76,7 +76,7 @@ SkPMColor HSLToSKColor(U8CPU alpha, float hsl[3]) {
SkAlphaMul(static_cast<int>(bh * scaleFactor), alpha));
}
-void SkColorToHSL(SkPMColor c, float hsl[3]) {
+void SkColorToHSL(SkPMColor c, HSL& hsl) {
double r = SkColorGetR(c) / 255.0;
double g = SkColorGetG(c) / 255.0;
double b = SkColorGetB(c) / 255.0;
@@ -115,9 +115,37 @@ void SkColorToHSL(SkPMColor c, float hsl[3]) {
if (h > 1) h -= 1;
}
- hsl[0] = h;
- hsl[1] = s;
- hsl[2] = l;
+ hsl.h = h;
+ hsl.s = s;
+ hsl.l = l;
+}
+
+SkColor HSLShift(HSL hsl, HSL shift) {
+ // Replace the hue with the tint's hue.
+ if (shift.h >= 0)
+ hsl.h = shift.h;
+
+ // Change the saturation.
+ if (shift.s >= 0) {
+ if (shift.s <= 0.5) {
+ hsl.s *= shift.s * 2.0;
+ } else {
+ hsl.s = hsl.s + (1.0 - hsl.s) *
+ ((shift.s - 0.5) * 2.0);
+ }
+ }
+
+ // Change the lightness.
+ if (shift.l >= 0) {
+ if (shift.l <= 0.5) {
+ hsl.l *= shift.l * 2.0;
+ } else {
+ hsl.l = hsl.l + (1.0 - hsl.l) *
+ ((shift.l - 0.5) * 2.0);
+ }
+ }
+
+ return skia::HSLToSKColor(0xff, hsl);
}
diff --git a/skia/ext/skia_utils.h b/skia/ext/skia_utils.h
index 98fa1b0..0f61b18 100644
--- a/skia/ext/skia_utils.h
+++ b/skia/ext/skia_utils.h
@@ -10,6 +10,12 @@
namespace skia {
+struct HSL {
+ double h;
+ double s;
+ double l;
+};
+
// Creates a vertical gradient shader. The caller owns the shader.
// Example usage to avoid leaks:
// paint.setShader(gfx::CreateGradientShader(0, 10, red, blue))->safeUnref();
@@ -22,10 +28,27 @@ SkShader* CreateGradientShader(int start_point,
SkColor end_color);
// Convert a premultiplied SkColor to a HSL value.
-void SkColorToHSL(SkPMColor c, float hsl[3]);
+void SkColorToHSL(SkPMColor c, HSL& hsl);
// Convert a HSL color to a premultiplied SkColor.
-SkPMColor HSLToSKColor(U8CPU alpha, float hsl[3]);
+SkPMColor HSLToSKColor(U8CPU alpha, HSL hsl);
+
+// Shift an HSL value. The shift values are in the range of 0-1,
+// with the option to specify -1 for 'no change'. The shift values are
+// defined as:
+// hsl_shift[0] (hue): The absolute hue value - 0 and 1 map
+// to 0 and 360 on the hue color wheel (red).
+// hsl_shift[1] (saturation): A saturation shift, with the
+// following key values:
+// 0 = remove all color.
+// 0.5 = leave unchanged.
+// 1 = fully saturate the image.
+// hsl_shift[2] (lightness): A lightness shift, with the
+// following key values:
+// 0 = remove all lightness (make all pixels black).
+// 0.5 = leave unchanged.
+// 1 = full lightness (make all pixels white).
+SkColor HSLShift(skia::HSL hsl, skia::HSL shift);
} // namespace skia
diff --git a/skia/ext/skia_utils_unittest.cc b/skia/ext/skia_utils_unittest.cc
index f7b00b1..444a5fc9 100644
--- a/skia/ext/skia_utils_unittest.cc
+++ b/skia/ext/skia_utils_unittest.cc
@@ -11,20 +11,20 @@
TEST(SkiaUtils, SkColorToHSLRed) {
SkColor red = SkColorSetARGB(255, 255, 0, 0);
- SkScalar hsl[3];
+ skia::HSL hsl = { 0, 0, 0 };
skia::SkColorToHSL(red, hsl);
- EXPECT_EQ(hsl[0], 0);
- EXPECT_EQ(hsl[1], 1);
- EXPECT_EQ(hsl[2], 0.5);
+ EXPECT_EQ(hsl.h, 0);
+ EXPECT_EQ(hsl.s, 1);
+ EXPECT_EQ(hsl.l, 0.5);
}
TEST(SkiaUtils, SkColorToHSLGrey) {
SkColor red = SkColorSetARGB(255, 128, 128, 128);
- SkScalar hsl[3];
+ skia::HSL hsl = { 0, 0, 0 };
skia::SkColorToHSL(red, hsl);
- EXPECT_EQ(hsl[0], 0);
- EXPECT_EQ(hsl[1], 0);
- EXPECT_EQ(static_cast<int>(hsl[2] * 100),
+ EXPECT_EQ(hsl.h, 0);
+ EXPECT_EQ(hsl.s, 0);
+ EXPECT_EQ(static_cast<int>(hsl.l * 100),
static_cast<int>(0.5 * 100)); // Accurate to two decimal places.
}
@@ -32,11 +32,7 @@ TEST(SkiaUtils, HSLToSkColorWithAlpha) {
// Premultiplied alpha - this is full red.
SkColor red = SkColorSetARGB(128, 128, 0, 0);
- SkScalar hsl[3] = {
- SkDoubleToScalar(0),
- SkDoubleToScalar(1),
- SkDoubleToScalar(0.5),
- };
+ skia::HSL hsl = { 0, 1, 0.5 };
SkColor result = skia::HSLToSKColor(128, hsl);
EXPECT_EQ(SkColorGetA(red), SkColorGetA(result));
diff --git a/views/view.cc b/views/view.cc
index b2951d9..f4ef13d 100644
--- a/views/view.cc
+++ b/views/view.cc
@@ -1568,6 +1568,11 @@ int View::GetLineScrollIncrement(ScrollView* scroll_view,
return 0;
}
+ThemeProvider* View::GetThemeProvider() {
+ Widget* widget = GetWidget();
+ return widget ? widget->GetThemeProvider() : NULL;
+}
+
// static
void View::RegisterChildrenForVisibleBoundsNotification(
RootView* root, View* view) {
diff --git a/views/view.h b/views/view.h
index e3a78f7..561632d 100644
--- a/views/view.h
+++ b/views/view.h
@@ -33,6 +33,7 @@ class Path;
class ChromeCanvas;
class OSExchangeData;
class ViewAccessibilityWrapper;
+class ThemeProvider;
namespace views {
@@ -995,6 +996,9 @@ class View : public AcceleratorTarget {
virtual int GetLineScrollIncrement(ScrollView* scroll_view,
bool is_horizontal, bool is_positive);
+ // Get the theme provider from the parent widget.
+ ThemeProvider* GetThemeProvider();
+
protected:
// The id of this View. Used to find this View.
int id_;
diff --git a/views/views.vcproj b/views/views.vcproj
index 2c98260..1d1c269 100644
--- a/views/views.vcproj
+++ b/views/views.vcproj
@@ -201,6 +201,36 @@
>
</File>
<File
+ RelativePath=".\widget\default_theme_provider.cc"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ ObjectFile="$(IntDir)\$(InputName)1.obj"
+ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\widget\default_theme_provider.h"
+ >
+ </File>
+ <File
+ RelativePath=".\widget\hwnd_notification_source.h"
+ >
+ </File>
+ <File
RelativePath=".\widget\root_view.cc"
>
<FileConfiguration
diff --git a/views/widget/default_theme_provider.cc b/views/widget/default_theme_provider.cc
new file mode 100644
index 0000000..be348a9
--- /dev/null
+++ b/views/widget/default_theme_provider.cc
@@ -0,0 +1,20 @@
+// 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.
+
+#include "views/widget/default_theme_provider.h"
+
+#include "app/resource_bundle.h"
+
+namespace views {
+
+SkBitmap* DefaultThemeProvider::GetBitmapNamed(int id) {
+ return ResourceBundle::GetSharedInstance().GetBitmapNamed(id);
+}
+
+SkColor DefaultThemeProvider::GetColor(int id) {
+ // Return debugging-blue.
+ return 0xff0000ff;
+}
+
+} // namespace views
diff --git a/views/widget/default_theme_provider.h b/views/widget/default_theme_provider.h
new file mode 100644
index 0000000..1060c8e
--- /dev/null
+++ b/views/widget/default_theme_provider.h
@@ -0,0 +1,30 @@
+// 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.
+
+#ifndef VIEWS_DEFAULT_THEME_PROVIDER_H_
+#define VIEWS_DEFAULT_THEME_PROVIDER_H_
+
+#include "app/theme_provider.h"
+#include "base/basictypes.h"
+
+class ResourceBundle;
+
+namespace views {
+
+class DefaultThemeProvider : public ThemeProvider {
+ public:
+ DefaultThemeProvider() { };
+ virtual ~DefaultThemeProvider() { };
+
+ // Overridden from ThemeProvider.
+ virtual SkBitmap* GetBitmapNamed(int id);
+ virtual SkColor GetColor(int id);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultThemeProvider);
+};
+
+} // namespace views
+
+#endif // VIEWS_DEFAULT_THEME_PROVIDER_H_
diff --git a/views/widget/widget.h b/views/widget/widget.h
index 8dd3f2e..b2c3551 100644
--- a/views/widget/widget.h
+++ b/views/widget/widget.h
@@ -7,6 +7,8 @@
#include "base/gfx/native_widget_types.h"
+class ThemeProvider;
+
namespace gfx {
class Rect;
}
@@ -53,6 +55,9 @@ class Widget {
// Returns the RootView contained by this Widget.
virtual RootView* GetRootView() = 0;
+ // Returns the Widget associated with the root ancestor.
+ virtual Widget* GetRootWidget() const = 0;
+
// Returns whether the Widget is visible to the user.
virtual bool IsVisible() const = 0;
@@ -74,6 +79,14 @@ class Widget {
// window.
virtual Window* GetWindow() { return NULL; }
virtual const Window* GetWindow() const { return NULL; }
+
+ // Get the theme provider.
+ virtual ThemeProvider* GetThemeProvider() const { return NULL; }
+
+ // Get the dialog theme provider; this is necessary for when a dialog has
+ // no profile (and ThemeProvider) associated with it. The dialog theme
+ // provider provides a default set of bitmaps that such dialogs can use.
+ virtual ThemeProvider* GetDialogThemeProvider() { return NULL; }
};
} // namespace views
diff --git a/views/widget/widget_win.cc b/views/widget/widget_win.cc
index c59f512..25f25da 100644
--- a/views/widget/widget_win.cc
+++ b/views/widget/widget_win.cc
@@ -15,6 +15,7 @@
#include "views/fill_layout.h"
#include "views/focus/focus_util_win.h"
#include "views/widget/aero_tooltip_manager.h"
+#include "views/widget/default_theme_provider.h"
#include "views/widget/root_view.h"
#include "views/window/window_win.h"
@@ -166,6 +167,8 @@ void WidgetWin::Init(HWND parent, const gfx::Rect& bounds,
// Force creation of the RootView if it hasn't been created yet.
GetRootView();
+ default_theme_provider_.reset(new DefaultThemeProvider());
+
// Ensures the parent we have been passed is valid, otherwise CreateWindowEx
// will fail.
if (parent && !::IsWindow(parent)) {
@@ -293,6 +296,11 @@ RootView* WidgetWin::GetRootView() {
return root_view_.get();
}
+Widget* WidgetWin::GetRootWidget() const {
+ return reinterpret_cast<WidgetWin*>(
+ win_util::GetWindowUserData(GetAncestor(hwnd_, GA_ROOT)));
+}
+
bool WidgetWin::IsVisible() const {
return !!::IsWindowVisible(GetNativeView());
}
@@ -305,6 +313,16 @@ TooltipManager* WidgetWin::GetTooltipManager() {
return tooltip_manager_.get();
}
+ThemeProvider* WidgetWin::GetThemeProvider() const {
+ Widget* widget = GetRootWidget();
+ if (widget) {
+ ThemeProvider* provider = widget->GetDialogThemeProvider();
+ if (provider)
+ return provider;
+ }
+ return default_theme_provider_.get();
+}
+
Window* WidgetWin::GetWindow() {
return GetWindowImpl(hwnd_);
}
diff --git a/views/widget/widget_win.h b/views/widget/widget_win.h
index 09efa21..d948e66 100644
--- a/views/widget/widget_win.h
+++ b/views/widget/widget_win.h
@@ -24,6 +24,7 @@ namespace views {
class RootView;
class TooltipManager;
+class DefaultThemeProvider;
class Window;
bool SetRootViewForHWND(HWND hwnd, RootView* root_view);
@@ -235,9 +236,11 @@ class WidgetWin : public Widget,
virtual gfx::NativeView GetNativeView() const;
virtual void PaintNow(const gfx::Rect& update_rect);
virtual RootView* GetRootView();
+ virtual Widget* GetRootWidget() const;
virtual bool IsVisible() const;
virtual bool IsActive() const;
virtual TooltipManager* GetTooltipManager();
+ virtual ThemeProvider* GetThemeProvider() const;
virtual Window* GetWindow();
virtual const Window* GetWindow() const;
@@ -627,6 +630,8 @@ class WidgetWin : public Widget,
// Instance of accessibility information and handling for MSAA root
CComPtr<IAccessible> accessibility_root_;
+ scoped_ptr<DefaultThemeProvider> default_theme_provider_;
+
// Our hwnd.
HWND hwnd_;
};
diff --git a/views/window/custom_frame_view.cc b/views/window/custom_frame_view.cc
index 1816fdc..88251b8 100644
--- a/views/window/custom_frame_view.cc
+++ b/views/window/custom_frame_view.cc
@@ -8,6 +8,7 @@
#include "app/gfx/chrome_font.h"
#include "app/gfx/path.h"
#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
#if defined(OS_WIN)
#include "app/win_util.h"
#include "base/win_util.h"
@@ -21,157 +22,7 @@
namespace views {
-// An enumeration of bitmap resources used by this window.
-enum {
- FRAME_PART_BITMAP_FIRST = 0, // Must be first.
-
- // Window Controls.
- FRAME_CLOSE_BUTTON_ICON,
- FRAME_CLOSE_BUTTON_ICON_H,
- FRAME_CLOSE_BUTTON_ICON_P,
- FRAME_CLOSE_BUTTON_ICON_SA,
- FRAME_CLOSE_BUTTON_ICON_SA_H,
- FRAME_CLOSE_BUTTON_ICON_SA_P,
- FRAME_RESTORE_BUTTON_ICON,
- FRAME_RESTORE_BUTTON_ICON_H,
- FRAME_RESTORE_BUTTON_ICON_P,
- FRAME_MAXIMIZE_BUTTON_ICON,
- FRAME_MAXIMIZE_BUTTON_ICON_H,
- FRAME_MAXIMIZE_BUTTON_ICON_P,
- FRAME_MINIMIZE_BUTTON_ICON,
- FRAME_MINIMIZE_BUTTON_ICON_H,
- FRAME_MINIMIZE_BUTTON_ICON_P,
-
- // Window Frame Border.
- FRAME_BOTTOM_EDGE,
- FRAME_BOTTOM_LEFT_CORNER,
- FRAME_BOTTOM_RIGHT_CORNER,
- FRAME_LEFT_EDGE,
- FRAME_RIGHT_EDGE,
- FRAME_TOP_EDGE,
- FRAME_TOP_LEFT_CORNER,
- FRAME_TOP_RIGHT_CORNER,
-
- // Client Edge Border.
- FRAME_CLIENT_EDGE_TOP_LEFT,
- FRAME_CLIENT_EDGE_TOP,
- FRAME_CLIENT_EDGE_TOP_RIGHT,
- FRAME_CLIENT_EDGE_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM_RIGHT,
- FRAME_CLIENT_EDGE_BOTTOM,
- FRAME_CLIENT_EDGE_BOTTOM_LEFT,
- FRAME_CLIENT_EDGE_LEFT,
-
- FRAME_PART_BITMAP_COUNT // Must be last.
-};
-
-class ActiveWindowResources : public WindowResources {
- public:
- ActiveWindowResources() {
- InitClass();
- }
- virtual ~ActiveWindowResources() {
- }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- 0,
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_WINDOW_BOTTOM_CENTER, IDR_WINDOW_BOTTOM_LEFT_CORNER,
- IDR_WINDOW_BOTTOM_RIGHT_CORNER, IDR_WINDOW_LEFT_SIDE,
- IDR_WINDOW_RIGHT_SIDE, IDR_WINDOW_TOP_CENTER,
- IDR_WINDOW_TOP_LEFT_CORNER, IDR_WINDOW_TOP_RIGHT_CORNER,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER,
- IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER,
- IDR_CONTENT_LEFT_SIDE,
- 0
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
- int id = kFramePartBitmapIds[i];
- if (id != 0)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id);
- }
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(ActiveWindowResources);
-};
-
-class InactiveWindowResources : public WindowResources {
- public:
- InactiveWindowResources() {
- InitClass();
- }
- virtual ~InactiveWindowResources() {
- }
-
- // WindowResources implementation:
- virtual SkBitmap* GetPartBitmap(FramePartBitmap part) const {
- return standard_frame_bitmaps_[part];
- }
-
- private:
- static void InitClass() {
- static bool initialized = false;
- if (!initialized) {
- static const int kFramePartBitmapIds[] = {
- 0,
- IDR_CLOSE, IDR_CLOSE_H, IDR_CLOSE_P,
- IDR_CLOSE_SA, IDR_CLOSE_SA_H, IDR_CLOSE_SA_P,
- IDR_RESTORE, IDR_RESTORE_H, IDR_RESTORE_P,
- IDR_MAXIMIZE, IDR_MAXIMIZE_H, IDR_MAXIMIZE_P,
- IDR_MINIMIZE, IDR_MINIMIZE_H, IDR_MINIMIZE_P,
- IDR_DEWINDOW_BOTTOM_CENTER, IDR_DEWINDOW_BOTTOM_LEFT_CORNER,
- IDR_DEWINDOW_BOTTOM_RIGHT_CORNER, IDR_DEWINDOW_LEFT_SIDE,
- IDR_DEWINDOW_RIGHT_SIDE, IDR_DEWINDOW_TOP_CENTER,
- IDR_DEWINDOW_TOP_LEFT_CORNER, IDR_DEWINDOW_TOP_RIGHT_CORNER,
- IDR_APP_TOP_LEFT, IDR_APP_TOP_CENTER, IDR_APP_TOP_RIGHT,
- IDR_CONTENT_RIGHT_SIDE, IDR_CONTENT_BOTTOM_RIGHT_CORNER,
- IDR_CONTENT_BOTTOM_CENTER, IDR_CONTENT_BOTTOM_LEFT_CORNER,
- IDR_CONTENT_LEFT_SIDE,
- 0
- };
-
- ResourceBundle& rb = ResourceBundle::GetSharedInstance();
- for (int i = 0; i < FRAME_PART_BITMAP_COUNT; ++i) {
- int id = kFramePartBitmapIds[i];
- if (id != 0)
- standard_frame_bitmaps_[i] = rb.GetBitmapNamed(id);
- }
- initialized = true;
- }
- }
-
- static SkBitmap* standard_frame_bitmaps_[FRAME_PART_BITMAP_COUNT];
-
- DISALLOW_EVIL_CONSTRUCTORS(InactiveWindowResources);
-};
-
-// static
-SkBitmap* ActiveWindowResources::standard_frame_bitmaps_[];
-SkBitmap* InactiveWindowResources::standard_frame_bitmaps_[];
-
// static
-WindowResources* CustomFrameView::active_resources_ = NULL;
-WindowResources* CustomFrameView::inactive_resources_ = NULL;
ChromeFont* CustomFrameView::title_font_ = NULL;
namespace {
@@ -231,33 +82,34 @@ CustomFrameView::CustomFrameView(Window* frame)
should_show_minmax_buttons_(false),
frame_(frame) {
InitClass();
- WindowResources* resources = active_resources_;
+
+ ThemeProvider* tp = GetThemeProvider();
// Close button images will be set in LayoutWindowControls().
AddChildView(close_button_);
restore_button_->SetImage(CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_RESTORE));
restore_button_->SetImage(CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_RESTORE_H));
restore_button_->SetImage(CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_RESTORE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_RESTORE_P));
AddChildView(restore_button_);
maximize_button_->SetImage(CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_MAXIMIZE));
maximize_button_->SetImage(CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_MAXIMIZE_H));
maximize_button_->SetImage(CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_MAXIMIZE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_MAXIMIZE_P));
AddChildView(maximize_button_);
minimize_button_->SetImage(CustomButton::BS_NORMAL,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON));
+ tp->GetBitmapNamed(IDR_MINIMIZE));
minimize_button_->SetImage(CustomButton::BS_HOT,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_H));
+ tp->GetBitmapNamed(IDR_MINIMIZE_H));
minimize_button_->SetImage(CustomButton::BS_PUSHED,
- resources->GetPartBitmap(FRAME_MINIMIZE_BUTTON_ICON_P));
+ tp->GetBitmapNamed(IDR_MINIMIZE_P));
AddChildView(minimize_button_);
should_show_minmax_buttons_ = frame_->GetDelegate()->CanMaximize();
@@ -443,17 +295,50 @@ int CustomFrameView::TitleCoordinates(int* title_top_spacing,
}
void CustomFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
- SkBitmap* top_left_corner = resources()->GetPartBitmap(FRAME_TOP_LEFT_CORNER);
+ // Window frame mode.
+ ThemeProvider* tp = GetThemeProvider();
+
+ SkBitmap* theme_frame;
+ SkColor frame_color;
+
+ if (frame_->IsActive()) {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME);
+ frame_color = ResourceBundle::frame_color;
+ } else {
+ theme_frame = tp->GetBitmapNamed(IDR_THEME_FRAME_INACTIVE);
+ frame_color = ResourceBundle::frame_color_inactive;
+ }
+
+ SkBitmap* top_left_corner = tp->GetBitmapNamed(IDR_WINDOW_TOP_LEFT_CORNER);
SkBitmap* top_right_corner =
- resources()->GetPartBitmap(FRAME_TOP_RIGHT_CORNER);
- SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
- SkBitmap* right_edge = resources()->GetPartBitmap(FRAME_RIGHT_EDGE);
- SkBitmap* left_edge = resources()->GetPartBitmap(FRAME_LEFT_EDGE);
+ tp->GetBitmapNamed(IDR_WINDOW_TOP_RIGHT_CORNER);
+ SkBitmap* top_edge = tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER);
+ SkBitmap* right_edge = tp->GetBitmapNamed(IDR_WINDOW_RIGHT_SIDE);
+ SkBitmap* left_edge = tp->GetBitmapNamed(IDR_WINDOW_LEFT_SIDE);
SkBitmap* bottom_left_corner =
- resources()->GetPartBitmap(FRAME_BOTTOM_LEFT_CORNER);
+ tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_LEFT_CORNER);
SkBitmap* bottom_right_corner =
- resources()->GetPartBitmap(FRAME_BOTTOM_RIGHT_CORNER);
- SkBitmap* bottom_edge = resources()->GetPartBitmap(FRAME_BOTTOM_EDGE);
+ tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_RIGHT_CORNER);
+ SkBitmap* bottom_edge = tp->GetBitmapNamed(IDR_WINDOW_BOTTOM_CENTER);
+
+ // Fill with the frame color first so we have a constant background for
+ // areas not covered by the theme image.
+ canvas->FillRectInt(frame_color, 0, 0, width(), theme_frame->height());
+ // Now fill down the sides
+ canvas->FillRectInt(frame_color,
+ 0, theme_frame->height(),
+ left_edge->width(), height() - theme_frame->height());
+ canvas->FillRectInt(frame_color,
+ width() - right_edge->width(), theme_frame->height(),
+ right_edge->width(), height() - theme_frame->height());
+ // Now fill the bottom area.
+ canvas->FillRectInt(frame_color,
+ left_edge->width(), height() - bottom_edge->height(),
+ width() - left_edge->width() - right_edge->width(),
+ bottom_edge->height());
+
+ // Draw the theme frame.
+ canvas->TileImageInt(*theme_frame, 0, 0, width(), theme_frame->height());
// Top.
canvas->DrawBitmapInt(*top_left_corner, 0, 0);
@@ -488,13 +373,15 @@ void CustomFrameView::PaintRestoredFrameBorder(ChromeCanvas* canvas) {
void CustomFrameView::PaintMaximizedFrameBorder(
ChromeCanvas* canvas) {
- SkBitmap* top_edge = resources()->GetPartBitmap(FRAME_TOP_EDGE);
+ ThemeProvider* tp = GetThemeProvider();
+
+ SkBitmap* top_edge = tp->GetBitmapNamed(IDR_WINDOW_TOP_CENTER);
canvas->TileImageInt(*top_edge, 0, FrameBorderThickness(), width(),
top_edge->height());
// The bottom of the titlebar actually comes from the top of the Client Edge
// graphic, with the actual client edge clipped off the bottom.
- SkBitmap* titlebar_bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
+ SkBitmap* titlebar_bottom = tp->GetBitmapNamed(IDR_APP_TOP_CENTER);
int edge_height = titlebar_bottom->height() - kClientEdgeThickness;
canvas->TileImageInt(*titlebar_bottom, 0,
frame_->GetClientView()->y() - edge_height, width(), edge_height);
@@ -518,16 +405,17 @@ void CustomFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
gfx::Rect client_area_bounds = frame_->GetClientView()->bounds();
int client_area_top = client_area_bounds.y();
- SkBitmap* top_left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_LEFT);
- SkBitmap* top = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP);
- SkBitmap* top_right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_TOP_RIGHT);
- SkBitmap* right = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_RIGHT);
+ ThemeProvider* tp = GetThemeProvider();
+ SkBitmap* top_left = tp->GetBitmapNamed(IDR_APP_TOP_LEFT);
+ SkBitmap* top = tp->GetBitmapNamed(IDR_APP_TOP_CENTER);
+ SkBitmap* top_right = tp->GetBitmapNamed(IDR_APP_TOP_RIGHT);
+ SkBitmap* right = tp->GetBitmapNamed(IDR_CONTENT_RIGHT_SIDE);
SkBitmap* bottom_right =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_RIGHT);
- SkBitmap* bottom = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM);
+ tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_RIGHT_CORNER);
+ SkBitmap* bottom = tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_CENTER);
SkBitmap* bottom_left =
- resources()->GetPartBitmap(FRAME_CLIENT_EDGE_BOTTOM_LEFT);
- SkBitmap* left = resources()->GetPartBitmap(FRAME_CLIENT_EDGE_LEFT);
+ tp->GetBitmapNamed(IDR_CONTENT_BOTTOM_LEFT_CORNER);
+ SkBitmap* left = tp->GetBitmapNamed(IDR_CONTENT_LEFT_SIDE);
// Top.
// This next calculation is necessary because the top center bitmap is shorter
@@ -559,6 +447,11 @@ void CustomFrameView::PaintRestoredClientEdge(ChromeCanvas* canvas) {
// Left.
canvas->TileImageInt(*left, client_area_bounds.x() - left->width(),
client_area_top, left->width(), client_area_height);
+
+ // Draw the toolbar color to fill in the edges.
+ canvas->DrawRectInt(ResourceBundle::toolbar_color,
+ client_area_bounds.x() - 1, client_area_top - 2,
+ client_area_bounds.width() + 1, client_area_bottom - client_area_top + 2);
}
void CustomFrameView::LayoutWindowControls() {
@@ -609,24 +502,26 @@ void CustomFrameView::LayoutWindowControls() {
minimize_button_size.width(),
minimize_button_size.height() + top_extra_height);
- normal_part = FRAME_CLOSE_BUTTON_ICON;
- hot_part = FRAME_CLOSE_BUTTON_ICON_H;
- pushed_part = FRAME_CLOSE_BUTTON_ICON_P;
+ normal_part = IDR_CLOSE;
+ hot_part = IDR_CLOSE_H;
+ pushed_part = IDR_CLOSE_P;
} else {
visible_button->SetVisible(false);
minimize_button_->SetVisible(false);
- normal_part = FRAME_CLOSE_BUTTON_ICON_SA;
- hot_part = FRAME_CLOSE_BUTTON_ICON_SA_H;
- pushed_part = FRAME_CLOSE_BUTTON_ICON_SA_P;
+ normal_part = IDR_CLOSE_SA;
+ hot_part = IDR_CLOSE_SA_H;
+ pushed_part = IDR_CLOSE_SA_P;
}
+ ThemeProvider* tp = GetThemeProvider();
+
close_button_->SetImage(CustomButton::BS_NORMAL,
- active_resources_->GetPartBitmap(normal_part));
+ tp->GetBitmapNamed(normal_part));
close_button_->SetImage(CustomButton::BS_HOT,
- active_resources_->GetPartBitmap(hot_part));
+ tp->GetBitmapNamed(hot_part));
close_button_->SetImage(CustomButton::BS_PUSHED,
- active_resources_->GetPartBitmap(pushed_part));
+ tp->GetBitmapNamed(pushed_part));
}
void CustomFrameView::LayoutTitleBar() {
@@ -688,9 +583,6 @@ void CustomFrameView::LayoutClientView() {
void CustomFrameView::InitClass() {
static bool initialized = false;
if (!initialized) {
- active_resources_ = new ActiveWindowResources;
- inactive_resources_ = new InactiveWindowResources;
-
#if defined(OS_WIN)
title_font_ = new ChromeFont(win_util::GetWindowTitleFont());
#elif defined(OS_LINUX)
diff --git a/views/window/custom_frame_view.h b/views/window/custom_frame_view.h
index f071692..ac0b114 100644
--- a/views/window/custom_frame_view.h
+++ b/views/window/custom_frame_view.h
@@ -85,12 +85,6 @@ class CustomFrameView : public NonClientFrameView,
void LayoutTitleBar();
void LayoutClientView();
- // Returns the resource collection to be used when rendering the window.
- WindowResources* resources() const {
- return frame_->IsActive() || paint_as_active() ? active_resources_
- : inactive_resources_;
- }
-
// The bounds of the client view, in this view's coordinates.
gfx::Rect client_view_bounds_;
@@ -110,8 +104,6 @@ class CustomFrameView : public NonClientFrameView,
// Initialize various static resources.
static void InitClass();
- static WindowResources* active_resources_;
- static WindowResources* inactive_resources_;
static ChromeFont* title_font_;
DISALLOW_EVIL_CONSTRUCTORS(CustomFrameView);