diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-15 15:55:33 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-15 15:55:33 +0000 |
commit | a99f5b8a912687a14a2cf0a5aede7ffc2eef8c8a (patch) | |
tree | fcb25e0363ba46c02e8ee1a2aa474b269c67f823 | |
parent | 9973ceb80aa79dc730b9f39e9666a7ad28130d39 (diff) | |
download | chromium_src-a99f5b8a912687a14a2cf0a5aede7ffc2eef8c8a.zip chromium_src-a99f5b8a912687a14a2cf0a5aede7ffc2eef8c8a.tar.gz chromium_src-a99f5b8a912687a14a2cf0a5aede7ffc2eef8c8a.tar.bz2 |
Show "Loading" bubble while loading a theme.
BUG=http://crbug.com/22219
TEST=load a theme, see "Loading..."
Review URL: http://codereview.chromium.org/267031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29121 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/browser.cc | 12 | ||||
-rw-r--r-- | chrome/browser/browser_window.h | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.h | 1 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.mm | 5 | ||||
-rw-r--r-- | chrome/browser/cocoa/theme_install_bubble_view.h | 56 | ||||
-rw-r--r-- | chrome/browser/cocoa/theme_install_bubble_view.mm | 171 | ||||
-rwxr-xr-x | chrome/browser/gtk/browser_window_gtk.cc | 5 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.cc | 16 | ||||
-rw-r--r-- | chrome/browser/views/frame/browser_view.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/theme_install_bubble_view.cc | 18 | ||||
-rw-r--r-- | chrome/browser/views/theme_install_bubble_view.h | 30 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 2 | ||||
-rw-r--r-- | chrome/test/test_browser_window.h | 1 |
14 files changed, 292 insertions, 30 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 3dcd0fb..f0c6624 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -86,7 +86,6 @@ #include "chrome/browser/user_data_manager.h" #include "chrome/browser/view_ids.h" #include "chrome/browser/views/location_bar_view.h" -#include "chrome/browser/views/theme_install_bubble_view.h" #include "chrome/common/child_process_host.h" #endif // OS_WIN @@ -2203,18 +2202,9 @@ void Browser::Observe(NotificationType type, break; case NotificationType::EXTENSION_READY_FOR_INSTALL: { -#if defined(OS_WIN) if (BrowserList::GetLastActive() != this) break; - TabContents* tab_contents = - BrowserList::GetLastActive()->GetSelectedTabContents(); - if (!tab_contents) - break; - if (platform_util::IsVisible(tab_contents->GetNativeView())) - ThemeInstallBubbleView::Show(tab_contents); -#else - NOTIMPLEMENTED(); -#endif + window()->ShowThemeInstallBubble(); break; } diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index 4e47efb..a83fbbd 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -208,6 +208,9 @@ class BrowserWindow { // Shows a dialog to the user that the history is too new. virtual void ShowHistoryTooNewDialog() = 0; + // Show the bubble that indicates to the user that a theme is being installed. + virtual void ShowThemeInstallBubble() = 0; + // Shows the confirmation dialog box warning that the browser is closing with // in-progress downloads. // This method should call Browser::InProgressDownloadResponse once the user diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 73e3bff..1b7cec2 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -76,6 +76,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void ShowNewProfileDialog(); virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); virtual void ShowHistoryTooNewDialog(); + virtual void ShowThemeInstallBubble(); virtual void ConfirmBrowserCloseWithPendingDownloads(); virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window); diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 6ab8128..66711aa 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -14,6 +14,7 @@ #include "chrome/browser/cocoa/page_info_window_mac.h" #include "chrome/browser/cocoa/status_bubble_mac.h" #include "chrome/browser/cocoa/task_manager_mac.h" +#import "chrome/browser/cocoa/theme_install_bubble_view.h" #include "chrome/browser/browser.h" #include "chrome/browser/download/download_shelf.h" #include "chrome/common/notification_service.h" @@ -278,6 +279,10 @@ void BrowserWindowCocoa::ShowHistoryTooNewDialog() { NOTIMPLEMENTED(); } +void BrowserWindowCocoa::ShowThemeInstallBubble() { + ThemeInstallBubbleView::Show(window_); +} + // We allow closing the window here since the real quit decision on Mac is made // in [AppController quit:]. void BrowserWindowCocoa::ConfirmBrowserCloseWithPendingDownloads() { diff --git a/chrome/browser/cocoa/theme_install_bubble_view.h b/chrome/browser/cocoa/theme_install_bubble_view.h new file mode 100644 index 0000000..858e659 --- /dev/null +++ b/chrome/browser/cocoa/theme_install_bubble_view.h @@ -0,0 +1,56 @@ +// 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/common/notification_registrar.h" +#include "chrome/common/notification_service.h" + +@class NSWindow; +@class ThemeInstallBubbleViewCocoa; + +// ThemeInstallBubbleView is a view that provides a "Loading..." bubble in the +// center of a browser window for use when an extension or theme is loaded. +// (The Browser class only calls it to install itself into the currently active +// browser window.) If an extension is being applied, the bubble goes away +// immediately. If a theme is being applied, it disappears when the theme has +// been loaded. The purpose of this bubble is to warn the user that the browser +// may be unresponsive while the theme is being installed. +// +// Edge case: note that if one installs a theme in one window and then switches +// rapidly to another window to install a theme there as well (in the short time +// between install begin and theme caching seizing the UI thread), the loading +// bubble will only appear over the first window, as there is only ever one +// instance of the bubble. +class ThemeInstallBubbleView : public NotificationObserver { + public: + ~ThemeInstallBubbleView(); + + // NotificationObserver + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Show the loading bubble. + static void Show(NSWindow* window); + + private: + explicit ThemeInstallBubbleView(NSWindow* window); + + // The one copy of the loading bubble. + static ThemeInstallBubbleView* view_; + + // A scoped container for notification registries. + NotificationRegistrar registrar_; + + // Shut down the popup and remove our notifications. + void Close(); + + // The actual Cocoa view implementing the bubble. + ThemeInstallBubbleViewCocoa* cocoa_view_; + + // Multiple loads can be started at once. Only show one bubble, and keep + // track of number of loads happening. Close bubble when num_loads < 1. + int num_loads_extant_; + + DISALLOW_COPY_AND_ASSIGN(ThemeInstallBubbleView); +}; diff --git a/chrome/browser/cocoa/theme_install_bubble_view.mm b/chrome/browser/cocoa/theme_install_bubble_view.mm new file mode 100644 index 0000000..f3c2c25 --- /dev/null +++ b/chrome/browser/cocoa/theme_install_bubble_view.mm @@ -0,0 +1,171 @@ +// 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. + +#import <Cocoa/Cocoa.h> + +#import "chrome/browser/cocoa/theme_install_bubble_view.h" + +#include "app/l10n_util_mac.h" +#include "base/scoped_nsobject.h" +#include "grit/generated_resources.h" + +namespace { + +// The alpha of the bubble. +static const float kBubbleAlpha = 0.75; + +// The roundedness of the edges of our bubble. +static const int kBubbleCornerRadius = 4; + +// Padding around text in popup box. +static const int kTextHorizPadding = 90; +static const int kTextVertPadding = 45; + +// Point size of the text in the box. +static const int kLoadingTextSize = 24; + +} + +// static +ThemeInstallBubbleView* ThemeInstallBubbleView::view_ = NULL; + +// The Cocoa view to draw a gray rounded rect with "Loading..." in it. +@interface ThemeInstallBubbleViewCocoa : NSView { + @private + scoped_nsobject<NSAttributedString> message_; + + NSRect grayRect_; + NSRect textRect_; +} + +- (id)init; + +// The size of the gray rect that will be drawn. +- (NSSize)preferredSize; +// Forces size calculations of where everything will be drawn. +- (void)layout; + +@end + +ThemeInstallBubbleView::ThemeInstallBubbleView(NSWindow* window) + : cocoa_view_([[ThemeInstallBubbleViewCocoa alloc] init]), + num_loads_extant_(1) { + DCHECK(window); + + NSView* parent_view = [window contentView]; + NSRect parent_bounds = [parent_view bounds]; + if (parent_bounds.size.height < [cocoa_view_ preferredSize].height) + Close(); + + // Close when theme has been installed. + registrar_.Add( + this, + NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + + // Close when we are installing an extension, not a theme. + registrar_.Add( + this, + NotificationType::NO_THEME_DETECTED, + NotificationService::AllSources()); + registrar_.Add( + this, + NotificationType::EXTENSION_INSTALLED, + NotificationService::AllSources()); + + // Add the view. + [cocoa_view_ setFrame:parent_bounds]; + [cocoa_view_ setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [parent_view addSubview:cocoa_view_ + positioned:NSWindowAbove + relativeTo:nil]; + [cocoa_view_ layout]; +} + +ThemeInstallBubbleView::~ThemeInstallBubbleView() { + // Need to delete self; the real work happens in Close(). +} + +void ThemeInstallBubbleView::Close() { + --num_loads_extant_; + if (num_loads_extant_ < 1) { + registrar_.RemoveAll(); + if (cocoa_view_ && [cocoa_view_ superview]) { + [cocoa_view_ removeFromSuperview]; + [cocoa_view_ release]; + } + view_ = NULL; + delete this; + // this is deleted; nothing more! + } +} + +void ThemeInstallBubbleView::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + Close(); +} + +// static +void ThemeInstallBubbleView::Show(NSWindow* window) { + if (view_) + ++view_->num_loads_extant_; + else + view_ = new ThemeInstallBubbleView(window); +} + +@implementation ThemeInstallBubbleViewCocoa + +- (id)init { + self = [super initWithFrame:NSZeroRect]; + if (self) { + // Need our own copy of the "Loading..." string: http://crbug.com/24177 + NSString* loadingString = + l10n_util::GetNSStringWithFixup(IDS_TAB_LOADING_TITLE); + NSFont* loadingFont = [NSFont systemFontOfSize:kLoadingTextSize]; + NSColor* textColor = [NSColor whiteColor]; + NSDictionary* loadingAttrs = [NSDictionary dictionaryWithObjectsAndKeys: + loadingFont, NSFontAttributeName, + textColor, NSForegroundColorAttributeName, + nil]; + message_.reset([[NSAttributedString alloc] initWithString:loadingString + attributes:loadingAttrs]); + + // TODO(avi): find a white-on-black spinner + } + return self; +} + +- (NSSize)preferredSize { + NSSize size = [message_.get() size]; + size.width += kTextHorizPadding; + size.height += kTextVertPadding; + return size; +} + +- (void)layout { + NSRect bounds = [self bounds]; + + grayRect_.size = [self preferredSize]; + grayRect_.origin.x = (bounds.size.width - grayRect_.size.width) / 2; + grayRect_.origin.y = bounds.size.height / 2; + + textRect_.size = [message_.get() size]; + textRect_.origin.x = (bounds.size.width - [message_.get() size].width) / 2; + textRect_.origin.y = (bounds.size.height + kTextVertPadding) / 2; +} + +- (void)drawRect:(NSRect)dirtyRect { + [[NSColor clearColor] set]; + NSRectFillUsingOperation([self bounds], NSCompositeSourceOver); + + [[[NSColor blackColor] colorWithAlphaComponent:kBubbleAlpha] set]; + [[NSBezierPath bezierPathWithRoundedRect:grayRect_ + xRadius:kBubbleCornerRadius + yRadius:kBubbleCornerRadius] fill]; + + [message_.get() drawInRect:textRect_]; +} + +@end diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index fc9b887..1b45602 100755 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -1129,6 +1129,11 @@ void BrowserWindowGtk::ShowHistoryTooNewDialog() { gtk_widget_destroy(dialog); } +void BrowserWindowGtk::ShowThemeInstallBubble() { + // http://crbug.com/24360 + NOTIMPLEMENTED(); +} + void BrowserWindowGtk::ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window) { NOTIMPLEMENTED(); diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 549a84a..00ed567 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -109,6 +109,7 @@ class BrowserWindowGtk : public BrowserWindow, virtual void ShowNewProfileDialog(); virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); virtual void ShowHistoryTooNewDialog(); + virtual void ShowThemeInstallBubble(); virtual void ConfirmBrowserCloseWithPendingDownloads(); virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window); diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 48f107a..f75af67 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -76,6 +76,7 @@ #if defined(OS_WIN) #include "app/win_util.h" #include "chrome/browser/jumplist.h" +#include "chrome/browser/views/theme_install_bubble_view.h" #include "views/controls/scrollbar/native_scroll_bar.h" #elif defined(OS_LINUX) #include "chrome/browser/views/accelerator_table_gtk.h" @@ -1105,6 +1106,21 @@ void BrowserView::ShowHistoryTooNewDialog() { #endif } +void BrowserView::ShowThemeInstallBubble() { +#if defined(OS_WIN) + TabContents* tab_contents = browser_->GetSelectedTabContents(); + if (!tab_contents) + return; + ThemeInstallBubbleView::Show(tab_contents); +#elif defined(OS_LINUX) + // Alas, the Views version of ThemeInstallBubbleView is Windows Views only. + // http://crbug.com/24360 + NOTIMPLEMENTED(); +#else + NOTIMPLEMENTED(); +#endif +} + void BrowserView::ConfirmBrowserCloseWithPendingDownloads() { DownloadInProgressConfirmDialogDelegate* delegate = new DownloadInProgressConfirmDialogDelegate(browser_.get()); diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index ff3291b..6e7400e 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -254,6 +254,7 @@ class BrowserView : public BrowserWindow, virtual void ShowNewProfileDialog(); virtual void ShowRepostFormWarningDialog(TabContents* tab_contents); virtual void ShowHistoryTooNewDialog(); + virtual void ShowThemeInstallBubble(); virtual void ConfirmBrowserCloseWithPendingDownloads(); virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window); diff --git a/chrome/browser/views/theme_install_bubble_view.cc b/chrome/browser/views/theme_install_bubble_view.cc index 7470280..e305cd0 100644 --- a/chrome/browser/views/theme_install_bubble_view.cc +++ b/chrome/browser/views/theme_install_bubble_view.cc @@ -8,13 +8,18 @@ #include "grit/generated_resources.h" namespace { - // Padding around text in popup box. - static const int kTextHorizPadding = 90; - static const int kTextVertPadding = 45; - // Multiple loads can be started at once. Only show one bubble, and keep - // track of number of loads happening. Close bubble when num_loads < 1. - static int num_loads_extant_ = 0; +// The roundedness of the edges of our bubble. +static const int kBubbleCornerRadius = 4; + +// Padding around text in popup box. +static const int kTextHorizPadding = 90; +static const int kTextVertPadding = 45; + +// Multiple loads can be started at once. Only show one bubble, and keep +// track of number of loads happening. Close bubble when num_loads < 1. +static int num_loads_extant_ = 0; + } ThemeInstallBubbleView::ThemeInstallBubbleView(TabContents* tab_contents) @@ -22,6 +27,7 @@ ThemeInstallBubbleView::ThemeInstallBubbleView(TabContents* tab_contents) if (!tab_contents) Close(); + // Need our own copy of the "Loading..." string: http://crbug.com/24177 text_ = l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE); ResourceBundle& rb = ResourceBundle::GetSharedInstance(); gfx::Font font(rb.GetFont(ResourceBundle::LargeFont)); diff --git a/chrome/browser/views/theme_install_bubble_view.h b/chrome/browser/views/theme_install_bubble_view.h index 3ac742f..694862e 100644 --- a/chrome/browser/views/theme_install_bubble_view.h +++ b/chrome/browser/views/theme_install_bubble_view.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef CHROME_BROWSER_VIEWS_THEME_INSTALL_BUBBLE_VIEW_H_ +#define CHROME_BROWSER_VIEWS_THEME_INSTALL_BUBBLE_VIEW_H_ + #include "app/gfx/canvas.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/notification_registrar.h" @@ -9,22 +12,22 @@ #include "views/controls/label.h" #include "views/widget/widget_win.h" -// ThemeInstallBubbleView launches a "loading..." bubble in the center of the -// currently active browser window when an extension or theme is loaded. If -// an extension is being applied, the bubble goes away immediately. If a theme -// is being applied, it disappears when the theme has been loaded. The purpose -// of this bubble is to warn the user that the browser may be unresponsive -// while the theme is being installed. +// ThemeInstallBubbleView is a view that provides a "Loading..." bubble in the +// center of a browser window for use when an extension or theme is loaded. +// (The Browser class only calls it to install itself into the currently active +// browser window.) If an extension is being applied, the bubble goes away +// immediately. If a theme is being applied, it disappears when the theme has +// been loaded. The purpose of this bubble is to warn the user that the browser +// may be unresponsive while the theme is being installed. // // Edge case: note that if one installs a theme in one window and then switches -// rapidly to another window to install a theme there as well (in the short -// time between install begin and theme caching seizing the UI thread), the -// loading bubble will only appear over the first window. +// rapidly to another window to install a theme there as well (in the short time +// between install begin and theme caching seizing the UI thread), the loading +// bubble will only appear over the first window, as there is only ever one +// instance of the bubble. class ThemeInstallBubbleView : public NotificationObserver, public views::Label { public: - explicit ThemeInstallBubbleView(TabContents* tab_contents); - ~ThemeInstallBubbleView(); // NotificationObserver @@ -36,8 +39,7 @@ class ThemeInstallBubbleView : public NotificationObserver, static void Show(TabContents* tab_contents); private: - // The roundedness of the edges of our bubble. - static const int kBubbleCornerRadius = 4; + explicit ThemeInstallBubbleView(TabContents* tab_contents); // The content area at the start of the animation. gfx::Rect tab_contents_bounds_; @@ -65,3 +67,5 @@ class ThemeInstallBubbleView : public NotificationObserver, DISALLOW_COPY_AND_ASSIGN(ThemeInstallBubbleView); }; +#endif // CHROME_BROWSER_VIEWS_THEME_INSTALL_BUBBLE_VIEW_H_ + diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index fa43d42..4c36aa5 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1168,6 +1168,8 @@ 'browser/cocoa/tab_window_controller.mm', 'browser/cocoa/task_manager_mac.h', 'browser/cocoa/task_manager_mac.mm', + 'browser/cocoa/theme_install_bubble_view.h', + 'browser/cocoa/theme_install_bubble_view.mm', 'browser/cocoa/throbber_view.h', 'browser/cocoa/throbber_view.mm', 'browser/cocoa/toolbar_button_cell.h', diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index 0859089..8aa657d 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -75,6 +75,7 @@ class TestBrowserWindow : public BrowserWindow { virtual void ShowNewProfileDialog() {} virtual void ShowRepostFormWarningDialog(TabContents* tab_contents) {} virtual void ShowHistoryTooNewDialog() {} + virtual void ShowThemeInstallBubble() {} virtual void ConfirmBrowserCloseWithPendingDownloads() {} virtual void ShowHTMLDialog(HtmlDialogUIDelegate* delegate, gfx::NativeWindow parent_window) {} |