Chromium Code Reviews| 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" |
| 11 #import "chrome/browser/ui/cocoa/hover_close_button.h" | 11 #import "chrome/browser/ui/cocoa/hover_close_button.h" |
| 12 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" | 12 #import "chrome/browser/ui/cocoa/hyperlink_button_cell.h" |
| 13 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 13 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 14 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 14 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 15 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h" | 15 #include "chrome/browser/ui/cocoa/web_intent_picker_cocoa.h" |
| 16 #include "chrome/browser/ui/constrained_window.h" | 16 #include "chrome/browser/ui/constrained_window.h" |
| 17 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" | 17 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
| 18 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 18 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
| 19 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 19 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 20 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
| 21 #include "content/public/browser/web_contents_view.h" | 21 #include "content/public/browser/web_contents_view.h" |
| 22 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
| 23 #include "grit/google_chrome_strings.h" | 23 #include "grit/google_chrome_strings.h" |
| 24 #include "grit/locale_settings.h" | 24 #include "grit/locale_settings.h" |
| 25 #include "grit/theme_resources.h" | 25 #include "grit/theme_resources.h" |
| 26 #include "grit/ui_resources.h" | 26 #include "grit/ui_resources.h" |
| 27 #include "skia/ext/skia_utils_mac.h" | |
| 27 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 28 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 29 #include "third_party/skia/include/core/SkColor.h" | |
| 28 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 29 #include "ui/base/l10n/l10n_util_mac.h" | 31 #include "ui/base/l10n/l10n_util_mac.h" |
| 30 #include "ui/base/resource/resource_bundle.h" | 32 #include "ui/base/resource/resource_bundle.h" |
| 31 #include "ui/base/text/text_elider.h" | 33 #include "ui/base/text/text_elider.h" |
| 32 #include "ui/gfx/font.h" | 34 #include "ui/gfx/font.h" |
| 33 #include "ui/gfx/image/image.h" | 35 #include "ui/gfx/image/image.h" |
| 34 | 36 |
| 35 using content::OpenURLParams; | 37 using content::OpenURLParams; |
| 36 using content::Referrer; | 38 using content::Referrer; |
| 37 | 39 |
| 40 @interface HyperlinkButtonCell (Private) | |
| 41 - (void)customizeButtonCell; | |
| 42 @end | |
| 43 | |
| 44 @interface CustomLinkButtonCell : HyperlinkButtonCell | |
| 45 @end | |
| 46 | |
| 38 namespace { | 47 namespace { |
| 39 | 48 |
| 40 // The width of a service button, in view coordinates. | 49 // The width of a service button, in view coordinates. |
| 41 const CGFloat kServiceButtonWidth = 300; | 50 const CGFloat kServiceButtonWidth = 300; |
| 42 | 51 |
| 43 // Spacing in between sections. | 52 // Spacing in between sections. |
| 44 const CGFloat kVerticalSpacing = 18; | 53 const CGFloat kVerticalSpacing = 18; |
| 45 | 54 |
| 46 // Square size of the close button. | 55 // Square size of the close button. |
| 47 const CGFloat kCloseButtonSize = 16; | 56 const CGFloat kCloseButtonSize = 16; |
| 48 | 57 |
| 49 // Font size for picker header. | |
| 50 const CGFloat kHeaderFontSize = 14.5; | |
| 51 | |
| 52 // Width of the text fields. | 58 // Width of the text fields. |
| 53 const CGFloat kTextWidth = WebIntentPicker::kWindowWidth - | 59 const CGFloat kTextWidth = WebIntentPicker::kWindowWidth - |
| 54 (WebIntentPicker::kContentAreaBorder * 2.0 + kCloseButtonSize); | 60 (WebIntentPicker::kContentAreaBorder * 2.0 + kCloseButtonSize); |
| 55 | 61 |
| 56 // Maximum number of intents (suggested and installed) displayed. | 62 // Maximum number of intents (suggested and installed) displayed. |
| 57 const int kMaxIntentRows = 4; | 63 const int kMaxIntentRows = 4; |
| 58 | 64 |
| 59 // Sets properties on the given |field| to act as title or description labels. | 65 // Sets properties on the given |field| to act as title or description labels. |
| 60 void ConfigureTextFieldAsLabel(NSTextField* field) { | 66 void ConfigureTextFieldAsLabel(NSTextField* field) { |
| 61 [field setEditable:NO]; | 67 [field setEditable:NO]; |
| 62 [field setSelectable:YES]; | 68 [field setSelectable:YES]; |
| 63 [field setDrawsBackground:NO]; | 69 [field setDrawsBackground:NO]; |
| 64 [field setBezeled:NO]; | 70 [field setBezeled:NO]; |
| 65 } | 71 } |
| 66 | 72 |
| 67 NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { | 73 NSButton* CreateHyperlinkButton(NSString* title, const NSRect& frame) { |
| 68 NSButton* button = [[NSButton alloc] initWithFrame:frame]; | 74 NSButton* button = [[NSButton alloc] initWithFrame:frame]; |
| 69 scoped_nsobject<HyperlinkButtonCell> cell( | 75 scoped_nsobject<CustomLinkButtonCell> cell( |
| 70 [[HyperlinkButtonCell alloc] initTextCell:title]); | 76 [[CustomLinkButtonCell alloc] initTextCell:title]); |
| 71 [cell setControlSize:NSSmallControlSize]; | 77 [cell setControlSize:NSSmallControlSize]; |
| 72 [button setCell:cell.get()]; | 78 [button setCell:cell.get()]; |
| 73 [button setButtonType:NSMomentaryPushInButton]; | 79 [button setButtonType:NSMomentaryPushInButton]; |
| 74 [button setBezelStyle:NSRegularSquareBezelStyle]; | 80 [button setBezelStyle:NSRegularSquareBezelStyle]; |
| 75 | 81 |
| 76 return button; | 82 return button; |
| 77 } | 83 } |
| 78 | 84 |
| 79 } // namespace | 85 } // namespace |
| 80 | 86 |
| 87 | |
| 88 // Provide custom link format for intent picker. Removes underline attribute, | |
| 89 // since UX direction is "look like WebUI". | |
| 90 @implementation CustomLinkButtonCell | |
| 91 - (void)customizeButtonCell { | |
| 92 [super customizeButtonCell]; | |
| 93 SkColor linkColor = SkColorSetARGB(0xff, 0x11, 0x55,0xcc); | |
| 94 [self setTextColor:gfx::SkColorToDeviceNSColor(linkColor)]; | |
|
Nico
2012/09/07 16:50:21
What's wrong with NSColor colorWithDeviceR:g:b:a?
groby-ooo-7-16
2012/09/08 00:29:39
Done.
| |
| 95 } | |
| 96 | |
| 97 - (NSDictionary*)linkAttributes { | |
| 98 scoped_nsobject<NSMutableParagraphStyle> paragraphStyle( | |
| 99 [[NSParagraphStyle defaultParagraphStyle] mutableCopy]); | |
| 100 [paragraphStyle setAlignment:[self alignment]]; | |
| 101 | |
| 102 return @{NSForegroundColorAttributeName: [self textColor], | |
|
Nico
2012/09/07 16:50:21
break after @{:
return @{
foo: ...,
bar
groby-ooo-7-16
2012/09/08 00:29:39
Done.
| |
| 103 NSFontAttributeName: [self font], | |
| 104 NSCursorAttributeName: [NSCursor pointingHandCursor], | |
| 105 NSParagraphStyleAttributeName: paragraphStyle.get()}; | |
| 106 } | |
| 107 @end | |
| 108 | |
| 81 // This simple NSView subclass is used as the single subview of the page info | 109 // This simple NSView subclass is used as the single subview of the page info |
| 82 // bubble's window's contentView. Drawing is flipped so that layout of the | 110 // bubble's window's contentView. Drawing is flipped so that layout of the |
| 83 // sections is easier. Apple recommends flipping the coordinate origin when | 111 // sections is easier. Apple recommends flipping the coordinate origin when |
| 84 // doing a lot of text layout because it's more natural. | 112 // doing a lot of text layout because it's more natural. |
| 85 @interface WebIntentsContentView : NSView | 113 @interface WebIntentsContentView : NSView |
| 86 @end | 114 @end |
| 87 @implementation WebIntentsContentView | 115 @implementation WebIntentsContentView |
| 88 - (BOOL)isFlipped { | 116 - (BOOL)isFlipped { |
| 89 return YES; | 117 return YES; |
| 90 } | 118 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 189 kTextWidth, 1); | 217 kTextWidth, 1); |
| 190 subtitleField_.reset([[NSTextField alloc] initWithFrame:frame]); | 218 subtitleField_.reset([[NSTextField alloc] initWithFrame:frame]); |
| 191 ConfigureTextFieldAsLabel(subtitleField_); | 219 ConfigureTextFieldAsLabel(subtitleField_); |
| 192 gfx::Font textFont = rb.GetFont(ConstrainedWindow::kTextFontStyle); | 220 gfx::Font textFont = rb.GetFont(ConstrainedWindow::kTextFontStyle); |
| 193 [subtitleField_ setFont:textFont.GetNativeFont()]; | 221 [subtitleField_ setFont:textFont.GetNativeFont()]; |
| 194 | 222 |
| 195 frame = NSMakeRect(0, 0, WebIntentPicker::kWindowWidth, 1.0); | 223 frame = NSMakeRect(0, 0, WebIntentPicker::kWindowWidth, 1.0); |
| 196 spacer_.reset([[NSBox alloc] initWithFrame:frame]); | 224 spacer_.reset([[NSBox alloc] initWithFrame:frame]); |
| 197 [spacer_ setBoxType:NSBoxSeparator]; | 225 [spacer_ setBoxType:NSBoxSeparator]; |
| 198 [spacer_ setBorderColor:[NSColor blackColor]]; | 226 [spacer_ setBorderColor:[NSColor blackColor]]; |
| 227 [spacer_ setAlphaValue:0.2]; | |
| 199 | 228 |
| 200 NSArray* subviews = @[titleField_, subtitleField_, spacer_]; | 229 NSArray* subviews = @[titleField_, subtitleField_, spacer_]; |
| 201 [self setSubviews:subviews]; | 230 [self setSubviews:subviews]; |
| 202 } | 231 } |
| 203 return self; | 232 return self; |
| 204 } | 233 } |
| 205 | 234 |
| 206 - (void)setTitle:(NSString*)title { | 235 - (void)setTitle:(NSString*)title { |
| 207 NSRect frame = [titleField_ frame]; | 236 NSRect frame = [titleField_ frame]; |
| 208 [titleField_ setStringValue:title]; | 237 [titleField_ setStringValue:title]; |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 630 styleMask:NSTitledWindowMask | 659 styleMask:NSTitledWindowMask |
| 631 backing:NSBackingStoreBuffered | 660 backing:NSBackingStoreBuffered |
| 632 defer:YES]); | 661 defer:YES]); |
| 633 if ((self = [super initWithWindow:window.get()])) { | 662 if ((self = [super initWithWindow:window.get()])) { |
| 634 picker_ = picker; | 663 picker_ = picker; |
| 635 if (picker) | 664 if (picker) |
| 636 model_ = picker->model(); | 665 model_ = picker->model(); |
| 637 | 666 |
| 638 inlineDispositionTitleField_.reset([[NSTextField alloc] init]); | 667 inlineDispositionTitleField_.reset([[NSTextField alloc] init]); |
| 639 ConfigureTextFieldAsLabel(inlineDispositionTitleField_); | 668 ConfigureTextFieldAsLabel(inlineDispositionTitleField_); |
| 640 | 669 [inlineDispositionTitleField_ setFont:[NSFont boldSystemFontOfSize:0]]; |
| 641 flipView_.reset([[WebIntentsContentView alloc] init]); | 670 flipView_.reset([[WebIntentsContentView alloc] init]); |
| 642 [flipView_ setAutoresizingMask:NSViewMinYMargin]; | 671 [flipView_ setAutoresizingMask:NSViewMinYMargin]; |
| 643 [[[self window] contentView] setSubviews: | 672 [[[self window] contentView] setSubviews: |
| 644 [NSArray arrayWithObject:flipView_]]; | 673 [NSArray arrayWithObject:flipView_]]; |
| 645 | 674 |
| 646 [self performLayoutWithModel:model_]; | 675 [self performLayoutWithModel:model_]; |
| 647 [[self window] makeFirstResponder:self]; | 676 [[self window] makeFirstResponder:self]; |
| 648 } | 677 } |
| 649 return self; | 678 return self; |
| 650 } | 679 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 containerSize.height += | 720 containerSize.height += |
| 692 [webContentView frame].origin.y + WebIntentPicker::kContentAreaBorder; | 721 [webContentView frame].origin.y + WebIntentPicker::kContentAreaBorder; |
| 693 containerSize.width += 2 * WebIntentPicker::kContentAreaBorder; | 722 containerSize.width += 2 * WebIntentPicker::kContentAreaBorder; |
| 694 | 723 |
| 695 // Ensure minimum container width. | 724 // Ensure minimum container width. |
| 696 containerSize.width = | 725 containerSize.width = |
| 697 std::max(CGFloat(WebIntentPicker::kWindowWidth), containerSize.width); | 726 std::max(CGFloat(WebIntentPicker::kWindowWidth), containerSize.width); |
| 698 | 727 |
| 699 // Resize web contents. | 728 // Resize web contents. |
| 700 [webContentView setFrameSize:inlineContentSize]; | 729 [webContentView setFrameSize:inlineContentSize]; |
| 701 | |
| 702 // Position close button. | |
| 703 NSRect buttonFrame = [closeButton_ frame]; | |
| 704 buttonFrame.origin.x = containerSize.width - | |
| 705 WebIntentPicker::kContentAreaBorder - kCloseButtonSize; | |
| 706 [closeButton_ setFrame:buttonFrame]; | |
| 707 | |
| 708 [self setContainerSize:containerSize]; | 730 [self setContainerSize:containerSize]; |
| 709 } | 731 } |
| 710 | 732 |
| 711 - (void)setContainerSize:(NSSize)containerSize { | 733 - (void)setContainerSize:(NSSize)containerSize { |
| 712 // Resize container views | 734 // Resize container views |
| 713 NSRect frame = NSMakeRect(0, 0, 0, 0); | 735 NSRect frame = NSMakeRect(0, 0, 0, 0); |
| 714 frame.size = containerSize; | 736 frame.size = containerSize; |
| 715 [[[self window] contentView] setFrame:frame]; | 737 [[[self window] contentView] setFrame:frame]; |
| 716 [flipView_ setFrame:frame]; | 738 [flipView_ setFrame:frame]; |
| 717 | 739 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 788 [button setAction:@selector(showChromeWebStore:)]; | 810 [button setAction:@selector(showChromeWebStore:)]; |
| 789 [subviews addObject:button.get()]; | 811 [subviews addObject:button.get()]; |
| 790 | 812 |
| 791 // Call size-to-fit to fixup for the localized string. | 813 // Call size-to-fit to fixup for the localized string. |
| 792 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; | 814 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button.get()]; |
| 793 | 815 |
| 794 return NSHeight([button frame]); | 816 return NSHeight([button frame]); |
| 795 } | 817 } |
| 796 | 818 |
| 797 - (void)addCloseButtonToSubviews:(NSMutableArray*)subviews { | 819 - (void)addCloseButtonToSubviews:(NSMutableArray*)subviews { |
| 820 const CGFloat kButtonFuzz = 4.0; // whitespace inside button frame. | |
|
Nico
2012/09/07 16:50:21
in css speak this is called "padding", so call it
groby-ooo-7-16
2012/09/08 00:29:39
Done.
| |
| 798 if (!closeButton_.get()) { | 821 if (!closeButton_.get()) { |
| 799 NSRect buttonFrame = NSMakeRect( | 822 NSRect buttonFrame = NSMakeRect( |
| 800 WebIntentPicker::kContentAreaBorder + kTextWidth, | 823 WebIntentPicker::kContentAreaBorder + kTextWidth + kButtonFuzz, |
| 801 WebIntentPicker::kContentAreaBorder, | 824 WebIntentPicker::kContentAreaBorder - kButtonFuzz, |
| 802 kCloseButtonSize, kCloseButtonSize); | 825 kCloseButtonSize, kCloseButtonSize); |
| 803 closeButton_.reset( | 826 closeButton_.reset( |
| 804 [[HoverCloseButton alloc] initWithFrame:buttonFrame]); | 827 [[HoverCloseButton alloc] initWithFrame:buttonFrame]); |
| 828 // Anchor close button to upper right. | |
| 829 [closeButton_ setAutoresizingMask:NSViewMaxYMargin|NSViewMinXMargin]; | |
|
Nico
2012/09/07 16:50:21
y grows too the top, so this anchors to lower righ
groby-ooo-7-16
2012/09/08 00:29:39
It's inside a flipped view. so it's actually ancho
Nico
2012/09/08 00:30:45
Might be worth a comment then.
On 2012/09/08 00:2
groby-ooo-7-16
2012/09/08 00:48:38
Done.
| |
| 805 [closeButton_ setTarget:self]; | 830 [closeButton_ setTarget:self]; |
| 806 [closeButton_ setAction:@selector(cancelOperation:)]; | 831 [closeButton_ setAction:@selector(cancelOperation:)]; |
| 807 } | 832 } |
| 808 [subviews addObject:closeButton_]; | 833 [subviews addObject:closeButton_]; |
| 809 } | 834 } |
| 810 | 835 |
| 811 // Adds a header (icon and explanatory text) to picker bubble. | 836 // Adds a header (icon and explanatory text) to picker bubble. |
| 812 // Returns the y position delta for the next offset. | 837 // Returns the y position delta for the next offset. |
| 813 - (CGFloat)addHeaderToSubviews:(NSMutableArray*)subviews | 838 - (CGFloat)addHeaderToSubviews:(NSMutableArray*)subviews |
| 814 atOffset:(CGFloat)offset { | 839 atOffset:(CGFloat)offset { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 849 WebIntentPicker::kContentAreaBorder, offset, size.width(), size.height()); | 874 WebIntentPicker::kContentAreaBorder, offset, size.width(), size.height()); |
| 850 | 875 |
| 851 [contents_->web_contents()->GetNativeView() setFrame:frame]; | 876 [contents_->web_contents()->GetNativeView() setFrame:frame]; |
| 852 [subviews addObject:contents_->web_contents()->GetNativeView()]; | 877 [subviews addObject:contents_->web_contents()->GetNativeView()]; |
| 853 | 878 |
| 854 return NSHeight(frame); | 879 return NSHeight(frame); |
| 855 } | 880 } |
| 856 | 881 |
| 857 - (CGFloat)addAnotherServiceLinkToSubviews:(NSMutableArray*)subviews | 882 - (CGFloat)addAnotherServiceLinkToSubviews:(NSMutableArray*)subviews |
| 858 atOffset:(CGFloat)offset { | 883 atOffset:(CGFloat)offset { |
| 884 DCHECK(model_); | |
| 885 DCHECK(model_->IsInlineDisposition()); | |
| 886 GURL url = model_->inline_disposition_url(); | |
| 859 | 887 |
| 888 const WebIntentPickerModel::InstalledService* service = | |
| 889 model_->GetInstalledServiceWithURL(url); | |
| 890 DCHECK(service); | |
| 891 | |
| 892 CGFloat originalOffset = offset; | |
| 893 | |
| 894 // Icon for current service. | |
| 895 scoped_nsobject<NSImageView> icon; | |
| 896 NSRect imageFrame = NSMakeRect(WebIntentPicker::kContentAreaBorder, offset, | |
| 897 0, 0); | |
| 898 icon.reset([[NSImageView alloc] initWithFrame:imageFrame]); | |
| 899 [icon setImage:service->favicon.ToNSImage()]; | |
| 900 [icon setImageFrameStyle:NSImageFrameNone]; | |
| 901 [icon setEnabled:YES]; | |
| 902 | |
| 903 imageFrame.size = [service->favicon.ToNSImage() size]; | |
| 904 [icon setFrame:imageFrame]; | |
| 905 | |
| 906 [subviews addObject:icon]; | |
| 907 | |
| 908 // Resize control to fit text | |
| 860 NSRect textFrame = | 909 NSRect textFrame = |
| 861 NSMakeRect(WebIntentPicker::kContentAreaBorder, offset, kTextWidth, 1); | 910 NSMakeRect(NSMaxX(imageFrame) + 4, |
| 911 offset, | |
| 912 WebIntentPicker::kTitleLinkMaxWidth, 1); | |
| 862 [inlineDispositionTitleField_ setFrame:textFrame]; | 913 [inlineDispositionTitleField_ setFrame:textFrame]; |
| 863 [subviews addObject:inlineDispositionTitleField_]; | 914 [subviews addObject:inlineDispositionTitleField_]; |
| 864 [GTMUILocalizerAndLayoutTweaker sizeToFitView:inlineDispositionTitleField_]; | 915 [GTMUILocalizerAndLayoutTweaker sizeToFitView:inlineDispositionTitleField_]; |
| 865 textFrame = [inlineDispositionTitleField_ frame]; | 916 textFrame = [inlineDispositionTitleField_ frame]; |
| 866 | 917 |
| 867 // Add link for "choose another service" if other suggestions are available | 918 // Add link for "choose another service" if other suggestions are available |
| 868 // or if more than one (the current) service is installed. | 919 // or if more than one (the current) service is installed. |
| 869 if (model_->GetInstalledServiceCount() > 1 || | 920 if (model_->GetInstalledServiceCount() > 1 || |
| 870 model_->GetSuggestedExtensionCount()) { | 921 model_->GetSuggestedExtensionCount()) { |
| 871 NSRect frame = NSMakeRect( | 922 NSRect frame = NSMakeRect( |
| 872 NSMaxX(textFrame) + WebIntentPicker::kContentAreaBorder, offset, | 923 NSMaxX(textFrame) + WebIntentPicker::kContentAreaBorder, offset, |
| 873 WebIntentPicker::kTitleLinkMaxWidth, 1); | 924 1, 1); |
| 874 NSString* string = l10n_util::GetNSStringWithFixup( | 925 NSString* string = l10n_util::GetNSStringWithFixup( |
| 875 IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE); | 926 IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE); |
| 876 scoped_nsobject<NSButton> button(CreateHyperlinkButton(string, frame)); | 927 scoped_nsobject<NSButton> button(CreateHyperlinkButton(string, frame)); |
| 877 [[button cell] setControlSize:NSRegularControlSize]; | 928 [[button cell] setControlSize:NSRegularControlSize]; |
| 929 [[button cell] setFont:[NSFont controlContentFontOfSize:0]]; | |
| 878 [button setTarget:self]; | 930 [button setTarget:self]; |
| 879 [button setAction:@selector(chooseAnotherService:)]; | 931 [button setAction:@selector(chooseAnotherService:)]; |
| 880 [subviews addObject:button]; | 932 [subviews addObject:button]; |
| 881 | 933 |
| 882 // Call size-to-fit to fixup for the localized string. | 934 // Call size-to-fit to fixup for the localized string. |
| 883 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button]; | 935 [GTMUILocalizerAndLayoutTweaker sizeToFitView:button]; |
| 884 | 936 |
| 937 // Right-align the "use another service" button. | |
| 938 frame = [button frame]; | |
| 939 frame.origin.x = WebIntentPicker::kWindowWidth - NSWidth(frame) - | |
| 940 2 * WebIntentPicker::kContentAreaBorder - kCloseButtonSize; | |
| 941 [button setFrame:frame]; | |
| 942 [button setAutoresizingMask:NSViewMinXMargin]; | |
| 943 | |
| 885 // And finally, make sure the link and the title are horizontally centered. | 944 // And finally, make sure the link and the title are horizontally centered. |
| 886 frame = [button frame]; | 945 frame = [button frame]; |
| 887 CGFloat height = std::max(NSHeight(textFrame), NSHeight(frame)); | 946 CGFloat height = std::max(NSHeight(textFrame), NSHeight(frame)); |
| 888 frame.origin.y += (height - NSHeight(frame)) / 2.0; | 947 frame.origin.y += (height - NSHeight(frame)) / 2.0; |
| 889 frame.size.height = height; | 948 frame.size.height = height; |
| 890 textFrame.origin.y += (height - NSHeight(textFrame)) / 2.0; | 949 textFrame.origin.y += (height - NSHeight(textFrame)) / 2.0; |
| 891 textFrame.size.height = height; | 950 textFrame.size.height = height; |
| 892 [button setFrame:frame]; | 951 [button setFrame:frame]; |
| 893 [inlineDispositionTitleField_ setFrame:textFrame]; | 952 [inlineDispositionTitleField_ setFrame:textFrame]; |
| 894 } | 953 } |
| 895 | 954 |
| 896 return NSHeight(textFrame); | 955 offset += NSHeight(textFrame) + kVerticalSpacing; |
| 956 | |
| 957 scoped_nsobject<NSBox> spacer; | |
| 958 | |
| 959 NSRect frame = NSMakeRect(0, offset, WebIntentPicker::kWindowWidth, 1.0); | |
| 960 spacer.reset([[NSBox alloc] initWithFrame:frame]); | |
| 961 [spacer setBoxType:NSBoxSeparator]; | |
| 962 [spacer setAlphaValue:0.2]; | |
| 963 [spacer setAutoresizingMask:NSViewWidthSizable]; | |
| 964 [subviews addObject: spacer]; | |
| 965 | |
| 966 return offset + kVerticalSpacing - originalOffset; | |
| 897 } | 967 } |
| 898 | 968 |
| 899 - (NSView*)createEmptyView { | 969 - (NSView*)createEmptyView { |
| 900 NSMutableArray* subviews = [NSMutableArray array]; | 970 NSMutableArray* subviews = [NSMutableArray array]; |
| 901 | 971 |
| 902 NSRect titleFrame = NSMakeRect(WebIntentPicker::kContentAreaBorder, | 972 NSRect titleFrame = NSMakeRect(WebIntentPicker::kContentAreaBorder, |
| 903 WebIntentPicker::kContentAreaBorder, | 973 WebIntentPicker::kContentAreaBorder, |
| 904 kTextWidth, 1); | 974 kTextWidth, 1); |
| 905 scoped_nsobject<NSTextField> title( | 975 scoped_nsobject<NSTextField> title( |
| 906 [[NSTextField alloc] initWithFrame:titleFrame]); | 976 [[NSTextField alloc] initWithFrame:titleFrame]); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 963 !model_->GetInstalledServiceCount() && | 1033 !model_->GetInstalledServiceCount() && |
| 964 !model_->GetSuggestedExtensionCount(); | 1034 !model_->GetSuggestedExtensionCount(); |
| 965 | 1035 |
| 966 if (isEmpty) { | 1036 if (isEmpty) { |
| 967 scoped_nsobject<NSView> emptyView([self createEmptyView]); | 1037 scoped_nsobject<NSView> emptyView([self createEmptyView]); |
| 968 [subviews addObject:emptyView]; | 1038 [subviews addObject:emptyView]; |
| 969 offset += NSHeight([emptyView frame]); | 1039 offset += NSHeight([emptyView frame]); |
| 970 } else if (contents_) { | 1040 } else if (contents_) { |
| 971 offset += [self addAnotherServiceLinkToSubviews:subviews | 1041 offset += [self addAnotherServiceLinkToSubviews:subviews |
| 972 atOffset:offset]; | 1042 atOffset:offset]; |
| 973 offset += WebIntentPicker::kContentAreaBorder; | |
| 974 offset += [self addInlineHtmlToSubviews:subviews atOffset:offset]; | 1043 offset += [self addInlineHtmlToSubviews:subviews atOffset:offset]; |
| 975 } else { | 1044 } else { |
| 976 offset += [self addHeaderToSubviews:subviews atOffset:offset]; | 1045 offset += [self addHeaderToSubviews:subviews atOffset:offset]; |
| 977 | 1046 |
| 978 if (model) { | 1047 if (model) { |
| 979 intentView_.reset( | 1048 intentView_.reset( |
| 980 [[IntentView alloc] initWithModel:model forController:self]); | 1049 [[IntentView alloc] initWithModel:model forController:self]); |
| 981 offset += [self addStackedView:intentView_ | 1050 offset += [self addStackedView:intentView_ |
| 982 toSubviews:subviews | 1051 toSubviews:subviews |
| 983 atOffset:offset]; | 1052 atOffset:offset]; |
| 984 } | 1053 } |
| 985 offset += [self addCwsButtonToSubviews:subviews atOffset:offset]; | 1054 offset += [self addCwsButtonToSubviews:subviews atOffset:offset]; |
| 986 } | 1055 } |
| 987 [self addCloseButtonToSubviews:subviews]; | |
| 988 | 1056 |
| 989 // Add the bottom padding. | 1057 // Add the bottom padding. |
| 990 offset += WebIntentPicker::kContentAreaBorder; | 1058 offset += WebIntentPicker::kContentAreaBorder; |
| 991 | 1059 |
| 1060 // Resize to fit. | |
| 1061 [self setContainerSize:NSMakeSize(WebIntentPicker::kWindowWidth, offset)]; | |
| 1062 | |
| 1063 [self addCloseButtonToSubviews:subviews]; | |
| 1064 | |
| 992 // Replace the window's content. | 1065 // Replace the window's content. |
| 993 [flipView_ setSubviews:subviews]; | 1066 [flipView_ setSubviews:subviews]; |
| 994 | |
| 995 // And resize to fit. | |
| 996 [self setContainerSize:NSMakeSize(WebIntentPicker::kWindowWidth, offset)]; | |
| 997 } | 1067 } |
| 998 | 1068 |
| 999 - (void)setActionString:(NSString*)actionString { | 1069 - (void)setActionString:(NSString*)actionString { |
| 1000 NSRect textFrame; | 1070 NSRect textFrame; |
| 1001 if (!actionTextField_.get()) { | 1071 if (!actionTextField_.get()) { |
| 1002 textFrame = NSMakeRect(WebIntentPicker::kContentAreaBorder, 0, | 1072 textFrame = NSMakeRect(WebIntentPicker::kContentAreaBorder, 0, |
| 1003 kTextWidth, 1); | 1073 kTextWidth, 1); |
| 1004 | 1074 |
| 1005 actionTextField_.reset([[NSTextField alloc] initWithFrame:textFrame]); | 1075 actionTextField_.reset([[NSTextField alloc] initWithFrame:textFrame]); |
| 1006 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1076 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 1032 - (void)stopThrobber { | 1102 - (void)stopThrobber { |
| 1033 [closeButton_ setEnabled:YES]; | 1103 [closeButton_ setEnabled:YES]; |
| 1034 [intentView_ stopThrobber]; | 1104 [intentView_ stopThrobber]; |
| 1035 } | 1105 } |
| 1036 | 1106 |
| 1037 - (void)closeSheet { | 1107 - (void)closeSheet { |
| 1038 [NSApp endSheet:[self window]]; | 1108 [NSApp endSheet:[self window]]; |
| 1039 } | 1109 } |
| 1040 | 1110 |
| 1041 @end // WebIntentPickerSheetController | 1111 @end // WebIntentPickerSheetController |
| OLD | NEW |