summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
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 /chrome/browser/cocoa
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
Diffstat (limited to 'chrome/browser/cocoa')
-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
4 files changed, 233 insertions, 0 deletions
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