summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-15 15:55:33 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-15 15:55:33 +0000
commita99f5b8a912687a14a2cf0a5aede7ffc2eef8c8a (patch)
treefcb25e0363ba46c02e8ee1a2aa474b269c67f823
parent9973ceb80aa79dc730b9f39e9666a7ad28130d39 (diff)
downloadchromium_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.cc12
-rw-r--r--chrome/browser/browser_window.h3
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h1
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm5
-rw-r--r--chrome/browser/cocoa/theme_install_bubble_view.h56
-rw-r--r--chrome/browser/cocoa/theme_install_bubble_view.mm171
-rwxr-xr-xchrome/browser/gtk/browser_window_gtk.cc5
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h1
-rw-r--r--chrome/browser/views/frame/browser_view.cc16
-rw-r--r--chrome/browser/views/frame/browser_view.h1
-rw-r--r--chrome/browser/views/theme_install_bubble_view.cc18
-rw-r--r--chrome/browser/views/theme_install_bubble_view.h30
-rwxr-xr-xchrome/chrome.gyp2
-rw-r--r--chrome/test/test_browser_window.h1
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) {}