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 /chrome/browser/cocoa | |
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
Diffstat (limited to 'chrome/browser/cocoa')
-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 |
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 |