diff options
author | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 20:16:45 +0000 |
---|---|---|
committer | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-07-13 20:16:45 +0000 |
commit | db47440e2fa833d5066d03fe938d8a7ca02458ef (patch) | |
tree | 5f40c48bb5eba7c5c2348747861827fbc4c72e01 /chrome/browser/ui/cocoa | |
parent | ca47d1193b54bcd6bc5705d6b81ae8fb580483d3 (diff) | |
download | chromium_src-db47440e2fa833d5066d03fe938d8a7ca02458ef.zip chromium_src-db47440e2fa833d5066d03fe938d8a7ca02458ef.tar.gz chromium_src-db47440e2fa833d5066d03fe938d8a7ca02458ef.tar.bz2 |
[WebIntents, OSX] Empty picker dialog.
Special case dialog if there are no installed services, and no suggested extensions.
R=rsesek@chromium.org
TBR=jhawkins@chromium.org
BUG=129005
TEST=bring up intent picker without any intents installed, and none in CWS. (Easier in Chromium, since CWS suggestions are disabled there)
Review URL: https://chromiumcodereview.appspot.com/10696184
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146640 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/cocoa')
5 files changed, 118 insertions, 13 deletions
diff --git a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.h b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.h index e872daf..780f3d9 100644 --- a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.h +++ b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.h @@ -48,6 +48,7 @@ class WebIntentPickerCocoa : public WebIntentPicker, virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE; virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE; virtual void OnInlineDispositionAutoResize(const gfx::Size& size) OVERRIDE; + virtual void OnPendingAsyncCompleted() OVERRIDE; // WebIntentPickerModelObserver implementation. virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE; diff --git a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm index 25a69ad..9e09fa5 100644 --- a/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm +++ b/chrome/browser/ui/cocoa/web_intent_picker_cocoa.mm @@ -222,6 +222,11 @@ void WebIntentPickerCocoa::OnInlineDispositionAutoResize( [sheet_controller_ setInlineDispositionFrameSize:inline_content_size]; } +void WebIntentPickerCocoa::OnPendingAsyncCompleted() { + DCHECK(sheet_controller_); + [sheet_controller_ pendingAsyncCompleted]; +} + void WebIntentPickerCocoa::OnExtensionLinkClicked(const std::string& id) { DCHECK(delegate_); delegate_->OnExtensionLinkClicked(id); diff --git a/chrome/browser/ui/cocoa/web_intent_sheet_controller.h b/chrome/browser/ui/cocoa/web_intent_sheet_controller.h index b7d2eea..a9bd1fb 100644 --- a/chrome/browser/ui/cocoa/web_intent_sheet_controller.h +++ b/chrome/browser/ui/cocoa/web_intent_sheet_controller.h @@ -29,6 +29,9 @@ class WebIntentPickerModel; // The intent picker data to be rendered. Weak reference. WebIntentPickerModel* model_; + // Indicator that we have neither suggested nor installed services. + BOOL isEmpty_; + scoped_nsobject<NSTextField> actionTextField_; scoped_nsobject<SuggestionView> suggestionView_; scoped_nsobject<NSButton> closeButton_; @@ -62,6 +65,9 @@ class WebIntentPickerModel; // Close the current sheet (and by extension, the constrained dialog). - (void)closeSheet; +// List of extensions/suggestions has been retrieved. +- (void)pendingAsyncCompleted; + // Notification handler - called when sheet has been closed. - (void)sheetDidEnd:(NSWindow*)sheet returnCode:(int)returnCode diff --git a/chrome/browser/ui/cocoa/web_intent_sheet_controller.mm b/chrome/browser/ui/cocoa/web_intent_sheet_controller.mm index cbfc6e8b..b52e9f0 100644 --- a/chrome/browser/ui/cocoa/web_intent_sheet_controller.mm +++ b/chrome/browser/ui/cocoa/web_intent_sheet_controller.mm @@ -467,7 +467,6 @@ NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:YES]); - if ((self = [super initWithWindow:window.get()])) { picker_ = picker; if (picker) @@ -763,23 +762,72 @@ NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { return NSHeight([button frame]); } +- (NSView*)createEmptyView { + NSMutableArray* subviews = [NSMutableArray array]; + + NSRect titleFrame = NSMakeRect(kFramePadding, kFramePadding, + kTextWidth, 1); + scoped_nsobject<NSTextField> title( + [[NSTextField alloc] initWithFrame:titleFrame]); + ConfigureTextFieldAsLabel(title); + [title setFont:[NSFont systemFontOfSize:kHeaderFontSize]]; + [title setStringValue: + l10n_util::GetNSStringWithFixup(IDS_INTENT_PICKER_NO_SERVICES_TITLE)]; + titleFrame.size.height += + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:title]; + + NSRect bodyFrame = titleFrame; + bodyFrame.origin.y += NSHeight(titleFrame) + kFramePadding; + + scoped_nsobject<NSTextField> body( + [[NSTextField alloc] initWithFrame:bodyFrame]); + ConfigureTextFieldAsLabel(body); + [body setStringValue: + l10n_util::GetNSStringWithFixup(IDS_INTENT_PICKER_NO_SERVICES)]; + bodyFrame.size.height += + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:body]; + NSRect viewFrame = NSMakeRect( + 0, + kFramePadding, + std::max(NSWidth(bodyFrame), NSWidth(titleFrame)) + 2 * kFramePadding, + NSHeight(titleFrame) + NSHeight(bodyFrame) + kVerticalSpacing); + + titleFrame.origin.y = NSHeight(viewFrame) - NSHeight(titleFrame); + bodyFrame.origin.y = 0; + + [title setFrame:titleFrame]; + [body setFrame: bodyFrame]; + + [subviews addObject:title]; + [subviews addObject:body]; + + NSView* view = [[NSView alloc] initWithFrame:viewFrame]; + [view setAutoresizingMask:NSViewMinYMargin ]; + [view setSubviews:subviews]; + + return view; +} + - (void)performLayoutWithModel:(WebIntentPickerModel*)model { model_ = model; + // |offset| is the Y position that should be drawn at next. CGFloat offset = kFramePadding; // Keep the new subviews in an array that gets replaced at the end. NSMutableArray* subviews = [NSMutableArray array]; - if (contents_) { + if (isEmpty_) { + scoped_nsobject<NSView> emptyView([self createEmptyView]); + [subviews addObject:emptyView]; + offset += NSHeight([emptyView frame]); + } else if (contents_) { offset += [self addAnotherServiceLinkToSubviews:subviews atOffset:offset]; offset += kFramePadding; offset += [self addInlineHtmlToSubviews:subviews atOffset:offset]; - [self addCloseButtonToSubviews:subviews]; } else { offset += [self addHeaderToSubviews:subviews atOffset:offset]; - [self addCloseButtonToSubviews:subviews]; offset += kVerticalSpacing; @@ -807,6 +855,7 @@ NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { } offset += [self addCwsButtonToSubviews:subviews atOffset:offset]; } + [self addCloseButtonToSubviews:subviews]; // Add the bottom padding. offset += kVerticalSpacing; @@ -857,4 +906,15 @@ NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { - (void)closeSheet { [NSApp endSheet:[self window]]; } + +- (void)pendingAsyncCompleted { + // Requests to both the WebIntentService and the Chrome Web Store have + // completed. If there are any services, installed or suggested, there's + // nothing to do. + DCHECK(model_); + isEmpty_ = !model_->GetInstalledServiceCount() && + !model_->GetSuggestedExtensionCount(); + [self performLayoutWithModel:model_]; +} + @end // WebIntentPickerSheetController diff --git a/chrome/browser/ui/cocoa/web_intent_sheet_controller_unittest.mm b/chrome/browser/ui/cocoa/web_intent_sheet_controller_unittest.mm index 4b3969e..bee8441 100644 --- a/chrome/browser/ui/cocoa/web_intent_sheet_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/web_intent_sheet_controller_unittest.mm @@ -45,27 +45,29 @@ class WebIntentPickerSheetControllerTest : public CocoaTest { // |row_count| buttons, and a CWS link. ASSERT_EQ(3U + row_count, [views count]); + const NSUInteger kFirstButton = 1; ASSERT_TRUE([[views objectAtIndex:0] isKindOfClass:[NSTextField class]]); - ASSERT_TRUE([[views objectAtIndex:1] isKindOfClass: - [HoverCloseButton class]]); for(NSUInteger i = 0; i < row_count; ++i) { - ASSERT_TRUE([[views objectAtIndex:2 + i] isKindOfClass: + ASSERT_TRUE([[views objectAtIndex:kFirstButton + i] isKindOfClass: [NSButton class]]); } + ASSERT_TRUE([[views lastObject] isKindOfClass: + [HoverCloseButton class]]); // Verify the close button - NSButton* close_button = static_cast<NSButton*>([views objectAtIndex:1]); + NSButton* close_button = static_cast<NSButton*>([views lastObject]); CheckButton(close_button, @selector(cancelOperation:)); // Verify the Chrome Web Store button. - NSButton* button = static_cast<NSButton*>([views lastObject]); + NSButton* button = static_cast<NSButton*>( + [views objectAtIndex:kFirstButton + row_count]); ASSERT_TRUE([button isKindOfClass:[NSButton class]]); EXPECT_TRUE([[button cell] isKindOfClass:[HyperlinkButtonCell class]]); CheckButton(button, @selector(showChromeWebStore:)); // Verify buttons pointing to services. for(NSUInteger i = 0; i < row_count; ++i) { - NSButton* button = [views objectAtIndex:2 + i]; + NSButton* button = [views objectAtIndex:kFirstButton + i]; CheckServiceButton(button, i); } } @@ -117,10 +119,10 @@ TEST_F(WebIntentPickerSheetControllerTest, SuggestionView) { NSArray* flip_views = [[window_ contentView] subviews]; NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; - // 3rd object should be the suggestion view. + // 2nd object should be the suggestion view, 3rd one is close button. ASSERT_TRUE([main_views count] > 2); - ASSERT_TRUE([[main_views objectAtIndex:2] isKindOfClass:[NSView class]]); - NSView* suggest_view = [main_views objectAtIndex:2]; + ASSERT_TRUE([[main_views objectAtIndex:1] isKindOfClass:[NSView class]]); + NSView* suggest_view = [main_views objectAtIndex:1]; // There are two subviews - label & suggested items. ASSERT_EQ(2U, [[suggest_view subviews] count]); @@ -149,3 +151,34 @@ TEST_F(WebIntentPickerSheetControllerTest, SuggestionView) { ASSERT_TRUE([[[item_view subviews] objectAtIndex:4] isKindOfClass:[NSProgressIndicator class]]); } + +TEST_F(WebIntentPickerSheetControllerTest, EmptyView) { + WebIntentPickerModel model; + [controller_ performLayoutWithModel:&model]; + [controller_ pendingAsyncCompleted]; + + ASSERT_TRUE(window_); + + // Get subviews. + NSArray* flip_views = [[window_ contentView] subviews]; + ASSERT_TRUE(flip_views); + + NSArray* main_views = [[flip_views objectAtIndex:0] subviews]; + ASSERT_TRUE(main_views); + + // Should have two subviews - the empty picker dialog and the close button. + ASSERT_EQ(2U, [main_views count]); + + // Extract empty picker dialog. + ASSERT_TRUE([[main_views objectAtIndex:0] isKindOfClass:[NSView class]]); + NSView* empty_dialog = [main_views objectAtIndex:0]; + + // Empty picker dialog has two elements, title and body. + ASSERT_EQ(2U, [[empty_dialog subviews] count]); + + // Both title and body are NSTextFields. + ASSERT_TRUE([[[empty_dialog subviews] objectAtIndex:0] + isKindOfClass:[NSTextField class]]); + ASSERT_TRUE([[[empty_dialog subviews] objectAtIndex:1] + isKindOfClass:[NSTextField class]]); +} |