OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/website_settings/permission_bubble_controller.h " | 5 #import "chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.h " |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/mac/bind_objc_block.h" | |
9 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
10 #include "base/mac/mac_util.h" | 11 #include "base/mac/mac_util.h" |
11 #include "base/strings/sys_string_conversions.h" | 12 #include "base/strings/sys_string_conversions.h" |
12 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
13 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
14 #include "chrome/browser/ui/browser_finder.h" | 15 #include "chrome/browser/ui/browser_finder.h" |
15 #import "chrome/browser/ui/chrome_style.h" | 16 #import "chrome/browser/ui/chrome_style.h" |
16 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 17 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
17 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" | 18 #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h" |
18 #import "chrome/browser/ui/cocoa/hover_close_button.h" | 19 #import "chrome/browser/ui/cocoa/hover_close_button.h" |
19 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" | 20 #import "chrome/browser/ui/cocoa/hyperlink_text_view.h" |
20 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 21 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
21 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 22 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
22 #include "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h" | 23 #include "chrome/browser/ui/cocoa/website_settings/permission_bubble_cocoa.h" |
24 #include "chrome/browser/ui/cocoa/website_settings/permission_selector_button.h" | |
23 #include "chrome/browser/ui/cocoa/website_settings/split_block_button.h" | 25 #include "chrome/browser/ui/cocoa/website_settings/split_block_button.h" |
24 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" | 26 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" |
25 #include "chrome/browser/ui/website_settings/permission_bubble_view.h" | 27 #include "chrome/browser/ui/website_settings/permission_bubble_view.h" |
28 #include "chrome/browser/ui/website_settings/permission_menu_model.h" | |
26 #include "content/public/browser/user_metrics.h" | 29 #include "content/public/browser/user_metrics.h" |
27 #include "grit/generated_resources.h" | 30 #include "grit/generated_resources.h" |
28 #include "skia/ext/skia_utils_mac.h" | 31 #include "skia/ext/skia_utils_mac.h" |
32 #import "ui/base/cocoa/menu_controller.h" | |
29 #include "ui/base/cocoa/window_size_constants.h" | 33 #include "ui/base/cocoa/window_size_constants.h" |
30 #import "ui/base/cocoa/menu_controller.h" | 34 #import "ui/base/cocoa/menu_controller.h" |
31 #include "ui/base/l10n/l10n_util_mac.h" | 35 #include "ui/base/l10n/l10n_util_mac.h" |
32 #include "ui/base/models/simple_menu_model.h" | 36 #include "ui/base/models/simple_menu_model.h" |
33 | 37 |
34 using base::UserMetricsAction; | 38 using base::UserMetricsAction; |
35 | 39 |
36 namespace { | 40 namespace { |
37 | 41 |
38 const CGFloat kHorizontalPadding = 20.0f; | 42 const CGFloat kHorizontalPadding = 20.0f; |
39 const CGFloat kVerticalPadding = 20.0f; | 43 const CGFloat kVerticalPadding = 20.0f; |
40 const CGFloat kButtonPadding = 10.0f; | 44 const CGFloat kButtonPadding = 10.0f; |
41 const CGFloat kTitlePaddingX = 50.0f; | 45 const CGFloat kTitlePaddingX = 50.0f; |
42 const CGFloat kCheckboxYAdjustment = 2.0f; | 46 const CGFloat kTitleFontSize = 15.0f; |
47 const CGFloat kPermissionFontSize = 12.0f; | |
48 const CGFloat kPermissionButtonTitleRightPadding = 4.0f; | |
43 | 49 |
44 const CGFloat kFontSize = 15.0f; | |
45 class MenuDelegate : public ui::SimpleMenuModel::Delegate { | 50 class MenuDelegate : public ui::SimpleMenuModel::Delegate { |
46 public: | 51 public: |
47 explicit MenuDelegate(PermissionBubbleController* bubble) | 52 explicit MenuDelegate(PermissionBubbleController* bubble) |
48 : bubble_controller_(bubble) {} | 53 : bubble_controller_(bubble) {} |
49 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { | 54 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { |
50 return false; | 55 return false; |
51 } | 56 } |
52 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { | 57 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { |
53 // TODO(leng): Change this to true once setting the bubble to be | 58 return true; |
54 // customizable works properly. Ideally, the bubble will alter its | |
55 // contents, rather than reshowing completely. | |
56 return false; | |
57 } | 59 } |
58 virtual bool GetAcceleratorForCommandId( | 60 virtual bool GetAcceleratorForCommandId( |
59 int command_id, | 61 int command_id, |
60 ui::Accelerator* accelerator) OVERRIDE { | 62 ui::Accelerator* accelerator) OVERRIDE { |
61 return false; | 63 return false; |
62 } | 64 } |
63 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE { | 65 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE { |
64 [bubble_controller_ onMenuItemClicked:command_id]; | 66 [bubble_controller_ onMenuItemClicked:command_id]; |
65 } | 67 } |
66 private: | 68 private: |
67 PermissionBubbleController* bubble_controller_; // Weak, owns us. | 69 PermissionBubbleController* bubble_controller_; // Weak, owns us. |
68 DISALLOW_COPY_AND_ASSIGN(MenuDelegate); | 70 DISALLOW_COPY_AND_ASSIGN(MenuDelegate); |
69 }; | 71 }; |
70 | 72 |
71 } // namespace | 73 } // namespace |
72 | 74 |
75 // NSPopUpButton with a menu containing two items: allow and block. | |
76 // One AllowBlockMenuButton is used for each requested permission, but only when | |
77 // the permission bubble is in 'customize' mode. | |
78 @interface AllowBlockMenuButton : NSPopUpButton { | |
79 @private | |
80 scoped_ptr<PermissionMenuModel> menuModel_; | |
81 base::scoped_nsobject<MenuController> menuController_; | |
82 } | |
83 | |
84 - (id)initForURL:(const GURL&)url | |
85 allowed:(BOOL)allow | |
86 index:(int)index | |
87 delegate:(PermissionBubbleView::Delegate*)delegate; | |
88 @end | |
89 | |
90 @implementation AllowBlockMenuButton | |
91 | |
92 - (id)initForURL:(const GURL&)url | |
93 allowed:(BOOL)allow | |
94 index:(int)index | |
95 delegate:(PermissionBubbleView::Delegate*)delegate { | |
96 if (self = [super initWithFrame:NSMakeRect(0, 0, 1, 1) pullsDown:NO]) { | |
groby-ooo-7-16
2014/04/25 19:25:28
Why not NSZeroRect?
leng
2014/04/25 22:18:56
Done.
| |
97 ContentSetting setting = | |
98 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | |
99 [self setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | |
100 [self setBordered:NO]; | |
101 | |
102 __block PermissionBubbleView::Delegate* blockDelegate = delegate; | |
103 PermissionMenuModel::ChangeCallback changeCallback = | |
104 base::BindBlock(^(const WebsiteSettingsUI::PermissionInfo& permission) { | |
groby-ooo-7-16
2014/04/25 19:25:28
I just realized we created an ObjC block for the O
leng
2014/04/25 22:18:56
On 2014/04/25 19:25:28, groby wrote:
> I just real
| |
105 blockDelegate->ToggleAccept( | |
106 index, permission.setting == CONTENT_SETTING_ALLOW); | |
107 }); | |
108 | |
109 menuModel_.reset(new PermissionMenuModel(url, setting, changeCallback)); | |
110 menuController_.reset([[MenuController alloc] initWithModel:menuModel_.get() | |
111 useWithPopUpButtonCell:NO]); | |
112 [self setMenu:[menuController_ menu]]; | |
113 [self selectItemAtIndex:menuModel_->GetIndexOfCommandId(setting)]; | |
114 [self sizeToFit]; | |
115 // Adjust the size to fit the current title. Using only -sizeToFit leaves | |
116 // an ugly amount of whitespace between the title and the arrows. | |
groby-ooo-7-16
2014/04/25 19:25:28
Ah. That's because NSPopUpButton's sizeToFit fits
leng
2014/04/25 22:18:56
Done.
| |
117 // TODO(leng): This was copied from PermissionSelectorButton. Move to a | |
118 // shared location, so that the code is not duplicated. | |
119 NSDictionary* textAttributes = @{NSFontAttributeName : [self font]}; | |
groby-ooo-7-16
2014/04/25 19:25:28
You could call
[[self attributedTitle] attribut
leng
2014/04/25 22:18:56
Done.
| |
120 NSSize titleSize = [[self title] sizeWithAttributes:textAttributes]; | |
121 NSRect frame = [self frame]; | |
122 NSRect titleRect = [[self cell] titleRectForBounds:frame]; | |
123 CGFloat width = titleSize.width + NSWidth(frame) - NSWidth(titleRect); | |
124 [self setFrameSize:NSMakeSize(width + kPermissionButtonTitleRightPadding, | |
125 NSHeight(frame))]; | |
126 } | |
127 return self; | |
128 } | |
129 | |
130 @end | |
131 | |
73 @interface PermissionBubbleController () | 132 @interface PermissionBubbleController () |
74 | 133 |
75 // Returns an autoreleased NSView displaying the icon and label for |request|. | 134 // Returns an autoreleased NSView displaying the icon and label for |request|. |
76 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request; | 135 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request; |
77 | 136 |
78 // Returns an autoreleased NSView displaying the title for the bubble | 137 // Returns an autoreleased NSView displaying the title for the bubble |
79 // requesting settings for |host|. | 138 // requesting settings for |host|. |
80 - (NSView*)titleWithHostname:(const std::string&)host; | 139 - (NSView*)titleWithHostname:(const std::string&)host; |
81 | 140 |
82 // Returns an autoreleased NSView displaying a checkbox for |request|. The | 141 // Returns an autoreleased NSView displaying a menu for |request|. The |
83 // checkbox will be initialized as checked if |checked| is YES. | 142 // menu will be initialized as 'allow' if |allow| is YES. |
84 - (NSView*)checkboxForRequest:(PermissionBubbleRequest*)request | 143 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request |
85 checked:(BOOL)checked; | 144 atIndex:(int)index |
145 allow:(BOOL)allow; | |
86 | 146 |
87 // Returns an autoreleased NSView of a button with |title| and |action|. | 147 // Returns an autoreleased NSView of a button with |title| and |action|. |
88 - (NSView*)buttonWithTitle:(NSString*)title | 148 - (NSView*)buttonWithTitle:(NSString*)title |
89 action:(SEL)action; | 149 action:(SEL)action; |
90 | 150 |
91 // Returns an autoreleased NSView displaying a block button. | 151 // Returns an autoreleased NSView displaying a block button. |
92 - (NSView*)blockButton; | 152 - (NSView*)blockButton; |
93 | 153 |
94 // Returns an autoreleased NSView with a block button and a drop-down menu | 154 // Returns an autoreleased NSView with a block button and a drop-down menu |
95 // with one item, which will change the UI to allow customizing the permissions. | 155 // with one item, which will change the UI to allow customizing the permissions. |
96 - (NSView*)blockButtonWithCustomizeMenu; | 156 - (NSView*)blockButtonWithCustomizeMenu; |
97 | 157 |
98 // Returns an autoreleased NSView displaying the close 'x' button. | 158 // Returns an autoreleased NSView displaying the close 'x' button. |
99 - (NSView*)closeButton; | 159 - (NSView*)closeButton; |
100 | 160 |
101 // Sets the width of both |viewA| and |viewB| to be the larger of the | |
102 // two views' widths. Does not change either view's origin or height. | |
103 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB; | |
104 | |
105 // Called when the 'ok' button is pressed. | 161 // Called when the 'ok' button is pressed. |
106 - (void)ok:(id)sender; | 162 - (void)ok:(id)sender; |
107 | 163 |
108 // Called when the 'allow' button is pressed. | 164 // Called when the 'allow' button is pressed. |
109 - (void)onAllow:(id)sender; | 165 - (void)onAllow:(id)sender; |
110 | 166 |
111 // Called when the 'block' button is pressed. | 167 // Called when the 'block' button is pressed. |
112 - (void)onBlock:(id)sender; | 168 - (void)onBlock:(id)sender; |
113 | 169 |
114 // Called when the 'close' button is pressed. | 170 // Called when the 'close' button is pressed. |
115 - (void)onClose:(id)sender; | 171 - (void)onClose:(id)sender; |
116 | 172 |
117 // Called when the 'customize' button is pressed. | 173 // Called when the 'customize' button is pressed. |
118 - (void)onCustomize:(id)sender; | 174 - (void)onCustomize:(id)sender; |
119 | 175 |
120 // Called when a checkbox changes from checked to unchecked, or vice versa. | 176 // Sets the width of both |viewA| and |viewB| to be the larger of the |
121 - (void)onCheckboxChanged:(id)sender; | 177 // two views' widths. Does not change either view's origin or height. |
178 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB; | |
179 | |
180 // Sets the offset of |viewA| so that its vertical center is aligned with the | |
181 // vertical center of |viewB|. | |
182 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB; | |
122 | 183 |
123 @end | 184 @end |
124 | 185 |
125 @implementation PermissionBubbleController | 186 @implementation PermissionBubbleController |
126 | 187 |
127 - (id)initWithParentWindow:(NSWindow*)parentWindow | 188 - (id)initWithParentWindow:(NSWindow*)parentWindow |
128 bridge:(PermissionBubbleCocoa*)bridge { | 189 bridge:(PermissionBubbleCocoa*)bridge { |
129 DCHECK(parentWindow); | 190 DCHECK(parentWindow); |
130 DCHECK(bridge); | 191 DCHECK(bridge); |
131 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] | 192 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 allowOrOkButton.reset([[self buttonWithTitle:okTitle | 230 allowOrOkButton.reset([[self buttonWithTitle:okTitle |
170 action:@selector(ok:)] retain]); | 231 action:@selector(ok:)] retain]); |
171 } else { | 232 } else { |
172 NSString* allowTitle = l10n_util::GetNSString(IDS_PERMISSION_ALLOW); | 233 NSString* allowTitle = l10n_util::GetNSString(IDS_PERMISSION_ALLOW); |
173 allowOrOkButton.reset([[self buttonWithTitle:allowTitle | 234 allowOrOkButton.reset([[self buttonWithTitle:allowTitle |
174 action:@selector(onAllow:)] retain]); | 235 action:@selector(onAllow:)] retain]); |
175 } | 236 } |
176 CGFloat yOffset = 2 * kVerticalPadding + NSMaxY([allowOrOkButton frame]); | 237 CGFloat yOffset = 2 * kVerticalPadding + NSMaxY([allowOrOkButton frame]); |
177 BOOL singlePermission = requests.size() == 1; | 238 BOOL singlePermission = requests.size() == 1; |
178 | 239 |
179 checkboxes_.reset(customizationMode ? [[NSMutableArray alloc] init] : nil); | 240 base::scoped_nsobject<NSMutableArray> permissionMenus; |
241 if (customizationMode) | |
242 permissionMenus.reset([[NSMutableArray alloc] init]); | |
243 | |
180 for (auto it = requests.begin(); it != requests.end(); it++) { | 244 for (auto it = requests.begin(); it != requests.end(); it++) { |
181 base::scoped_nsobject<NSView> permissionView; | 245 base::scoped_nsobject<NSView> permissionView( |
182 if (customizationMode) { | 246 [[self labelForRequest:(*it)] retain]); |
183 int index = it - requests.begin(); | |
184 permissionView.reset( | |
185 [[self checkboxForRequest:(*it) | |
186 checked:acceptStates[index] ? YES : NO] retain]); | |
187 [base::mac::ObjCCastStrict<NSButton>(permissionView) setTag:index]; | |
188 [checkboxes_ addObject:permissionView]; | |
189 } else { | |
190 permissionView.reset([[self labelForRequest:(*it)] retain]); | |
191 } | |
192 NSPoint origin = [permissionView frame].origin; | 247 NSPoint origin = [permissionView frame].origin; |
193 origin.x += kHorizontalPadding; | 248 origin.x += kHorizontalPadding; |
194 origin.y += yOffset; | 249 origin.y += yOffset; |
195 [permissionView setFrameOrigin:origin]; | 250 [permissionView setFrameOrigin:origin]; |
196 [contentView addSubview:permissionView]; | 251 [contentView addSubview:permissionView]; |
197 | 252 |
253 if (customizationMode) { | |
254 int index = it - requests.begin(); | |
255 base::scoped_nsobject<NSView> menu( | |
256 [[self menuForRequest:(*it) | |
257 atIndex:index | |
258 allow:acceptStates[index] ? YES : NO] retain]); | |
259 // Align vertically. Horizontal alignment will be adjusted once the | |
260 // widest permission is know. | |
261 [PermissionBubbleController alignCenterOf:menu | |
262 verticallyToCenterOf:permissionView]; | |
263 [permissionMenus addObject:menu]; | |
264 [contentView addSubview:menu]; | |
265 } | |
198 yOffset += NSHeight([permissionView frame]); | 266 yOffset += NSHeight([permissionView frame]); |
199 } | 267 } |
200 | 268 |
201 // The maximum width of the above permissions will dictate the width of the | 269 // The maximum width of the above permissions will dictate the width of the |
202 // bubble. It is calculated here so that it can be used for the positioning | 270 // bubble. It is calculated here so that it can be used for the positioning |
203 // of the buttons. | 271 // of the buttons. |
204 NSRect bubbleFrame = NSZeroRect; | 272 NSRect bubbleFrame = NSZeroRect; |
205 for (NSView* view in [contentView subviews]) { | 273 for (NSView* view in [contentView subviews]) { |
206 bubbleFrame = NSUnionRect( | 274 bubbleFrame = NSUnionRect( |
207 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); | 275 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); |
208 } | 276 } |
209 | 277 |
278 if (customizationMode) { | |
279 // Adjust the horizontal origin for each menu. | |
280 CGFloat xOffset = NSWidth(bubbleFrame) - kHorizontalPadding; | |
281 CGFloat maxMenuWidth = 0; | |
282 for (NSView* view in permissionMenus.get()) { | |
283 [view setFrameOrigin:NSMakePoint(xOffset, NSMinY([view frame]))]; | |
284 maxMenuWidth = std::max(maxMenuWidth, NSWidth([view frame])); | |
285 } | |
286 // And add the menu width to the bubble's width. | |
287 bubbleFrame.size.width += maxMenuWidth; | |
288 } | |
289 | |
210 base::scoped_nsobject<NSView> titleView( | 290 base::scoped_nsobject<NSView> titleView( |
211 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] | 291 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] |
212 retain]); | 292 retain]); |
213 [contentView addSubview:titleView]; | 293 [contentView addSubview:titleView]; |
214 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, | 294 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, |
215 kVerticalPadding + yOffset)]; | 295 kVerticalPadding + yOffset)]; |
216 yOffset += NSHeight([titleView frame]) + kVerticalPadding; | 296 yOffset += NSHeight([titleView frame]) + kVerticalPadding; |
217 | 297 |
218 // The title must fit within the bubble. | 298 // The title must fit within the bubble. |
219 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), | 299 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), |
(...skipping 15 matching lines...) Expand all Loading... | |
235 kHorizontalPadding; | 315 kHorizontalPadding; |
236 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 316 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
237 [contentView addSubview:allowOrOkButton]; | 317 [contentView addSubview:allowOrOkButton]; |
238 | 318 |
239 if (!customizationMode) { | 319 if (!customizationMode) { |
240 base::scoped_nsobject<NSView> blockButton; | 320 base::scoped_nsobject<NSView> blockButton; |
241 if (singlePermission) | 321 if (singlePermission) |
242 blockButton.reset([[self blockButton] retain]); | 322 blockButton.reset([[self blockButton] retain]); |
243 else | 323 else |
244 blockButton.reset([[self blockButtonWithCustomizeMenu] retain]); | 324 blockButton.reset([[self blockButtonWithCustomizeMenu] retain]); |
245 CGFloat width = [self matchWidthsOf:blockButton andOf:allowOrOkButton]; | 325 CGFloat width = [PermissionBubbleController matchWidthsOf:blockButton |
326 andOf:allowOrOkButton]; | |
246 // Ensure the allow/ok button is still in the correct position. | 327 // Ensure the allow/ok button is still in the correct position. |
247 xOrigin = NSWidth(bubbleFrame) - width - kHorizontalPadding; | 328 xOrigin = NSWidth(bubbleFrame) - width - kHorizontalPadding; |
248 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 329 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
249 // Line up the block button. | 330 // Line up the block button. |
250 xOrigin = NSMinX([allowOrOkButton frame]) - width - kButtonPadding; | 331 xOrigin = NSMinX([allowOrOkButton frame]) - width - kButtonPadding; |
251 [blockButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 332 [blockButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
252 [contentView addSubview:blockButton]; | 333 [contentView addSubview:blockButton]; |
253 } | 334 } |
254 | 335 |
255 bubbleFrame.size.height = yOffset + kVerticalPadding; | 336 bubbleFrame.size.height = yOffset + kVerticalPadding; |
(...skipping 27 matching lines...) Expand all Loading... | |
283 [permissionIcon setFrameSize:[[permissionIcon image] size]]; | 364 [permissionIcon setFrameSize:[[permissionIcon image] size]]; |
284 [permissionView addSubview:permissionIcon]; | 365 [permissionView addSubview:permissionIcon]; |
285 | 366 |
286 base::scoped_nsobject<NSTextField> permissionLabel( | 367 base::scoped_nsobject<NSTextField> permissionLabel( |
287 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 368 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
288 base::string16 label = request->GetMessageTextFragment(); | 369 base::string16 label = request->GetMessageTextFragment(); |
289 [permissionLabel setDrawsBackground:NO]; | 370 [permissionLabel setDrawsBackground:NO]; |
290 [permissionLabel setBezeled:NO]; | 371 [permissionLabel setBezeled:NO]; |
291 [permissionLabel setEditable:NO]; | 372 [permissionLabel setEditable:NO]; |
292 [permissionLabel setSelectable:NO]; | 373 [permissionLabel setSelectable:NO]; |
374 [permissionLabel setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | |
293 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; | 375 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; |
294 [permissionLabel sizeToFit]; | 376 [permissionLabel sizeToFit]; |
295 [permissionLabel setFrameOrigin: | 377 [permissionLabel setFrameOrigin: |
296 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; | 378 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; |
297 [permissionView addSubview:permissionLabel]; | 379 [permissionView addSubview:permissionLabel]; |
298 | 380 |
299 // Match the horizontal centers of the two subviews. Note that the label's | 381 // Match the horizontal centers of the two subviews. Note that the label's |
300 // center is rounded down, and the icon's center, up. It looks better that | 382 // center is rounded down, and the icon's center, up. It looks better that |
301 // way - with the text's center slightly lower than the icon's center - if the | 383 // way - with the text's center slightly lower than the icon's center - if the |
302 // height delta is not evenly split. | 384 // height delta is not evenly split. |
(...skipping 16 matching lines...) Expand all Loading... | |
319 - (NSView*)titleWithHostname:(const std::string&)host { | 401 - (NSView*)titleWithHostname:(const std::string&)host { |
320 base::scoped_nsobject<NSTextField> titleView( | 402 base::scoped_nsobject<NSTextField> titleView( |
321 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 403 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
322 [titleView setDrawsBackground:NO]; | 404 [titleView setDrawsBackground:NO]; |
323 [titleView setBezeled:NO]; | 405 [titleView setBezeled:NO]; |
324 [titleView setEditable:NO]; | 406 [titleView setEditable:NO]; |
325 [titleView setSelectable:NO]; | 407 [titleView setSelectable:NO]; |
326 [titleView setStringValue: | 408 [titleView setStringValue: |
327 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, | 409 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, |
328 base::UTF8ToUTF16(host))]; | 410 base::UTF8ToUTF16(host))]; |
329 [titleView setFont:[NSFont systemFontOfSize:kFontSize]]; | 411 [titleView setFont:[NSFont systemFontOfSize:kTitleFontSize]]; |
330 [titleView sizeToFit]; | 412 [titleView sizeToFit]; |
331 NSRect titleFrame = [titleView frame]; | 413 NSRect titleFrame = [titleView frame]; |
332 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, | 414 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, |
333 NSHeight(titleFrame))]; | 415 NSHeight(titleFrame))]; |
334 return titleView.autorelease(); | 416 return titleView.autorelease(); |
335 } | 417 } |
336 | 418 |
337 - (NSView*)checkboxForRequest:(PermissionBubbleRequest*)request | 419 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request |
338 checked:(BOOL)checked { | 420 atIndex:(int)index |
421 allow:(BOOL)allow { | |
339 DCHECK(request); | 422 DCHECK(request); |
340 base::scoped_nsobject<NSButton> checkbox( | 423 DCHECK(delegate_); |
341 [[NSButton alloc] initWithFrame:NSZeroRect]); | 424 base::scoped_nsobject<AllowBlockMenuButton> button( |
342 [checkbox setButtonType:NSSwitchButton]; | 425 [[AllowBlockMenuButton alloc] initForURL:request->GetRequestingHostname() |
343 base::string16 permission = request->GetMessageTextFragment(); | 426 allowed:allow |
344 [checkbox setTitle:base::SysUTF16ToNSString(permission)]; | 427 index:index |
345 [checkbox setState:(checked ? NSOnState : NSOffState)]; | 428 delegate:delegate_]); |
346 [checkbox setTarget:self]; | 429 return button.autorelease(); |
347 [checkbox setAction:@selector(onCheckboxChanged:)]; | |
348 [checkbox sizeToFit]; | |
349 [checkbox setFrameOrigin:NSMakePoint(0, kCheckboxYAdjustment)]; | |
350 return checkbox.autorelease(); | |
351 } | 430 } |
352 | 431 |
353 - (NSView*)buttonWithTitle:(NSString*)title | 432 - (NSView*)buttonWithTitle:(NSString*)title |
354 action:(SEL)action { | 433 action:(SEL)action { |
355 base::scoped_nsobject<NSButton> button( | 434 base::scoped_nsobject<NSButton> button( |
356 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); | 435 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); |
357 [button setButtonType:NSMomentaryPushInButton]; | 436 [button setButtonType:NSMomentaryPushInButton]; |
358 [button setTitle:title]; | 437 [button setTitle:title]; |
359 [button setTarget:self]; | 438 [button setTarget:self]; |
360 [button setAction:action]; | 439 [button setAction:action]; |
(...skipping 21 matching lines...) Expand all Loading... | |
382 - (NSView*)closeButton { | 461 - (NSView*)closeButton { |
383 int dimension = chrome_style::GetCloseButtonSize(); | 462 int dimension = chrome_style::GetCloseButtonSize(); |
384 NSRect frame = NSMakeRect(0, 0, dimension, dimension); | 463 NSRect frame = NSMakeRect(0, 0, dimension, dimension); |
385 base::scoped_nsobject<NSButton> button( | 464 base::scoped_nsobject<NSButton> button( |
386 [[WebUIHoverCloseButton alloc] initWithFrame:frame]); | 465 [[WebUIHoverCloseButton alloc] initWithFrame:frame]); |
387 [button setAction:@selector(onClose:)]; | 466 [button setAction:@selector(onClose:)]; |
388 [button setTarget:self]; | 467 [button setTarget:self]; |
389 return button.autorelease(); | 468 return button.autorelease(); |
390 } | 469 } |
391 | 470 |
392 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { | |
393 NSRect frameA = [viewA frame]; | |
394 NSRect frameB = [viewB frame]; | |
395 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); | |
396 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; | |
397 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; | |
398 return width; | |
399 } | |
400 | |
401 - (void)ok:(id)sender { | 471 - (void)ok:(id)sender { |
402 DCHECK(delegate_); | 472 DCHECK(delegate_); |
403 delegate_->Closing(); | 473 delegate_->Closing(); |
404 } | 474 } |
405 | 475 |
406 - (void)onAllow:(id)sender { | 476 - (void)onAllow:(id)sender { |
407 DCHECK(delegate_); | 477 DCHECK(delegate_); |
408 delegate_->Accept(); | 478 delegate_->Accept(); |
409 } | 479 } |
410 | 480 |
411 - (void)onBlock:(id)sender { | 481 - (void)onBlock:(id)sender { |
412 DCHECK(delegate_); | 482 DCHECK(delegate_); |
413 delegate_->Deny(); | 483 delegate_->Deny(); |
414 } | 484 } |
415 | 485 |
416 - (void)onClose:(id)sender { | 486 - (void)onClose:(id)sender { |
417 DCHECK(delegate_); | 487 DCHECK(delegate_); |
418 delegate_->Closing(); | 488 delegate_->Closing(); |
419 } | 489 } |
420 | 490 |
421 - (void)onCustomize:(id)sender { | 491 - (void)onCustomize:(id)sender { |
422 DCHECK(delegate_); | 492 DCHECK(delegate_); |
423 delegate_->SetCustomizationMode(); | 493 delegate_->SetCustomizationMode(); |
424 } | 494 } |
425 | 495 |
426 - (void)onCheckboxChanged:(id)sender { | |
427 DCHECK(delegate_); | |
428 NSButton* checkbox = base::mac::ObjCCastStrict<NSButton>(sender); | |
429 delegate_->ToggleAccept([checkbox tag], [checkbox state] == NSOnState); | |
430 } | |
431 | |
432 - (void)onMenuItemClicked:(int)commandId { | 496 - (void)onMenuItemClicked:(int)commandId { |
433 DCHECK(commandId == 0); | 497 DCHECK(commandId == 0); |
434 [self onCustomize:nil]; | 498 [self onCustomize:nil]; |
435 } | 499 } |
436 | 500 |
501 + (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { | |
502 NSRect frameA = [viewA frame]; | |
503 NSRect frameB = [viewB frame]; | |
504 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); | |
505 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; | |
506 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; | |
507 return width; | |
508 } | |
509 | |
510 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { | |
511 NSRect frameA = [viewA frame]; | |
512 NSRect frameB = [viewB frame]; | |
513 frameA.origin.y = | |
514 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); | |
515 [viewA setFrameOrigin:frameA.origin]; | |
516 } | |
517 | |
437 @end // implementation PermissionBubbleController | 518 @end // implementation PermissionBubbleController |
OLD | NEW |