diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-14 23:40:15 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-14 23:40:15 +0000 |
commit | 447a51cad97fe5413535c28dae5265ee1ad3c9cc (patch) | |
tree | a0914e5f83908a2290f7bae3d7c1f280682627ec /chrome | |
parent | fec7dc520f31a2234bffe060a33c4356fe4a5d4c (diff) | |
download | chromium_src-447a51cad97fe5413535c28dae5265ee1ad3c9cc.zip chromium_src-447a51cad97fe5413535c28dae5265ee1ad3c9cc.tar.gz chromium_src-447a51cad97fe5413535c28dae5265ee1ad3c9cc.tar.bz2 |
ExtensionShelf now uses the BookmarkExtensionBackground, just like the BookmarkBarView.
Changed the WebKit API to add an optional |id| parameter to the insertStyleText, which is needed to be able to replace style sheets that have been previously added.
Added an interface that both BookmarkBarView and ExtensionShelf implement.
This new interface tells us whether we are located at the top or at the bottom and whether we are detached from the frame or not.
Factored out some of the duplicate painting-related code to a namespace of its own. Not happy with the name (welcome suggestions).
Moved the check for whether extensions are on top to new class and now cache the value for the lifetime of the process.
Toolstrip text color values are no longer hard-coded but use the color specified in the theme.
Decreased the timeouts for showing and hiding the toolstrip handle.
Replaced the pressed background image and the hover background image for the toolstrip to match what the bookmark bar uses.
Known issues:
Some themes expose the fact that:
- The background for the extension shelf when in detached mode (and located on the bottom) does not seamlessly blend in with background of new tab page. Still works surprisingly well when it breaks, though.
- Didn't spend much time theming the shelf handle (just used the solid color from the theme).
BUG=18452, 21272, 21273
TEST=Install a theme for Chrome and make sure everything looks correct and is updated on a theme change. Also make sure painting problems in bugs 21272 and 21273 are fixed.
Review URL: http://codereview.chromium.org/203034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26178 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
19 files changed, 642 insertions, 487 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 15777e7..44ea2c3 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This comment is only here because changes to resources are not picked up -without changes to the corresponding grd file. mp2 --> +without changes to the corresponding grd file. fb01 --> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="grit/browser_resources.h" type="rc_header"> diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc index c483070..2a19667 100644 --- a/chrome/browser/extensions/extension_host.cc +++ b/chrome/browser/extensions/extension_host.cc @@ -8,6 +8,7 @@ #include "base/string_util.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extension_tabs_module.h" @@ -36,6 +37,8 @@ using WebKit::WebDragOperationsMask; // static bool ExtensionHost::enable_dom_automation_ = false; +static const char* kToolstripTextColorSubstitution = "$TEXT_COLOR$"; + ExtensionHost::ExtensionHost(Extension* extension, SiteInstance* site_instance, const GURL& url, ViewType::Type host_type) : extension_(extension), @@ -150,33 +153,57 @@ void ExtensionHost::DidNavigate(RenderViewHost* render_view_host, new ExtensionFunctionDispatcher(render_view_host_, this, url_)); } -void ExtensionHost::DidStopLoading(RenderViewHost* render_view_host) { - static const base::StringPiece toolstrip_css( - ResourceBundle::GetSharedInstance().GetRawDataResource( - IDR_EXTENSIONS_TOOLSTRIP_CSS)); +void ExtensionHost::InsertCssIfToolstrip() { #if defined(TOOLKIT_VIEWS) ExtensionView* view = view_.get(); - if (view) { - // TODO(erikkay) this injection should really happen in the renderer. - // When the Jerry's view type change lands, investigate moving this there. - - // As a toolstrip, inject our toolstrip CSS to make it easier for toolstrips - // to blend in with the chrome UI. - if (view->is_toolstrip()) { - render_view_host->InsertCSSInWebFrame(L"", toolstrip_css.as_string()); - } else { - // No CSS injecting currently, but call SetDidInsertCSS to tell the view - // that it's OK to display. - view->SetDidInsertCSS(true); - } + if (!view) + return; + if (!view->is_toolstrip()) { + // No CSS injecting currently, but call SetDidInsertCSS to tell the view + // that it's OK to display. + view->SetDidInsertCSS(true); + return; } #elif defined(OS_LINUX) ExtensionViewGtk* view = view_.get(); - if (view && view->is_toolstrip()) { - render_view_host->InsertCSSInWebFrame(L"", toolstrip_css.as_string()); + if (!view || !view->is_toolstrip()) + return; +#endif + + static const base::StringPiece toolstrip_css( + ResourceBundle::GetSharedInstance().GetRawDataResource( + IDR_EXTENSIONS_TOOLSTRIP_CSS)); + + std::string css = toolstrip_css.as_string(); + ThemeProvider* theme_provider = + render_view_host()->process()->profile()->GetThemeProvider(); + + SkColor text_color = theme_provider ? + theme_provider->GetColor(BrowserThemeProvider::COLOR_BOOKMARK_TEXT) : + SK_ColorBLACK; + + std::string hex_color_string = StringPrintf( + "#%02x%02x%02x", SkColorGetR(text_color), + SkColorGetG(text_color), + SkColorGetB(text_color)); + size_t pos = css.find(kToolstripTextColorSubstitution); + while (pos != std::string::npos) { + css.replace(pos, 12, hex_color_string); + pos = css.find(kToolstripTextColorSubstitution); } + +#if defined(TOOLKIT_VIEWS) || defined(OS_LINUX) + // TODO(erikkay) this injection should really happen in the renderer. + // When the Jerry's view type change lands, investigate moving this there. + + // As a toolstrip, inject our toolstrip CSS to make it easier for toolstrips + // to blend in with the chrome UI. + render_view_host()->InsertCSSInWebFrame(L"", css, "ToolstripDefaultCss"); #endif +} +void ExtensionHost::DidStopLoading(RenderViewHost* render_view_host) { + InsertCssIfToolstrip(); if (!did_stop_loading_) { NotificationService::current()->Notify( NotificationType::EXTENSION_HOST_DID_STOP_LOADING, diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h index 76c1014..b6e25e5 100644 --- a/chrome/browser/extensions/extension_host.h +++ b/chrome/browser/extensions/extension_host.h @@ -76,6 +76,9 @@ class ExtensionHost : public RenderViewHostDelegate, // Sets |url_| and navigates |render_view_host_|. void NavigateToURL(const GURL& url); + // Insert the CSS for a toolstrip. + void InsertCssIfToolstrip(); + // RenderViewHostDelegate implementation. virtual RenderViewHostDelegate::View* GetViewDelegate(); virtual const GURL& GetURL() const { return url_; } diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index bab8ac8..6d92b81 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -510,8 +510,10 @@ void RenderViewHost::ExecuteJavascriptInWebFrame( } void RenderViewHost::InsertCSSInWebFrame( - const std::wstring& frame_xpath, const std::string& css) { - Send(new ViewMsg_CSSInsertRequest(routing_id(), frame_xpath, css)); + const std::wstring& frame_xpath, + const std::string& css, + const std::string& id) { + Send(new ViewMsg_CSSInsertRequest(routing_id(), frame_xpath, css, id)); } void RenderViewHost::AddMessageToConsole( @@ -611,7 +613,7 @@ void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, } void RenderViewHost::JavaScriptMessageBoxWindowDestroyed() { - ResetModalDialogEvent(); + ResetModalDialogEvent(); } void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg, @@ -1111,7 +1113,7 @@ void RenderViewHost::OnMsgFindReply(int request_id, void RenderViewHost::OnDeterminePageTextReply( const std::wstring& page_text) { -#if defined(OS_WIN) // Only for windows. +#if defined(OS_WIN) // Only for windows. int num_languages = 0; bool is_reliable = false; const char* language_iso_code = LanguageCodeISO639_1( @@ -1671,8 +1673,8 @@ void RenderViewHost::SignalModalDialogEvent() { } void RenderViewHost::ResetModalDialogEvent() { - if (--modal_dialog_count_ == 0) - modal_dialog_event_->Reset(); + if (--modal_dialog_count_ == 0) + modal_dialog_event_->Reset(); } void RenderViewHost::UpdateBrowserWindowId(int window_id) { diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 5be72a4..30f9709 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -258,9 +258,11 @@ class RenderViewHost : public RenderWidgetHost, void ExecuteJavascriptInWebFrame(const std::wstring& frame_xpath, const std::wstring& jscript); - // Insert some css into a frame in the page. + // Insert some css into a frame in the page. |id| is optional, and specifies + // the element id given when inserting/replacing the style element. void InsertCSSInWebFrame(const std::wstring& frame_xpath, - const std::string& css); + const std::string& css, + const std::string& id); // Logs a message to the console of a frame in the page. void AddMessageToConsole(const string16& frame_xpath, diff --git a/chrome/browser/resources/extensions_toolstrip.css b/chrome/browser/resources/extensions_toolstrip.css index ee88de6..456978f 100644 --- a/chrome/browser/resources/extensions_toolstrip.css +++ b/chrome/browser/resources/extensions_toolstrip.css @@ -12,8 +12,7 @@ body { margin: 0; padding:0; font: menu; - color: #062D75; - text-shadow: #FFFFFF 1px 1px 0px; + color: $TEXT_COLOR$; -webkit-user-select:none; cursor:default; } @@ -53,8 +52,7 @@ div.toolstrip-button { border:6px solid transparent; font:menu; background:transparent; - color: #062D75; - text-shadow: #FFFFFF 1px 1px 0px; + color: $TEXT_COLOR$; line-height:100%; padding:0; } @@ -88,10 +86,10 @@ div.toolstrip-button>span { */ div.toolstrip-button:hover { border-width:6px; - -webkit-border-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAaCAYAAACHD21cAAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAaFJREFUeNqklOlu2zAQhL+laFKHrSRt2vd/sj5AA7RpdFG0zM0PWT4Cx27dAfYPMcPZCys/fgZlD1U9CwAROYsFVuQo2MbIMPTEODJN00ywFuc8RVGycu7wgZW90zgMDH3D46Zi862mKnIAuiHQtAOvzStFuSEvilmoCtu4Zehbvn994KleowrTLqGAWzmevzhW1vLy+40sszjvsaCE0PO4qXh6WJMUkh7KBgEF6roiThNd6HHeYVSVOI7U6xxVSElPNRzbAVWRE8cRVcWiSko7ityTVM+Ipx8A5N6R0g5UMXMqijHCaYaXYIygKAiYj+ncwsI33AnzcSNuOu75/+F4d41yh93S1Tt0e0e5ntalRysnBLni8G9zFJnjAuxhjldIp+9ncxQRUko3m5JSOiyLMSLYLCOM8aZwjFtslmFEMGIE5z1dH7i1eX0IOO8RI7NjWZY0bUfbdJ+Kmqala3vKssSIzM1xzlGua379eSPuJoo8J/cegDCOdEOga3uqTY1bLt1Ls9XlPMYYGfpPzmNZHkUiWFiOLXif45z/q4P8PgC/bsLRhT00kAAAAABJRU5ErkJggg==) 6 round round; + -webkit-border-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAaCAYAAACHD21cAAAAAXNSR0IArs4c6QAAAAZiS0dEAPYA+QD9Ry7YfAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kJChUuJy+ouI4AAAFXSURBVDjL7dSxTsJQFIDh/95SmqpEYjASAgPGGI26wGv4BMbBVUZewBQfRBxAZ0cXG2d8AANoFEJgAGOAkqK31wEGJ23cTPiTs53vjEcAYj5RYAmwgAjQYlYG+AR8wAOmgAaQwLLjlHL1RrM4HI0rKtA1z1c1z1c1FejacDSu1BvNouOUcsAyIA3AcpzS7mmhcJxKpQ4Nw0yoQM9OAirQSCOSiMfjB3t7+6ux2ErHdd2BANbqjeZJNps9UsFs8adeX56rO9tbZQlYyWQyH4RAAIn1jTxgScCwbXsz0L8jANu2NwEjArSnn9okZEIIE2hL/tgCLuB/guloRHyEBVrrDyAtATWZTJ7CwvmukoDf7XYfpAgHe73uA+BLwKtWKu7bYHD/Gxr0+/fXV1UX8AwgcN2791hspZPJZIZm1Iqappn4DjzPe2y3W7eX5Yubc+fsEfDFXx/yF0HjkTNryckZAAAAAElFTkSuQmCC) 6 round round; } div.toolstrip-button:active { border-width:6px; - -webkit-border-image:url(data:image/png;base64,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) 6 round round; + -webkit-border-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAaCAYAAACHD21cAAAAAXNSR0IArs4c6QAAAAZiS0dEAPYA+QD9Ry7YfAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9kJChYWGmIZ9j0AAAGzSURBVDjLnZTBahNRFIa/c2+SyaRWBzddiBVCQ0Hqou67yCbgQnyC7NyluPUhHBCJeQLBVxDBbXwACY271iKBQBHbJE0nM3OPi9Q2qYqT+VeHyznn/89/7r2WBRhjSqpaBgTwgRRQ/gIB6HQ6prq1/ebx7u7+zQTVedbkfMLR4eHLrwe9V61WSwXgw8dP7Z1HO/t3bgfX7ZSlWFVJkoRe78vbOJq+KABsbj7YK3v+Ag1/xCJCsVikWt3au39vY874fTCM1m6tl6wxS/lyo4cAzrlZp/26bACMtSURIQtETMnzvAWKjLhSDjAYnmilsoZZYP2nVIVgvSzmcl+ZIUAYhiKAPxienOdhzIVc5oRhmMNVpwD+6lLnPsSrF+r1jFGOyqIBvByEkQGmOaR6udYhItOVr9z8V1DJO6MzQRBEUexms0Qzsjl837em2Wym4/G475zLVBhdTA9qtVpq2u327Pjb8fs0Sf/7MqJYOTs77TcaDbUAz54++awioqZ0V2xxI3UQp0qSKmmqJE4ZTyb9058/3j3crj6/+ld/o9vt2tFoVLHWXlweeQCFQmFSr9eXTPgFRPyveVqGdF0AAAAASUVORK5CYII=) 6 round round; } diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc index 96dc4b7..24b287c 100644 --- a/chrome/browser/views/bookmark_bar_view.cc +++ b/chrome/browser/views/bookmark_bar_view.cc @@ -80,9 +80,6 @@ static SkBitmap* kFolderIcon = NULL; // Border colors for the BookmarBarView. static const SkColor kTopBorderColor = SkColorSetRGB(222, 234, 248); -// How round the 'new tab' style bookmarks bar is. -static const int kNewtabBarRoundness = 5; - // Offset for where the menu is shown relative to the bottom of the // BookmarkBarView. static const int kMenuOffset = 3; @@ -297,25 +294,10 @@ class BookmarkBarView::ButtonSeparatorView : public views::View { virtual ~ButtonSeparatorView() {} virtual void Paint(gfx::Canvas* canvas) { - SkPaint paint; - paint.setShader(skia::CreateGradientShader(0, - height() / 2, - kTopBorderColor, - kSeparatorColor))->safeUnref(); - SkRect rc = {SkIntToScalar(kSeparatorStartX), SkIntToScalar(0), - SkIntToScalar(1), SkIntToScalar(height() / 2) }; - canvas->drawRect(rc, paint); - - SkPaint paint_down; - paint_down.setShader(skia::CreateGradientShader(height() / 2, - height(), + DetachableToolbarView::PaintVerticalDivider( + canvas, kSeparatorStartX, height(), 1, kTopBorderColor, kSeparatorColor, - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR) - ))->safeUnref(); - SkRect rc_down = { - SkIntToScalar(kSeparatorStartX), SkIntToScalar(height() / 2), - SkIntToScalar(1), SkIntToScalar(height() - 1) }; - canvas->drawRect(rc_down, paint_down); + GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); } virtual gfx::Size GetPreferredSize() { @@ -736,8 +718,8 @@ void BookmarkBarView::OnStateChanged() { // re-enter her password. If extension shelf appears along with the bookmark // shelf, it too needs to be layed out. Since both have the same parent, it is // enough to let the parent layout both of these children. - // TODO (sky): This should not require Layout() and SchedulePaint(). Needs - // some cleanup. + // TODO(sky): This should not require Layout() and SchedulePaint(). Needs + // some cleanup. PreferredSizeChanged(); Layout(); SchedulePaint(); @@ -751,15 +733,19 @@ void BookmarkBarView::OnFullscreenToggled(bool fullscreen) { size_animation_->Reset(0); } -bool BookmarkBarView::IsDetachedStyle() { +bool BookmarkBarView::IsDetached() const { return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); } -bool BookmarkBarView::IsAlwaysShown() { +bool BookmarkBarView::IsOnTop() const { + return true; +} + +bool BookmarkBarView::IsAlwaysShown() const { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); } -bool BookmarkBarView::OnNewTabPage() { +bool BookmarkBarView::OnNewTabPage() const { return (browser_ && browser_->GetSelectedTabContents() && browser_->GetSelectedTabContents()->IsBookmarkBarAlwaysVisible()); } @@ -1090,7 +1076,7 @@ void BookmarkBarView::RunMenu(views::View* view, int x = view->GetX(APPLY_MIRRORING_TRANSFORMATION); int bar_height = height() - kMenuOffset; - if (IsDetachedStyle()) + if (IsDetached()) bar_height -= kNewtabVerticalPadding; int start_index = 0; @@ -1685,7 +1671,8 @@ gfx::Size BookmarkBarView::LayoutItems(bool compute_bounds_only) { if (should_show_sync_error_button) { x += kButtonPadding; if (!compute_bounds_only) { - sync_error_button_->SetBounds(x, y, sync_error_button_pref.width(), height); + sync_error_button_->SetBounds( + x, y, sync_error_button_pref.width(), height); sync_error_button_->SetVisible(true); } x += sync_error_button_pref.width(); diff --git a/chrome/browser/views/bookmark_bar_view.h b/chrome/browser/views/bookmark_bar_view.h index 06b44f2..20fcc07 100644 --- a/chrome/browser/views/bookmark_bar_view.h +++ b/chrome/browser/views/bookmark_bar_view.h @@ -11,6 +11,7 @@ #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/views/bookmark_menu_controller_views.h" +#include "chrome/browser/views/detachable_toolbar_view.h" #include "chrome/common/notification_registrar.h" #include "views/controls/button/menu_button.h" #include "views/controls/label.h" @@ -33,7 +34,7 @@ class MenuItemView; // BookmarkBarView shows the bookmarks from a specific Profile. BookmarkBarView // waits until the HistoryService for the profile has been loaded before // creating the BookmarkModel. -class BookmarkBarView : public views::View, +class BookmarkBarView : public DetachableToolbarView, #ifdef CHROME_PERSONALIZATION public ProfileSyncServiceObserver, #endif @@ -88,6 +89,13 @@ class BookmarkBarView : public views::View, // the bookmark bar. void SetPageNavigator(PageNavigator* navigator); + // DetachableToolbarView methods: + virtual bool IsDetached() const; + virtual bool IsOnTop() const; + virtual double GetAnimationValue() const { + return size_animation_->GetCurrentValue(); + } + // View methods: virtual gfx::Size GetPreferredSize(); virtual gfx::Size GetMinimumSize(); @@ -108,9 +116,6 @@ class BookmarkBarView : public views::View, virtual bool GetAccessibleName(std::wstring* name); virtual bool GetAccessibleRole(AccessibilityTypes::Role* role); virtual void SetAccessibleName(const std::wstring& name); - double GetSizeAnimationValue() const { - return size_animation_->GetCurrentValue(); - } #ifdef CHROME_PERSONALIZATION // ProfileSyncServiceObserver method. @@ -143,15 +148,11 @@ class BookmarkBarView : public views::View, // Returns the model. BookmarkModel* GetModel() { return model_; } - // Returns true if the bookmark bar is drawn detached from the toolbar. This - // can only be true when OnNewTabPage() is true (see below). - bool IsDetachedStyle(); - // Returns true if the bookmarks bar preference is set to 'always show'. - bool IsAlwaysShown(); + bool IsAlwaysShown() const; // True if we're on a page where the bookmarks bar is always visible. - bool OnNewTabPage(); + bool OnNewTabPage() const; // How much we want the bookmark bar to overlap the toolbar. If |return_max| // is true, we return the maximum overlap rather than the current overlap. diff --git a/chrome/browser/views/detachable_toolbar_view.cc b/chrome/browser/views/detachable_toolbar_view.cc new file mode 100644 index 0000000..9cc81d2 --- /dev/null +++ b/chrome/browser/views/detachable_toolbar_view.cc @@ -0,0 +1,262 @@ +// 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/views/detachable_toolbar_view.h" + +#include "app/gfx/canvas.h" +#include "chrome/browser/browser_theme_provider.h" +#include "grit/theme_resources.h" +#include "third_party/skia/include/core/SkBitmap.h" + +// How round the 'new tab' style bookmarks bar is. +static const int kNewtabBarRoundness = 5; + +// static +void DetachableToolbarView::PaintBackgroundDetachedMode(gfx::Canvas* canvas, + views::View* view) { + int browser_height = view->GetParent()->GetBounds( + views::View::APPLY_MIRRORING_TRANSFORMATION).height(); + + // Draw the background to match the new tab page. + ThemeProvider* tp = view->GetThemeProvider(); + canvas->FillRectInt(tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND), + 0, 0, view->width(), view->height()); + + if (tp->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { + int tiling = BrowserThemeProvider::NO_REPEAT; + tp->GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_TILING, + &tiling); + int alignment; + if (tp->GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, + &alignment)) { + SkBitmap* ntp_background = tp->GetBitmapNamed(IDR_THEME_NTP_BACKGROUND); + + if (alignment & BrowserThemeProvider::ALIGN_TOP) { + PaintThemeBackgroundTopAligned( + canvas, ntp_background, tiling, alignment, + view->width(), view->height()); + } else { + PaintThemeBackgroundBottomAligned( + canvas, ntp_background, tiling, alignment, + view->width(), view->height(), browser_height); + } + } + } +} + +// static +void DetachableToolbarView::PaintBackgroundAttachedMode(gfx::Canvas* canvas, + views::View* view) { + gfx::Rect bounds = + view->GetBounds(views::View::APPLY_MIRRORING_TRANSFORMATION); + + ThemeProvider* tp = view->GetThemeProvider(); + SkColor theme_toolbar_color = + tp->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); + canvas->FillRectInt(theme_toolbar_color, 0, 0, + view->width(), view->height()); + + canvas->TileImageInt(*tp->GetBitmapNamed(IDR_THEME_TOOLBAR), + view->GetParent()->GetBounds( + views::View::APPLY_MIRRORING_TRANSFORMATION).x() + bounds.x(), + bounds.y(), 0, 0, view->width(), view->height()); +} + +// static +void DetachableToolbarView::CalculateContentArea( + double animation_state, double horizontal_padding, + double vertical_padding, SkRect* rect, + double* roundness, views::View* view) { + // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness. + rect->set(SkDoubleToScalar(horizontal_padding - 0.5), + SkDoubleToScalar(vertical_padding - 0.5), + SkDoubleToScalar(view->width() - horizontal_padding - 0.5), + SkDoubleToScalar(view->height() - vertical_padding - 0.5)); + + *roundness = static_cast<double>(kNewtabBarRoundness) * animation_state; +} + +// static +void DetachableToolbarView::PaintHorizontalBorder(gfx::Canvas* canvas, + DetachableToolbarView* view) { + // Border can be at the top or at the bottom of the view depending on whether + // the view (bar/shelf) is at the top/at the bottom and whether it is attached + // or detached. + int y = view->IsOnTop() == !view->IsDetached() ? view->height() - 1 : 0; + canvas->FillRectInt(ResourceBundle::toolbar_separator_color, + 0, y, view->width(), 1); +} + +// static +void DetachableToolbarView::PaintContentAreaBackground( + gfx::Canvas* canvas, ThemeProvider* theme_provider, + const SkRect& rect, double roundness) { + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(theme_provider->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); + + canvas->drawRoundRect( + rect, SkDoubleToScalar(roundness), SkDoubleToScalar(roundness), paint); +} + +// static +void DetachableToolbarView::PaintContentAreaBorder( + gfx::Canvas* canvas, ThemeProvider* theme_provider, + const SkRect& rect, double roundness) { + SkPaint border_paint; + border_paint.setColor( + theme_provider->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER)); + border_paint.setStyle(SkPaint::kStroke_Style); + border_paint.setAlpha(96); + border_paint.setAntiAlias(true); + + canvas->drawRoundRect(rect, + SkDoubleToScalar(roundness), + SkDoubleToScalar(roundness), border_paint); +} + +// static +void DetachableToolbarView::PaintVerticalDivider( + gfx::Canvas* canvas, int x, int height, int vertical_padding, + const SkColor& top_color, + const SkColor& middle_color, + const SkColor& bottom_color) { + // Draw the upper half of the divider. + SkPaint paint; + paint.setShader(skia::CreateGradientShader(vertical_padding + 1, + height / 2, + top_color, + middle_color))->safeUnref(); + SkRect rc = { SkIntToScalar(x), + SkIntToScalar(vertical_padding + 1), + SkIntToScalar(x + 1), + SkIntToScalar(height / 2) }; + canvas->drawRect(rc, paint); + + // Draw the lower half of the divider. + SkPaint paint_down; + paint_down.setShader(skia::CreateGradientShader(height / 2, + height - vertical_padding, + middle_color, + bottom_color))->safeUnref(); + SkRect rc_down = { SkIntToScalar(x), + SkIntToScalar(height / 2), + SkIntToScalar(x + 1), + SkIntToScalar(height - vertical_padding) }; + canvas->drawRect(rc_down, paint_down); +} + +// static +void DetachableToolbarView::PaintThemeBackgroundTopAligned( + gfx::Canvas* canvas, SkBitmap* ntp_background, int tiling, int alignment, + int width, int height) { + if (alignment & BrowserThemeProvider::ALIGN_LEFT) { + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, 0, 0, width, height); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, 0, 0, width, + ntp_background->height()); + } else { + canvas->TileImageInt(*ntp_background, 0, 0, + ntp_background->width(), ntp_background->height()); + } + } else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) { + int x_pos = width % ntp_background->width() - ntp_background->width(); + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, x_pos, 0, + width + ntp_background->width(), height); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, x_pos, + 0, width + ntp_background->width(), ntp_background->height()); + } else { + canvas->TileImageInt(*ntp_background, width - ntp_background->width(), + 0, ntp_background->width(), ntp_background->height()); + } + } else { // ALIGN == CENTER + int x_pos = width > ntp_background->width() ? + ((width / 2 - ntp_background->width() / 2) % + ntp_background->width()) - ntp_background->width() : + width / 2 - ntp_background->width() / 2; + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, x_pos, 0, + width + ntp_background->width(), height); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, x_pos, 0, + width + ntp_background->width(), + ntp_background->height()); + } else { + canvas->TileImageInt(*ntp_background, + width / 2 - ntp_background->width() / 2, + 0, ntp_background->width(), ntp_background->height()); + } + } +} + +// static +void DetachableToolbarView::PaintThemeBackgroundBottomAligned( + gfx::Canvas* canvas, SkBitmap* ntp_background, int tiling, int alignment, + int width, int height, int browser_height) { + int border_width = 5; + int y_pos = ((tiling == BrowserThemeProvider::REPEAT_X) || + (tiling == BrowserThemeProvider::NO_REPEAT)) ? + browser_height - ntp_background->height() - height - border_width : + browser_height % ntp_background->height() - height - border_width - + ntp_background->height(); + + if (alignment & BrowserThemeProvider::ALIGN_LEFT) { + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, 0, y_pos, width, + 2 * height + ntp_background->height() + 5); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, 0, y_pos, width, + ntp_background->height()); + } else if (tiling == BrowserThemeProvider::REPEAT_Y) { + canvas->TileImageInt(*ntp_background, 0, y_pos, + ntp_background->width(), + 2 * height + ntp_background->height() + 5); + } else { + canvas->TileImageInt(*ntp_background, 0, y_pos, ntp_background->width(), + ntp_background->height()); + } + } else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) { + int x_pos = width % ntp_background->width() - ntp_background->width(); + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, x_pos, y_pos, + width + ntp_background->width(), + 2 * height + ntp_background->height() + 5); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, x_pos, y_pos, + width + ntp_background->width(), ntp_background->height()); + } else if (tiling == BrowserThemeProvider::REPEAT_Y) { + canvas->TileImageInt(*ntp_background, width - ntp_background->width(), + y_pos, ntp_background->width(), + 2 * height + ntp_background->height() + 5); + } else { + canvas->TileImageInt(*ntp_background, width - ntp_background->width(), + y_pos, ntp_background->width(), ntp_background->height()); + } + } else { // ALIGN == CENTER + int x_pos = width > ntp_background->width() ? + ((width / 2 - ntp_background->width() / 2) % + ntp_background->width()) - ntp_background->width() : + width / 2 - ntp_background->width() / 2; + if (tiling == BrowserThemeProvider::REPEAT) { + canvas->TileImageInt(*ntp_background, x_pos, y_pos, + width + ntp_background->width(), + 2 * height + ntp_background->height() + 5); + } else if (tiling == BrowserThemeProvider::REPEAT_X) { + canvas->TileImageInt(*ntp_background, x_pos, y_pos, + width + ntp_background->width(), ntp_background->height()); + } else if (tiling == BrowserThemeProvider::REPEAT_Y) { + canvas->TileImageInt(*ntp_background, + width / 2 - ntp_background->width() / 2, + y_pos, ntp_background->width(), + 2 * height + ntp_background->height() + 5); + } else { + canvas->TileImageInt(*ntp_background, + width / 2 - ntp_background->width() / 2, + y_pos, ntp_background->width(), ntp_background->height()); + } + } +} diff --git a/chrome/browser/views/detachable_toolbar_view.h b/chrome/browser/views/detachable_toolbar_view.h new file mode 100644 index 0000000..f831ea1 --- /dev/null +++ b/chrome/browser/views/detachable_toolbar_view.h @@ -0,0 +1,98 @@ +// 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_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ +#define CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ + +#include "views/view.h" + +class SkBitmap; +struct SkRect; + +// DetachableToolbarView contains functionality common to views that can detach +// from the Chrome frame, such as the BookmarkBarView and the Extension shelf. +class DetachableToolbarView : public views::View { + public: + DetachableToolbarView() {} + virtual ~DetachableToolbarView() {} + + // Whether the view is currently detached from the Chrome frame. + virtual bool IsDetached() const = 0; + + // Whether the shelf/bar is above the page or below it. + virtual bool IsOnTop() const = 0; + + // Gets the current state of the resize animation (show/hide). + virtual double GetAnimationValue() const = 0; + + // Paint the background (including the theme image behind content area) when + // in bar/shelf is detached from the Chrome frame. + static void PaintBackgroundDetachedMode(gfx::Canvas* canvas, + views::View* view); + + // Paint the background (including the theme image behind content area) when + // in bar/shelf is attached to the Chrome frame. + static void PaintBackgroundAttachedMode(gfx::Canvas* canvas, + views::View* view); + + // Calculate the rect for the content area of the bar/shelf. This is only + // needed when the bar/shelf is detached from the Chrome frame (otherwise the + // content area is the whole area of the bar/shelf. When detached, however, + // only a small round rectangle is for drawing our content on. This calculates + // how big this area is, where it is located within the shelf and how round + // the edges should be. + static void CalculateContentArea(double animation_state, + double horizontal_padding, + double vertical_padding, + SkRect* rect, + double* roundness, + views::View* view); + + // Paint the horizontal border separating the shelf/bar from the page content. + static void PaintHorizontalBorder(gfx::Canvas* canvas, + DetachableToolbarView* view); + + // Paint the background of the content area (the surface behind the + // bookmarks or extension toolstrips). |rect| is the rectangle to paint + // the background within. |roundness| describes the roundness of the corners. + static void PaintContentAreaBackground(gfx::Canvas* canvas, + ThemeProvider* theme_provider, + const SkRect& rect, + double roundness); + // Paint the border around the content area (when in detached mode). + static void PaintContentAreaBorder(gfx::Canvas* canvas, + ThemeProvider* theme_provider, + const SkRect& rect, + double roundness); + + // Paint a themed gradient divider at location |x|. The color of the divider + // is a gradient starting with |top_color| at the top, and changing into + // |middle_color| and then over to |bottom_color| as you go further down. + static void PaintVerticalDivider(gfx::Canvas* canvas, + int x, + int height, + int vertical_padding, + const SkColor& top_color, + const SkColor& middle_color, + const SkColor& bottom_color); + + // Paint the theme background with the proper alignment. + static void PaintThemeBackgroundTopAligned(gfx::Canvas* canvas, + SkBitmap* ntp_background, + int tiling, + int alignment, + int width, + int height); + static void PaintThemeBackgroundBottomAligned(gfx::Canvas* canvas, + SkBitmap* ntp_background, + int tiling, + int alignment, + int width, + int height, + int browser_height); + private: + DISALLOW_COPY_AND_ASSIGN(DetachableToolbarView); +}; + +#endif // CHROME_BROWSER_VIEWS_DETACHABLE_TOOLBAR_VIEW_H_ diff --git a/chrome/browser/views/extensions/extension_shelf.cc b/chrome/browser/views/extensions/extension_shelf.cc index 91c20b6..22ae0d2 100644 --- a/chrome/browser/views/extensions/extension_shelf.cc +++ b/chrome/browser/views/extensions/extension_shelf.cc @@ -19,6 +19,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/views/extensions/extension_view.h" +#include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" @@ -45,7 +46,7 @@ static const int kToolstripDividerWidth = 2; static const int kShelfHeight = 29; // Preferred height of the Extension shelf when only shown on the new tab page. -const int kNewtabShelfHeight = 57; +const int kNewtabShelfHeight = 58; // How inset the extension shelf is when displayed on the new tab page. This is // in addition to the margins above. @@ -58,32 +59,18 @@ static const int kNewtabVerticalPadding = 12; static const int kNewtabExtraHorMargin = 2; static const int kNewtabExtraVerMargin = 2; -// How round the 'new tab' style extension shelf is. -static const int kNewtabBarRoundness = 5; - // Height of the toolstrip within the shelf. static const int kToolstripHeight = kShelfHeight - (kTopMargin + kBottomMargin); // Colors for the ExtensionShelf. -static const SkColor kBackgroundColor = SkColorSetRGB(230, 237, 244); -static const SkColor kBorderColor = SkColorSetRGB(201, 212, 225); static const SkColor kDividerHighlightColor = SkColorSetRGB(247, 250, 253); -// Text colors for the handle. -static const SkColor kHandleTextColor = SkColorSetRGB(6, 45, 117); -static const SkColor kHandleTextHighlightColor = - SkColorSetARGB(200, 255, 255, 255); - // Handle padding. static const int kHandlePadding = 4; -// TODO(erikkay) convert back to a gradient when Glen figures out the -// specs. -// static const SkColor kBackgroundColor = SkColorSetRGB(237, 244, 252); -// static const SkColor kTopGradientColor = SkColorSetRGB(222, 234, 248); - // Delays for showing and hiding the shelf handle. -static const int kHideDelayMs = 500; +static const int kShowDelayMs = 500; +static const int kHideDelayMs = 300; } // namespace @@ -122,7 +109,7 @@ class ExtensionShelf::Toolstrip : public views::View, // Convenience to calculate just the size of the handle. gfx::Size GetHandlePreferredSize(); - // View + // View methods: virtual void Paint(gfx::Canvas* canvas); virtual gfx::Size GetPreferredSize(); virtual void Layout(); @@ -255,9 +242,6 @@ ExtensionShelf::Toolstrip::Toolstrip(ExtensionShelf* shelf, // the various mouse events necessary for hovering and dragging. ResourceBundle& rb = ResourceBundle::GetSharedInstance(); title_.reset(new views::Label(name, rb.GetFont(ResourceBundle::BaseFont))); - title_->SetColor(kHandleTextColor); - title_->SetDrawHighlighted(true); - title_->SetHighlightColor(kHandleTextHighlightColor); title_->SetBounds(kHandlePadding, kHandlePadding, 100, 100); title_->SizeToPreferredSize(); @@ -270,14 +254,19 @@ ExtensionShelf::Toolstrip::~Toolstrip() { } void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) { - canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); - canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); - canvas->FillRectInt(kBorderColor, 0, 0, 1, height() - 1); - canvas->FillRectInt(kBorderColor, width() - 1, 0, 1, height() - 1); + // Paints the handle for the toolstrip (only called on mouse-hover). + SkColor theme_toolbar_color = + shelf_->GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR); + canvas->FillRectInt(theme_toolbar_color, 0, 0, width(), height()); + + SkColor border_color = ResourceBundle::toolbar_separator_color; + canvas->FillRectInt(border_color, 0, 0, width(), 1); + canvas->FillRectInt(border_color, 0, 0, 1, height() - 1); + canvas->FillRectInt(border_color, width() - 1, 0, 1, height() - 1); int ext_width = view()->width() + kToolstripPadding + kToolstripDividerWidth; if (ext_width < width()) { - canvas->FillRectInt(kBorderColor, ext_width, height() - 1, + canvas->FillRectInt(border_color, ext_width, height() - 1, width() - ext_width, 1); } @@ -286,8 +275,8 @@ void ExtensionShelf::Toolstrip::Paint(gfx::Canvas* canvas) { title_->ProcessPaint(canvas); if (dragging_) { - // when we're dragging, draw the bottom border. - canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); + // When we're dragging, draw the bottom border. + canvas->FillRectInt(border_color, 0, height() - 1, width(), 1); } } @@ -519,6 +508,11 @@ void ExtensionShelf::Toolstrip::AttachToShelf(bool browserAttach) { void ExtensionShelf::Toolstrip::DoShowShelfHandle() { GetHandle(); if (!handle_->visible()) { + // Make sure the text color for the title matches the theme colors. + title_->SetColor( + shelf_->GetThemeProvider()->GetColor( + BrowserThemeProvider::COLOR_BOOKMARK_TEXT)); + LayoutHandle(); handle_->Show(); } @@ -596,7 +590,7 @@ void ExtensionShelf::Toolstrip::ShowShelfHandle() { MessageLoop::current()->PostDelayedTask(FROM_HERE, timer_factory_.NewRunnableMethod( &ExtensionShelf::Toolstrip::DoShowShelfHandle), - 1000); + kShowDelayMs); } void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { @@ -618,7 +612,9 @@ void ExtensionShelf::Toolstrip::HideShelfHandle(int delay_ms) { //////////////////////////////////////////////////////////////////////////////// ExtensionShelf::ExtensionShelf(Browser* browser) - : browser_(browser), + : background_for_detached_(false), + browser_(browser), + background_needs_repaint_(true), model_(browser->extension_shelf_model()) { model_->AddObserver(this); LoadFromModel(); @@ -645,95 +641,27 @@ ExtensionShelf::~ExtensionShelf() { } } -void ExtensionShelf::Paint(gfx::Canvas* canvas) { - if (IsDetachedStyle()) { - // Draw the background to match the new tab page. - ThemeProvider* tp = GetThemeProvider(); - canvas->FillRectInt( - tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND), - 0, 0, width(), height()); - - // As 'hidden' according to the animation is the full in-tab state, - // we invert the value - when current_state is at '0', we expect the - // shelf to be docked. - double current_state = 1 - size_animation_->GetCurrentValue(); - - // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness. - double h_padding = static_cast<double> - (kNewtabHorizontalPadding) * current_state; - double v_padding = static_cast<double> - (kNewtabVerticalPadding) * current_state; - SkRect rect; - rect.set(SkDoubleToScalar(h_padding - 0.5), - SkDoubleToScalar(v_padding - 0.5), - SkDoubleToScalar(width() - h_padding - 0.5), - SkDoubleToScalar(height() - v_padding - 0.5)); - - double roundness = static_cast<double> - (kNewtabBarRoundness) * current_state; - - // Draw the background behind the toolstrips. - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(kBackgroundColor); - - canvas->drawRoundRect(rect, - SkDoubleToScalar(roundness), - SkDoubleToScalar(roundness), paint); - - SkRect background_rect = { - SkIntToScalar(h_padding), - SkIntToScalar(v_padding + 2), - SkIntToScalar(h_padding + 1), - SkIntToScalar(v_padding + kToolstripHeight - 3)}; - InitBackground(canvas, background_rect); - - // Draw the border around the toolstrips in the extension shelf. - SkPaint border_paint; - border_paint.setColor( - GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_NTP_HEADER)); - border_paint.setStyle(SkPaint::kStroke_Style); - border_paint.setAlpha(96); - border_paint.setAntiAlias(true); - canvas->drawRoundRect(rect, - SkDoubleToScalar(roundness), - SkDoubleToScalar(roundness), border_paint); - } else { -#if 0 - // TODO(erikkay) Re-enable when Glen has the gradient values worked out. - SkPaint paint; - paint.setShader(skia::CreateGradientShader(0, - height(), - kTopGradientColor, - kBackgroundColor))->safeUnref(); - canvas->FillRectInt(0, 0, width(), height(), paint); -#else - canvas->FillRectInt(kBackgroundColor, 0, 0, width(), height()); -#endif - - SkRect background_rect = { - SkIntToScalar(0), - SkIntToScalar(0), - SkIntToScalar(1), - SkIntToScalar(height()) - }; - InitBackground(canvas, background_rect); - - // Draw border around shelf in attached mode. If we are in detached mode - // we've already drawn the borders. - canvas->FillRectInt(kBorderColor, 0, 0, width(), 1); - canvas->FillRectInt(kBorderColor, 0, height() - 1, width(), 1); - } +void ExtensionShelf::PaintChildren(gfx::Canvas* canvas) { + // Capture a background bitmap to give to the toolstrips. + SkRect background_rect = { + SkIntToScalar(0), + SkIntToScalar(0), + SkIntToScalar(width()), + SkIntToScalar(height()) + }; + InitBackground(canvas, background_rect); // Draw vertical dividers between Toolstrip items in the Extension shelf. int count = GetChildViewCount(); for (int i = 0; i < count; ++i) { int right = GetChildViewAt(i)->bounds().right() + kToolstripPadding; - int y = IsDetachedStyle() ? kNewtabVerticalPadding : 1; - int h = IsDetachedStyle() ? height() - (2 * kNewtabVerticalPadding) - 1: - height() - 2; - canvas->FillRectInt(kBorderColor, right, y, 1, h); - canvas->FillRectInt(kDividerHighlightColor, right + 1, y, 1, h); + int vertical_padding = IsDetached() ? (height() - kShelfHeight) / 2 : 1; + + DetachableToolbarView::PaintVerticalDivider( + canvas, right, height(), vertical_padding, + SK_ColorWHITE, + kDividerHighlightColor, + GetThemeProvider()->GetColor(BrowserThemeProvider::COLOR_TOOLBAR)); } } @@ -771,7 +699,6 @@ void ExtensionShelf::Layout() { LayoutItems(false); } - void ExtensionShelf::OnMouseEntered(const views::MouseEvent& event) { } @@ -799,6 +726,17 @@ void ExtensionShelf::SetAccessibleName(const std::wstring& name) { accessible_name_.assign(name); } +void ExtensionShelf::ThemeChanged() { + background_needs_repaint_ = true; + + // Refresh the CSS to update toolstrip text colors from theme. + int count = model_->count(); + for (int i = 0; i < count; ++i) + ToolstripAtIndex(i)->view()->host()->InsertCssIfToolstrip(); + + Layout(); +} + void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, int index) { model_->SetToolstripDataAt(index, @@ -806,8 +744,7 @@ void ExtensionShelf::ToolstripInsertedAt(ExtensionHost* host, bool had_views = GetChildViewCount() > 0; ExtensionView* view = host->view(); - if (!background_.empty()) - view->SetBackground(background_); + background_needs_repaint_ = true; AddChildView(view); view->SetContainer(this); if (!had_views) @@ -876,7 +813,8 @@ void ExtensionShelf::AnimationEnded(const Animation* animation) { if (browser_) browser_->ExtensionShelfSizeChanged(); - SchedulePaint(); + background_needs_repaint_ = true; + Layout(); } void ExtensionShelf::Observe(NotificationType type, @@ -936,38 +874,49 @@ void ExtensionShelf::CollapseToolstrip(ExtensionHost* host, const GURL& url) { model_->CollapseToolstrip(toolstrip, url); } -void ExtensionShelf::InitBackground(gfx::Canvas* canvas, const SkRect& subset) { - if (!background_.empty()) - return; - - const SkBitmap& background = canvas->getDevice()->accessBitmap(false); - - // Extract the correct subset of the toolstrip background into a bitmap. We - // must use a temporary here because extractSubset() returns a bitmap that - // references pixels in the original one and we want to actually make a copy - // that will have a long lifetime. - SkBitmap temp; - temp.setConfig(background.config(), - static_cast<int>(subset.width()), - static_cast<int>(subset.height())); - - SkRect mapped_subset = subset; - bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); - DCHECK(result); - - SkIRect isubset; - mapped_subset.round(&isubset); - result = background.extractSubset(&temp, isubset); - if (!result) +void ExtensionShelf::InitBackground( + gfx::Canvas* canvas, const SkRect& subset) { + bool detached = IsDetached(); + if (!background_needs_repaint_ && background_for_detached_ == detached) return; - temp.copyTo(&background_, temp.config()); - DCHECK(background_.readyToDraw()); + background_for_detached_ = detached; // Tell all extension views about the new background int count = model_->count(); - for (int i = 0; i < count; ++i) - ToolstripAtIndex(i)->view()->SetBackground(background_); + for (int i = 0; i < count; ++i) { + ExtensionView* view = ToolstripAtIndex(i)->view(); + + const SkBitmap& background = canvas->getDevice()->accessBitmap(false); + + // Extract the correct subset of the toolstrip background into a bitmap. We + // must use a temporary here because extractSubset() returns a bitmap that + // references pixels in the original one and we want to actually make a copy + // that will have a long lifetime. + SkBitmap temp; + temp.setConfig(background.config(), + static_cast<int>(subset.width()), + static_cast<int>(subset.height())); + + SkRect mapped_subset = subset; + gfx::Rect view_bounds = view->bounds(); + mapped_subset.offset(SkIntToScalar(view_bounds.x()), + SkIntToScalar(view_bounds.y())); + bool result = canvas->getTotalMatrix().mapRect(&mapped_subset); + DCHECK(result); + + SkIRect isubset; + mapped_subset.round(&isubset); + result = background.extractSubset(&temp, isubset); + if (!result) + return; + + DCHECK(temp.readyToDraw()); + + view->SetBackground(temp); + } + + background_needs_repaint_ = false; } ExtensionShelf::Toolstrip* ExtensionShelf::ToolstripAtX(int x) { @@ -1032,13 +981,13 @@ gfx::Size ExtensionShelf::LayoutItems(bool compute_bounds_only) { int count = model_->count(); for (int i = 0; i < count; ++i) { - x += kToolstripPadding; // left padding + x += kToolstripPadding; // Left padding. Toolstrip* toolstrip = ToolstripAtIndex(i); - if (!toolstrip) // can be NULL while in the process of removing + if (!toolstrip) // Can be NULL while in the process of removing. continue; View* view = toolstrip->GetShelfView(); gfx::Size pref = view->GetPreferredSize(); - int next_x = x + pref.width() + kToolstripPadding; // right padding + int next_x = x + pref.width() + kToolstripPadding; // Right padding. if (!compute_bounds_only) { if (view == toolstrip->view()) toolstrip->view()->set_is_clipped(next_x >= max_x); @@ -1070,16 +1019,22 @@ gfx::Size ExtensionShelf::LayoutItems(bool compute_bounds_only) { return prefsize; } -bool ExtensionShelf::IsDetachedStyle() { +bool ExtensionShelf::IsOnTop() const { + static bool is_on_top = CommandLine::ForCurrentProcess()->HasSwitch( + switches::kShowExtensionsOnTop); + return is_on_top; +} + +bool ExtensionShelf::IsDetached() const { return OnNewTabPage() && (size_animation_->GetCurrentValue() != 1); } -bool ExtensionShelf::IsAlwaysShown() { +bool ExtensionShelf::IsAlwaysShown() const { Profile* profile = browser_->profile(); return profile->GetPrefs()->GetBoolean(prefs::kShowExtensionShelf); } -bool ExtensionShelf::OnNewTabPage() { +bool ExtensionShelf::OnNewTabPage() const { return (browser_ && browser_->GetSelectedTabContents() && browser_->GetSelectedTabContents()->IsExtensionShelfAlwaysVisible()); } diff --git a/chrome/browser/views/extensions/extension_shelf.h b/chrome/browser/views/extensions/extension_shelf.h index 3f994e4..c15921b 100644 --- a/chrome/browser/views/extensions/extension_shelf.h +++ b/chrome/browser/views/extensions/extension_shelf.h @@ -11,6 +11,7 @@ #include "chrome/browser/extensions/extension_shelf_model.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/views/browser_bubble.h" +#include "chrome/browser/views/detachable_toolbar_view.h" #include "views/view.h" class Browser; @@ -20,7 +21,7 @@ namespace views { } // A shelf that contains Extension toolstrips. -class ExtensionShelf : public views::View, +class ExtensionShelf : public DetachableToolbarView, public ExtensionContainer, public ExtensionShelfModelObserver, public AnimationDelegate, @@ -32,14 +33,18 @@ class ExtensionShelf : public views::View, // Get the current model. ExtensionShelfModel* model() { return model_; } - // Returns whether the extension shelf is detached from the Chrome frame. - bool IsDetachedStyle(); - // Toggles a preference for whether to always show the extension shelf. static void ToggleWhenExtensionShelfVisible(Profile* profile); - // View - virtual void Paint(gfx::Canvas* canvas); + // DetachableToolbarView methods: + virtual bool IsOnTop() const; + virtual bool IsDetached() const; + virtual double GetAnimationValue() const { + return size_animation_->GetCurrentValue(); + } + + // View methods: + virtual void PaintChildren(gfx::Canvas* canvas); virtual gfx::Size GetPreferredSize(); virtual void Layout(); virtual void OnMouseExited(const views::MouseEvent& event); @@ -47,12 +52,13 @@ class ExtensionShelf : 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(); - // ExtensionContainer + // ExtensionContainer methods: virtual void OnExtensionMouseEvent(ExtensionView* view); virtual void OnExtensionMouseLeave(ExtensionView* view); - // ExtensionShelfModelObserver + // ExtensionShelfModelObserver methods: virtual void ToolstripInsertedAt(ExtensionHost* toolstrip, int index); virtual void ToolstripRemovingAt(ExtensionHost* toolstrip, int index); virtual void ToolstripDraggingFrom(ExtensionHost* toolstrip, int index); @@ -64,17 +70,17 @@ class ExtensionShelf : public views::View, virtual void ShelfModelReloaded(); virtual void ShelfModelDeleting(); - // AnimationDelegate + // AnimationDelegate methods: virtual void AnimationProgressed(const Animation* animation); virtual void AnimationEnded(const Animation* animation); - // NotificationObserver + // NotificationObserver methods: virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); protected: - // View + // View methods: virtual void ChildPreferredSizeChanged(View* child); private: @@ -92,7 +98,7 @@ class ExtensionShelf : public views::View, // Collapse the specified toolstrip, navigating to |url| if non-empty. void CollapseToolstrip(ExtensionHost* host, const GURL& url); - // Inits the background bitmap. + // Initializes the background bitmaps for all views. void InitBackground(gfx::Canvas* canvas, const SkRect& subset); // Returns the Toolstrip at |x| coordinate. If |x| is out of bounds, returns @@ -115,16 +121,21 @@ class ExtensionShelf : public views::View, gfx::Size LayoutItems(bool compute_bounds_only); // Returns whether the extension shelf always shown (checks pref value). - bool IsAlwaysShown(); + bool IsAlwaysShown() const; // Returns whether the extension shelf is being displayed over the new tab // page. - bool OnNewTabPage(); + bool OnNewTabPage() const; NotificationRegistrar registrar_; // Background bitmap to draw under extension views. - SkBitmap background_; + bool background_needs_repaint_; + + // Whether the background we are remembering is for detached mode or not. + // This allows us to switch backgrounds and remember if we've done so, so that + // we don't have to do it over and over again. + bool background_for_detached_; // The browser this extension shelf belongs to. Browser* browser_; diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index e42262d..beef3f4 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -127,254 +127,59 @@ static const char kBrowserViewClassName[] = "browser/views/BrowserView"; // and paint the bookmark bar. class BookmarkExtensionBackground : public views::Background { public: - explicit BookmarkExtensionBackground(BrowserView* browser_view); + explicit BookmarkExtensionBackground(BrowserView* browser_view, + DetachableToolbarView* host_view); // View methods overridden from views:Background. virtual void Paint(gfx::Canvas* canvas, views::View* view) const; private: - // Paint the theme background with the proper alignment. - void PaintThemeBackgroundTopAligned(gfx::Canvas* canvas, - SkBitmap* ntp_background, int tiling, int alignment) const; - void PaintThemeBackgroundBottomAligned(gfx::Canvas* canvas, - SkBitmap* ntp_background, int tiling, int alignment) const; - BrowserView* browser_view_; + // The view hosting this background. + DetachableToolbarView* host_view_; + DISALLOW_COPY_AND_ASSIGN(BookmarkExtensionBackground); }; BookmarkExtensionBackground::BookmarkExtensionBackground( - BrowserView* browser_view) - : browser_view_(browser_view) { + BrowserView* browser_view, + DetachableToolbarView* host_view) + : browser_view_(browser_view), + host_view_(host_view) { } void BookmarkExtensionBackground::Paint(gfx::Canvas* canvas, - views::View* view) const { - // Paint the bookmark bar. - BookmarkBarView* bookmark_bar_view = browser_view_->GetBookmarkBarView(); - if (bookmark_bar_view->IsDetachedStyle()) { + views::View* view) const { + ThemeProvider* tp = host_view_->GetThemeProvider(); + if (host_view_->IsDetached()) { // Draw the background to match the new tab page. - ThemeProvider* tp = bookmark_bar_view->GetThemeProvider(); - canvas->FillRectInt( - tp->GetColor(BrowserThemeProvider::COLOR_NTP_BACKGROUND), - 0, 0, bookmark_bar_view->width(), bookmark_bar_view->height()); - - if (tp->HasCustomImage(IDR_THEME_NTP_BACKGROUND)) { - int tiling = BrowserThemeProvider::NO_REPEAT; - tp->GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_TILING, - &tiling); - int alignment; - if (tp->GetDisplayProperty(BrowserThemeProvider::NTP_BACKGROUND_ALIGNMENT, - &alignment)) { - SkBitmap* ntp_background = tp->GetBitmapNamed( - IDR_THEME_NTP_BACKGROUND); - - if (alignment & BrowserThemeProvider::ALIGN_TOP) { - PaintThemeBackgroundTopAligned(canvas, ntp_background, tiling, - alignment); - } else { - PaintThemeBackgroundBottomAligned(canvas, ntp_background, tiling, - alignment); - } - } - } - - // Draw the 'bottom' of the toolbar above our bubble. - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, 0, 0, - bookmark_bar_view->width(), 1); + DetachableToolbarView::PaintBackgroundDetachedMode(canvas, host_view_); SkRect rect; // As 'hidden' according to the animation is the full in-tab state, // we invert the value - when current_state is at '0', we expect the // bar to be docked. - double current_state = 1 - bookmark_bar_view->GetSizeAnimationValue(); + double current_state = 1 - host_view_->GetAnimationValue(); // The 0.5 is to correct for Skia's "draw on pixel boundaries"ness. double h_padding = static_cast<double> - (BookmarkBarView::kNewtabHorizontalPadding) * current_state; + (BookmarkBarView::kNewtabHorizontalPadding) * current_state; double v_padding = static_cast<double> - (BookmarkBarView::kNewtabVerticalPadding) * current_state; - rect.set(SkDoubleToScalar(h_padding - 0.5), - SkDoubleToScalar(v_padding - 0.5), - SkDoubleToScalar(bookmark_bar_view->width() - h_padding - 0.5), - SkDoubleToScalar(bookmark_bar_view->height() - v_padding - 0.5)); - - double roundness = static_cast<double> - (kNewtabBarRoundness) * current_state; - - // Draw our background. - SkPaint paint; - paint.setAntiAlias(true); - paint.setColor(bookmark_bar_view->GetThemeProvider()->GetColor( - BrowserThemeProvider::COLOR_TOOLBAR)); - - canvas->drawRoundRect(rect, - SkDoubleToScalar(roundness), - SkDoubleToScalar(roundness), paint); - - // Draw border - SkPaint border_paint; - border_paint.setColor(bookmark_bar_view->GetThemeProvider()->GetColor( - BrowserThemeProvider::COLOR_NTP_HEADER)); - border_paint.setStyle(SkPaint::kStroke_Style); - border_paint.setAlpha(96); - border_paint.setAntiAlias(true); - - canvas->drawRoundRect(rect, - SkDoubleToScalar(roundness), - SkDoubleToScalar(roundness), border_paint); + (BookmarkBarView::kNewtabVerticalPadding) * current_state; + double roundness = 0; + + DetachableToolbarView::CalculateContentArea(current_state, + h_padding, v_padding, + &rect, &roundness, host_view_); + DetachableToolbarView::PaintContentAreaBackground( + canvas, tp, rect, roundness); + DetachableToolbarView::PaintContentAreaBorder(canvas, tp, rect, roundness); + DetachableToolbarView::PaintHorizontalBorder(canvas, host_view_); } else { - gfx::Rect bounds = bookmark_bar_view->GetBounds(views::View:: - APPLY_MIRRORING_TRANSFORMATION); - - SkColor theme_toolbar_color = - bookmark_bar_view->GetThemeProvider()->GetColor(BrowserThemeProvider:: - COLOR_TOOLBAR); - canvas->FillRectInt(theme_toolbar_color, 0, 0, - bookmark_bar_view->width(), - bookmark_bar_view->height()); - - canvas->TileImageInt( - *browser_view_->GetBookmarkBarView()->GetThemeProvider()-> - GetBitmapNamed(IDR_THEME_TOOLBAR), - bookmark_bar_view->GetParent()->GetBounds(views:: - View::APPLY_MIRRORING_TRANSFORMATION).x() + bounds.x(), bounds.y(), - 0, 0, - bookmark_bar_view->width(), - bookmark_bar_view->height()); - canvas->FillRectInt(ResourceBundle::toolbar_separator_color, - 0, - bookmark_bar_view->height() - 1, - bookmark_bar_view->width(), 1); - } -} - -void BookmarkExtensionBackground::PaintThemeBackgroundTopAligned( - gfx::Canvas* canvas, SkBitmap* ntp_background, int tiling, - int alignment) const { - BookmarkBarView* bookmark_bar_view = browser_view_->GetBookmarkBarView(); - if (alignment & BrowserThemeProvider::ALIGN_LEFT) { - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, 0, 0, - bookmark_bar_view->width(), bookmark_bar_view->height()); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, 0, 0, - bookmark_bar_view->width(), - ntp_background->height()); - else - canvas->TileImageInt(*ntp_background, 0, 0, - ntp_background->width(), ntp_background->height()); - - } else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) { - int x_pos = bookmark_bar_view->width() % ntp_background->width() - - ntp_background->width(); - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, x_pos, 0, - bookmark_bar_view->width() + ntp_background->width(), - bookmark_bar_view->height()); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, x_pos, - 0, bookmark_bar_view->width() + ntp_background->width(), - ntp_background->height()); - else - canvas->TileImageInt(*ntp_background, - bookmark_bar_view->width() - ntp_background->width(), 0, - ntp_background->width(), ntp_background->height()); - - } else { // ALIGN == CENTER - int x_pos = bookmark_bar_view->width() > ntp_background->width() ? - ((bookmark_bar_view->width() / 2 - ntp_background->width() / 2) % - ntp_background->width()) - ntp_background->width() : - bookmark_bar_view->width() / 2 - ntp_background->width() / 2; - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, x_pos, 0, - bookmark_bar_view->width() + ntp_background->width(), - bookmark_bar_view->height()); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, x_pos, 0, - bookmark_bar_view->width() + ntp_background->width(), - ntp_background->height()); - else - canvas->TileImageInt(*ntp_background, - bookmark_bar_view->width() / 2 - ntp_background->width() / 2, - 0, ntp_background->width(), ntp_background->height()); - } -} - -void BookmarkExtensionBackground::PaintThemeBackgroundBottomAligned( - gfx::Canvas* canvas, SkBitmap* ntp_background, int tiling, - int alignment) const { - BookmarkBarView* bookmark_bar_view = browser_view_->GetBookmarkBarView(); - int browser_height = bookmark_bar_view->GetParent()->GetBounds( - views::View::APPLY_MIRRORING_TRANSFORMATION).height(); - int border_width = 5; - int y_pos = ((tiling == BrowserThemeProvider::REPEAT_X) || - (tiling == BrowserThemeProvider::NO_REPEAT)) ? - browser_height - ntp_background->height() - bookmark_bar_view->height() - - border_width : - browser_height % ntp_background->height() - bookmark_bar_view->height() - - border_width - ntp_background->height(); - - if (alignment & BrowserThemeProvider::ALIGN_LEFT) { - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, 0, y_pos, - bookmark_bar_view->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, 0, y_pos, - bookmark_bar_view->width(), ntp_background->height()); - else if (tiling == BrowserThemeProvider::REPEAT_Y) - canvas->TileImageInt(*ntp_background, 0, y_pos, - ntp_background->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else - canvas->TileImageInt(*ntp_background, 0, y_pos, ntp_background->width(), - ntp_background->height()); - - } else if (alignment & BrowserThemeProvider::ALIGN_RIGHT) { - int x_pos = bookmark_bar_view->width() % ntp_background->width() - - ntp_background->width(); - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, x_pos, y_pos, - bookmark_bar_view->width() + ntp_background->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, x_pos, y_pos, - bookmark_bar_view->width() + ntp_background->width(), - ntp_background->height()); - else if (tiling == BrowserThemeProvider::REPEAT_Y) - canvas->TileImageInt(*ntp_background, bookmark_bar_view->width() - - ntp_background->width(), y_pos, ntp_background->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else - canvas->TileImageInt(*ntp_background, - bookmark_bar_view->width() - ntp_background->width(), - y_pos, ntp_background->width(), ntp_background->height()); - - } else { // ALIGN == CENTER - int x_pos = bookmark_bar_view->width() > ntp_background->width() ? - ((bookmark_bar_view->width() / 2 - ntp_background->width() / 2) % - ntp_background->width()) - ntp_background->width() : - bookmark_bar_view->width() / 2 - ntp_background->width() / 2; - if (tiling == BrowserThemeProvider::REPEAT) - canvas->TileImageInt(*ntp_background, x_pos, y_pos, - bookmark_bar_view->width() + ntp_background->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else if (tiling == BrowserThemeProvider::REPEAT_X) - canvas->TileImageInt(*ntp_background, x_pos, y_pos, - bookmark_bar_view->width() + ntp_background->width(), - ntp_background->height()); - else if (tiling == BrowserThemeProvider::REPEAT_Y) - canvas->TileImageInt(*ntp_background, - bookmark_bar_view->width() / 2 - ntp_background->width() / 2, - y_pos, ntp_background->width(), - 2 * bookmark_bar_view->height() + ntp_background->height() + 5); - else - canvas->TileImageInt(*ntp_background, - bookmark_bar_view->width() / 2 - ntp_background->width() / 2, - y_pos, ntp_background->width(), ntp_background->height()); + DetachableToolbarView::PaintBackgroundAttachedMode(canvas, host_view_); + DetachableToolbarView::PaintHorizontalBorder(canvas, host_view_); } } @@ -1829,6 +1634,8 @@ void BrowserView::Init() { if (browser_->SupportsWindowFeature(Browser::FEATURE_EXTENSIONSHELF)) { extension_shelf_ = new ExtensionShelf(browser_.get()); + extension_shelf_->set_background( + new BookmarkExtensionBackground(this, extension_shelf_)); extension_shelf_-> SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_EXTENSIONS)); AddChildView(extension_shelf_); @@ -1900,7 +1707,7 @@ int BrowserView::LayoutBookmarkAndInfoBars(int top) { // If we're showing the Bookmark bar in detached style, then we need to show // any Info bar _above_ the Bookmark bar, since the Bookmark bar is styled // to look like it's part of the page. - if (bookmark_bar_view_->IsDetachedStyle()) + if (bookmark_bar_view_->IsDetached()) return LayoutTopBar(LayoutInfoBar(top)); // Otherwise, Bookmark bar first, Info bar second. top = LayoutTopBar(top); @@ -1922,17 +1729,17 @@ int BrowserView::LayoutTopBar(int top) { if (!IsBookmarkBarVisible()) { bookmark_bar_view_->SetVisible(false); bookmark_bar_view_->SetBounds(0, y, width(), 0); - if (ShowExtensionsOnTop()) + if (extension_shelf_->IsOnTop()) extension_shelf_->SetVisible(false); return y; } int bookmark_bar_height = bookmark_bar_view_->GetPreferredSize().height(); - y -= kSeparationLineHeight + (bookmark_bar_view_->IsDetachedStyle() ? + y -= kSeparationLineHeight + (bookmark_bar_view_->IsDetached() ? 0 : bookmark_bar_view_->GetToolbarOverlap(false)); - if (ShowExtensionsOnTop()) { - if (!bookmark_bar_view_->IsDetachedStyle()) { + if (extension_shelf_->IsOnTop()) { + if (!bookmark_bar_view_->IsDetached()) { int extension_shelf_width = extension_shelf_->GetPreferredSize().width(); int bookmark_bar_given_width = width() - extension_shelf_width; @@ -1949,7 +1756,7 @@ int BrowserView::LayoutTopBar(int top) { bookmark_bar_height); x += extension_shelf_width; } else { - // TODO (sidchat): For detached style bookmark bar, set the extensions + // TODO(sidchat): For detached style bookmark bar, set the extensions // shelf in a better position. Issue = 20741. extension_shelf_->SetVisible(false); } @@ -1978,7 +1785,7 @@ int BrowserView::LayoutExtensionAndDownloadShelves() { // to look like it's part of the page. int bottom = height(); if (extension_shelf_) { - if (extension_shelf_->IsDetachedStyle()) { + if (extension_shelf_->IsDetached()) { bottom = LayoutDownloadShelf(bottom); return LayoutExtensionShelf(bottom); } @@ -2017,7 +1824,7 @@ void BrowserView::LayoutStatusBubble(int top) { } int BrowserView::LayoutExtensionShelf(int bottom) { - if (ShowExtensionsOnTop()) + if (!extension_shelf_ || extension_shelf_->IsOnTop()) return bottom; if (extension_shelf_) { @@ -2041,7 +1848,8 @@ bool BrowserView::MaybeShowBookmarkBar(TabContents* contents) { bookmark_bar_view_.reset(new BookmarkBarView(contents->profile(), browser_.get())); bookmark_bar_view_->SetParentOwned(false); - bookmark_bar_view_->set_background(new BookmarkExtensionBackground(this)); + bookmark_bar_view_->set_background( + new BookmarkExtensionBackground(this, bookmark_bar_view_.get())); } else { bookmark_bar_view_->SetProfile(contents->profile()); } @@ -2327,11 +2135,6 @@ void BrowserView::InitHangMonitor() { #endif } -bool BrowserView::ShowExtensionsOnTop() { - return extension_shelf_ && CommandLine::ForCurrentProcess()->HasSwitch( - switches::kShowExtensionsOnTop); -} - // static void BrowserView::InitClass() { static bool initialized = false; diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index 2d06f98..89cf05a 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -405,9 +405,6 @@ class BrowserView : public BrowserWindow, // Initialize the hung plugin detector. void InitHangMonitor(); - // Returns true if extensions and bookmarks are positioned next to each other. - bool ShowExtensionsOnTop(); - // Initialize class statics. static void InitClass(); diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 9f36ea0..a2bdf0cf 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1963,6 +1963,8 @@ 'browser/views/constrained_window_win.h', 'browser/views/confirm_message_box_dialog.cc', 'browser/views/confirm_message_box_dialog.h', + 'browser/views/detachable_toolbar_view.cc', + 'browser/views/detachable_toolbar_view.h', 'browser/views/dialog_stubs_gtk.cc', 'browser/views/dom_view.cc', 'browser/views/dom_view.h', diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index a2b99b5..806c0e5 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -311,9 +311,10 @@ IPC_BEGIN_MESSAGES(View) // Request for the renderer to evaluate an xpath to a frame and insert css // into that frame's document. See ViewMsg_ScriptEvalRequest for details on // allowed xpath expressions. - IPC_MESSAGE_ROUTED2(ViewMsg_CSSInsertRequest, + IPC_MESSAGE_ROUTED3(ViewMsg_CSSInsertRequest, std::wstring, /* frame_xpath */ - std::string /* css string */) + std::string, /* css string */ + std::string /* element id */) // Log a message to the console of the target frame IPC_MESSAGE_ROUTED3(ViewMsg_AddMessageToConsole, diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index f339309..b8ee661 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2734,12 +2734,13 @@ void RenderView::EvaluateScript(const std::wstring& frame_xpath, } void RenderView::InsertCSS(const std::wstring& frame_xpath, - const std::string& css) { + const std::string& css, + const std::string& id) { WebFrame* web_frame = GetChildFrame(frame_xpath); if (!web_frame) return; - web_frame->insertStyleText(WebString::fromUTF8(css)); + web_frame->insertStyleText(WebString::fromUTF8(css), WebString::fromUTF8(id)); } void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath, @@ -2748,8 +2749,9 @@ void RenderView::OnScriptEvalRequest(const std::wstring& frame_xpath, } void RenderView::OnCSSInsertRequest(const std::wstring& frame_xpath, - const std::string& css) { - InsertCSS(frame_xpath, css); + const std::string& css, + const std::string& id) { + InsertCSS(frame_xpath, css, id); // Notify RenderViewHost that css has been inserted into the frame. Send(new ViewHostMsg_OnCSSInserted(routing_id_)); diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 5836b52..2fe5201 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -405,9 +405,12 @@ class RenderView : public RenderWidget, void EvaluateScript(const std::wstring& frame_xpath, const std::wstring& jscript); - // Inserts a string of CSS in a particular frame. + // Inserts a string of CSS in a particular frame. |id| can be specified to + // give the CSS style element an id, and (if specified) will replace the + // element with the same id. void InsertCSS(const std::wstring& frame_xpath, - const std::string& css); + const std::string& css, + const std::string& id); int delay_seconds_for_form_state_sync() const { return delay_seconds_for_form_state_sync_; @@ -590,7 +593,8 @@ class RenderView : public RenderWidget, void OnScriptEvalRequest(const std::wstring& frame_xpath, const std::wstring& jscript); void OnCSSInsertRequest(const std::wstring& frame_xpath, - const std::string& css); + const std::string& css, + const std::string& id); void OnAddMessageToConsole(const string16& frame_xpath, const string16& message, const WebKit::WebConsoleMessage::Level&); diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc index 2ebd68f..7f7ad31 100644 --- a/chrome/renderer/user_script_slave.cc +++ b/chrome/renderer/user_script_slave.cc @@ -130,7 +130,7 @@ bool UserScriptSlave::InjectScripts(WebFrame* frame, for (size_t j = 0; j < script->css_scripts().size(); ++j) { UserScript::File& file = script->css_scripts()[j]; frame->insertStyleText( - WebString::fromUTF8(file.GetContent().as_string())); + WebString::fromUTF8(file.GetContent().as_string()), WebString()); } } if (script->run_location() == location) { |