OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/web_intent_sheet_controller.h" | 5 #import "chrome/browser/ui/cocoa/web_intent_sheet_controller.h" |
6 | 6 |
7 #include "base/memory/scoped_nsobject.h" | 7 #include "base/memory/scoped_nsobject.h" |
8 #include "base/sys_string_conversions.h" | 8 #include "base/sys_string_conversions.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/ui/browser_list.h" | 10 #include "chrome/browser/ui/browser_list.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
50 // Square size of the close button. | 50 // Square size of the close button. |
51 const CGFloat kCloseButtonSize = 16; | 51 const CGFloat kCloseButtonSize = 16; |
52 | 52 |
53 // Font size for picker header. | 53 // Font size for picker header. |
54 const CGFloat kHeaderFontSize = 14.5; | 54 const CGFloat kHeaderFontSize = 14.5; |
55 | 55 |
56 // Width of the text fields. | 56 // Width of the text fields. |
57 const CGFloat kTextWidth = kWindowWidth - | 57 const CGFloat kTextWidth = kWindowWidth - |
58 (kFramePadding * 2 + kCloseButtonSize); | 58 (kFramePadding * 2 + kCloseButtonSize); |
59 | 59 |
60 } // namespace | 60 // Sets properties on the given |field| to act as title or description labels. |
61 void ConfigureTextFieldAsLabel(NSTextField* field) { | |
62 [field setEditable:NO]; | |
63 [field setSelectable:YES]; | |
64 [field setDrawsBackground:NO]; | |
65 [field setBezeled:NO]; | |
66 } | |
61 | 67 |
62 // Helper methods used for the creation of the picker sheet controls. | 68 NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { |
63 @implementation WebIntentPickerSheetController (helpers) | |
64 + (NSButton*)createHyperlinkButton:(NSString*)title withFrame:(NSRect)frame { | |
65 NSButton* button = [[NSButton alloc] initWithFrame:frame]; | 69 NSButton* button = [[NSButton alloc] initWithFrame:frame]; |
66 scoped_nsobject<HyperlinkButtonCell> cell( | 70 scoped_nsobject<HyperlinkButtonCell> cell( |
67 [[HyperlinkButtonCell alloc] initTextCell:title]); | 71 [[HyperlinkButtonCell alloc] initTextCell:title]); |
68 [cell setControlSize:NSSmallControlSize]; | 72 [cell setControlSize:NSSmallControlSize]; |
69 [button setCell:cell.get()]; | 73 [button setCell:cell.get()]; |
70 [button setButtonType:NSMomentaryPushInButton]; | 74 [button setButtonType:NSMomentaryPushInButton]; |
71 [button setBezelStyle:NSRegularSquareBezelStyle]; | 75 [button setBezelStyle:NSRegularSquareBezelStyle]; |
72 | 76 |
73 return button; | 77 return button; |
74 } | 78 } |
75 @end | 79 |
80 } // namespace | |
76 | 81 |
77 // This simple NSView subclass is used as the single subview of the page info | 82 // This simple NSView subclass is used as the single subview of the page info |
78 // bubble's window's contentView. Drawing is flipped so that layout of the | 83 // bubble's window's contentView. Drawing is flipped so that layout of the |
79 // sections is easier. Apple recommends flipping the coordinate origin when | 84 // sections is easier. Apple recommends flipping the coordinate origin when |
80 // doing a lot of text layout because it's more natural. | 85 // doing a lot of text layout because it's more natural. |
81 @interface WebIntentsContentView : NSView | 86 @interface WebIntentsContentView : NSView |
82 @end | 87 @end |
83 @implementation WebIntentsContentView | 88 @implementation WebIntentsContentView |
84 - (BOOL)isFlipped { | 89 - (BOOL)isFlipped { |
85 return YES; | 90 return YES; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 imageFrame.size = [icon size]; | 204 imageFrame.size = [icon size]; |
200 imageFrame.size.height = std::min(NSHeight(imageFrame), kMaxHeight); | 205 imageFrame.size.height = std::min(NSHeight(imageFrame), kMaxHeight); |
201 imageFrame.origin.y += (kMaxHeight - NSHeight(imageFrame)) / 2.0; | 206 imageFrame.origin.y += (kMaxHeight - NSHeight(imageFrame)) / 2.0; |
202 [iconView_ setFrame:imageFrame]; | 207 [iconView_ setFrame:imageFrame]; |
203 [subviews addObject:iconView_]; | 208 [subviews addObject:iconView_]; |
204 | 209 |
205 // Add the extension title. | 210 // Add the extension title. |
206 NSRect frame = NSMakeRect(kTitleX, 0, 0, 0); | 211 NSRect frame = NSMakeRect(kTitleX, 0, 0, 0); |
207 | 212 |
208 NSString* string = base::SysUTF16ToNSString(extension->title); | 213 NSString* string = base::SysUTF16ToNSString(extension->title); |
209 cwsButton_.reset( | 214 cwsButton_.reset(CreateHyperlinkButton(string, frame)); |
210 [WebIntentPickerSheetController createHyperlinkButton:string | |
211 withFrame:frame]); | |
212 [cwsButton_ setAlignment:NSLeftTextAlignment]; | 215 [cwsButton_ setAlignment:NSLeftTextAlignment]; |
213 [cwsButton_ setTarget:controller]; | 216 [cwsButton_ setTarget:controller]; |
214 [cwsButton_ setAction:@selector(openExtensionLink:)]; | 217 [cwsButton_ setAction:@selector(openExtensionLink:)]; |
215 [cwsButton_ setTag:index]; | 218 [cwsButton_ setTag:index]; |
216 [cwsButton_ sizeToFit]; | 219 [cwsButton_ sizeToFit]; |
217 | 220 |
218 frame = [cwsButton_ frame]; | 221 frame = [cwsButton_ frame]; |
219 frame.size.height = std::min([[cwsButton_ cell] cellSize].height, | 222 frame.size.height = std::min([[cwsButton_ cell] cellSize].height, |
220 kMaxHeight); | 223 kMaxHeight); |
221 frame.origin.y = (kMaxHeight - NSHeight(frame)) / 2.0; | 224 frame.origin.y = (kMaxHeight - NSHeight(frame)) / 2.0; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 [throbber_ stopAnimation:self]; | 322 [throbber_ stopAnimation:self]; |
320 [installButton_ setHidden:NO]; | 323 [installButton_ setHidden:NO]; |
321 } | 324 } |
322 | 325 |
323 @end | 326 @end |
324 | 327 |
325 @interface SuggestionView : NSView { | 328 @interface SuggestionView : NSView { |
326 @private | 329 @private |
327 // Used to forward button clicks. Weak reference. | 330 // Used to forward button clicks. Weak reference. |
328 WebIntentPickerSheetController* controller_; | 331 WebIntentPickerSheetController* controller_; |
332 scoped_nsobject<NSTextField> suggestionLabel_; | |
329 } | 333 } |
330 | 334 |
331 - (id)initWithModel:(WebIntentPickerModel*)model | 335 - (id)initWithModel:(WebIntentPickerModel*)model |
332 forController:(WebIntentPickerSheetController*)controller; | 336 forController:(WebIntentPickerSheetController*)controller; |
333 - (void)startThrobberForRow:(NSInteger)index; | 337 - (void)startThrobberForRow:(NSInteger)index; |
334 - (void)stopThrobber; | 338 - (void)stopThrobber; |
335 @end | 339 @end |
336 | 340 |
337 @implementation SuggestionView | 341 @implementation SuggestionView |
338 - (id)initWithModel:(WebIntentPickerModel*)model | 342 - (id)initWithModel:(WebIntentPickerModel*)model |
339 forController:(WebIntentPickerSheetController*)controller { | 343 forController:(WebIntentPickerSheetController*)controller { |
340 const CGFloat kYMargin = 16.0; | 344 const CGFloat kYMargin = 16.0; |
341 size_t count = model->GetSuggestedExtensionCount(); | 345 size_t count = model->GetSuggestedExtensionCount(); |
342 if (count == 0) | 346 if (count == 0) |
343 return nil; | 347 return nil; |
344 | 348 |
345 NSMutableArray* subviews = [NSMutableArray array]; | 349 NSMutableArray* subviews = [NSMutableArray array]; |
346 | 350 |
351 NSRect textFrame = NSMakeRect(0, 0, | |
352 kTextWidth, 1); | |
353 suggestionLabel_.reset([[NSTextField alloc] initWithFrame:textFrame]); | |
354 ConfigureTextFieldAsLabel(suggestionLabel_); | |
355 | |
347 CGFloat offset = kYMargin; | 356 CGFloat offset = kYMargin; |
348 for (size_t i = count; i > 0; --i) { | 357 for (size_t i = count; i > 0; --i) { |
349 const WebIntentPickerModel::SuggestedExtension& ext = | 358 const WebIntentPickerModel::SuggestedExtension& ext = |
350 model->GetSuggestedExtensionAt(i - 1); | 359 model->GetSuggestedExtensionAt(i - 1); |
351 scoped_nsobject<NSView> suggestView( | 360 scoped_nsobject<NSView> suggestView( |
352 [[SingleSuggestionView alloc] initWithExtension:&ext | 361 [[SingleSuggestionView alloc] initWithExtension:&ext |
353 withIndex:i-1 | 362 withIndex:i-1 |
354 forController:controller]); | 363 forController:controller]); |
355 offset += [self addStackedView:suggestView.get() | 364 offset += [self addStackedView:suggestView.get() |
356 toSubviews:subviews | 365 toSubviews:subviews |
357 atOffset:offset]; | 366 atOffset:offset]; |
358 } | 367 } |
368 | |
369 [self updateSuggestionLabelForModel:model]; | |
370 offset += [self addStackedView:suggestionLabel_ | |
371 toSubviews:subviews | |
372 atOffset:offset]; | |
373 | |
359 offset += kYMargin; | 374 offset += kYMargin; |
360 | 375 |
361 NSRect contentFrame = NSMakeRect(kFramePadding, 0, kWindowWidth, offset); | 376 NSRect contentFrame = NSMakeRect(kFramePadding, 0, kWindowWidth, offset); |
362 if(self = [super initWithFrame:contentFrame]) | 377 if(self = [super initWithFrame:contentFrame]) |
363 [self setSubviews: subviews]; | 378 [self setSubviews: subviews]; |
364 | 379 |
365 controller_ = controller; | 380 controller_ = controller; |
366 return self; | 381 return self; |
367 } | 382 } |
368 | 383 |
384 - (void)updateSuggestionLabelForModel:(WebIntentPickerModel*)model { | |
385 DCHECK(suggestionLabel_.get()); | |
386 string16 labelText; | |
387 | |
388 if (model->GetSuggestedExtensionCount() != 0) { | |
Nico
2012/05/16 23:55:25
nit "> 0"
| |
389 if (model->GetInstalledServiceCount() == 0) | |
390 labelText = l10n_util::GetStringUTF16( | |
391 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED); | |
392 else | |
393 labelText = l10n_util::GetStringUTF16( | |
394 IDS_INTENT_PICKER_GET_MORE_SERVICES); | |
395 } | |
396 | |
397 if (labelText.empty()) { | |
398 [suggestionLabel_ setHidden:TRUE]; | |
399 } else { | |
400 NSRect textFrame = [suggestionLabel_ frame]; | |
401 | |
402 [suggestionLabel_ setHidden:FALSE]; | |
403 [suggestionLabel_ setStringValue:base::SysUTF16ToNSString(labelText)]; | |
404 textFrame.size.height += | |
405 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: | |
406 suggestionLabel_]; | |
407 [suggestionLabel_ setFrame: textFrame]; | |
408 } | |
409 } | |
410 | |
369 - (void)startThrobberForRow:(NSInteger)index { | 411 - (void)startThrobberForRow:(NSInteger)index { |
370 for (SingleSuggestionView* row in [self subviews]) { | 412 for (SingleSuggestionView* row in [self subviews]) { |
371 [row setEnabled:NO]; | 413 [row setEnabled:NO]; |
372 if ([row tag] == index) | 414 if ([row tag] == index) |
373 [row startThrobber]; | 415 [row startThrobber]; |
374 } | 416 } |
375 } | 417 } |
376 | 418 |
377 - (void)stopThrobber { | 419 - (void)stopThrobber { |
378 for (SingleSuggestionView* row in [self subviews]) { | 420 for (SingleSuggestionView* row in [self subviews]) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 picker_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id)); | 526 picker_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id)); |
485 } | 527 } |
486 } | 528 } |
487 | 529 |
488 - (void)setIntentButtonsEnabled:(BOOL)enabled { | 530 - (void)setIntentButtonsEnabled:(BOOL)enabled { |
489 for (NSButton* button in intentButtons_.get()) { | 531 for (NSButton* button in intentButtons_.get()) { |
490 [button setEnabled:enabled]; | 532 [button setEnabled:enabled]; |
491 } | 533 } |
492 } | 534 } |
493 | 535 |
494 // Sets properties on the given |field| to act as title or description labels. | |
495 - (void)configureTextFieldAsLabel:(NSTextField*)field { | |
496 [field setEditable:NO]; | |
497 [field setSelectable:YES]; | |
498 [field setDrawsBackground:NO]; | |
499 [field setBezeled:NO]; | |
500 } | |
501 | |
502 - (CGFloat)addStackedView:(NSView*)view | 536 - (CGFloat)addStackedView:(NSView*)view |
503 toSubviews:(NSMutableArray*)subviews | 537 toSubviews:(NSMutableArray*)subviews |
504 atOffset:(CGFloat)offset { | 538 atOffset:(CGFloat)offset { |
505 if (view == nil) | 539 if (view == nil) |
506 return 0.0; | 540 return 0.0; |
507 | 541 |
508 NSPoint frameOrigin = [view frame].origin; | 542 NSPoint frameOrigin = [view frame].origin; |
509 frameOrigin.y = offset; | 543 frameOrigin.y = offset; |
510 [view setFrameOrigin:frameOrigin]; | 544 [view setFrameOrigin:frameOrigin]; |
511 [subviews addObject:view]; | 545 [subviews addObject:view]; |
512 | 546 |
513 return NSHeight([view frame]); | 547 return NSHeight([view frame]); |
514 } | 548 } |
515 | 549 |
516 // Adds a link to the Chrome Web Store, to obtain further intent handlers. | 550 // Adds a link to the Chrome Web Store, to obtain further intent handlers. |
517 // Returns the y position delta for the next offset. | 551 // Returns the y position delta for the next offset. |
518 - (CGFloat)addCwsButtonToSubviews:(NSMutableArray*)subviews | 552 - (CGFloat)addCwsButtonToSubviews:(NSMutableArray*)subviews |
519 atOffset:(CGFloat)offset { | 553 atOffset:(CGFloat)offset { |
520 NSRect frame = NSMakeRect(kFramePadding, offset, 100, 10); | 554 NSRect frame = NSMakeRect(kFramePadding, offset, 100, 10); |
521 NSString* string = | 555 NSString* string = |
522 l10n_util::GetNSStringWithFixup(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE); | 556 l10n_util::GetNSStringWithFixup(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE); |
523 scoped_nsobject<NSButton> button( | 557 scoped_nsobject<NSButton> button(CreateHyperlinkButton(string,frame)); |
524 [WebIntentPickerSheetController createHyperlinkButton:string | |
525 withFrame:frame]); | |
526 [button setTarget:self]; | 558 [button setTarget:self]; |
527 [button setAction:@selector(showChromeWebStore:)]; | 559 [button setAction:@selector(showChromeWebStore:)]; |
528 [subviews addObject:button.get()]; | 560 [subviews addObject:button.get()]; |
529 | 561 |
530 // Call size-to-fit to fixup for the localized string. | 562 // Call size-to-fit to fixup for the localized string. |
531 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; | 563 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; |
532 | 564 |
533 return NSHeight([button frame]); | 565 return NSHeight([button frame]); |
534 } | 566 } |
535 | 567 |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
686 [NSArray arrayWithObject:contentView]]; | 718 [NSArray arrayWithObject:contentView]]; |
687 } | 719 } |
688 | 720 |
689 - (void)setActionString:(NSString*)actionString { | 721 - (void)setActionString:(NSString*)actionString { |
690 NSRect textFrame; | 722 NSRect textFrame; |
691 if (!actionTextField_.get()) { | 723 if (!actionTextField_.get()) { |
692 textFrame = NSMakeRect(kFramePadding, 0, | 724 textFrame = NSMakeRect(kFramePadding, 0, |
693 kTextWidth, 1); | 725 kTextWidth, 1); |
694 | 726 |
695 actionTextField_.reset([[NSTextField alloc] initWithFrame:textFrame]); | 727 actionTextField_.reset([[NSTextField alloc] initWithFrame:textFrame]); |
696 [self configureTextFieldAsLabel:actionTextField_.get()]; | 728 ConfigureTextFieldAsLabel(actionTextField_); |
697 [actionTextField_ setFont:[NSFont systemFontOfSize:kHeaderFontSize]]; | 729 [actionTextField_ setFont:[NSFont systemFontOfSize:kHeaderFontSize]]; |
698 } else { | 730 } else { |
699 textFrame = [actionTextField_ frame]; | 731 textFrame = [actionTextField_ frame]; |
700 } | 732 } |
701 | 733 |
702 [actionTextField_ setStringValue:actionString]; | 734 [actionTextField_ setStringValue:actionString]; |
703 textFrame.size.height += | 735 textFrame.size.height += |
704 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: | 736 [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: |
705 actionTextField_]; | 737 actionTextField_]; |
706 [actionTextField_ setFrame: textFrame]; | 738 [actionTextField_ setFrame: textFrame]; |
707 } | 739 } |
708 | 740 |
709 - (void)stopThrobber { | 741 - (void)stopThrobber { |
710 [closeButton_ setEnabled:YES]; | 742 [closeButton_ setEnabled:YES]; |
711 [self setIntentButtonsEnabled:YES]; | 743 [self setIntentButtonsEnabled:YES]; |
712 [suggestionView_ stopThrobber]; | 744 [suggestionView_ stopThrobber]; |
713 } | 745 } |
714 | 746 |
715 - (void)closeSheet { | 747 - (void)closeSheet { |
716 [NSApp endSheet:[self window]]; | 748 [NSApp endSheet:[self window]]; |
717 } | 749 } |
718 @end // WebIntentPickerSheetController | 750 @end // WebIntentPickerSheetController |
OLD | NEW |