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; | |
43 | 48 |
44 const CGFloat kFontSize = 15.0f; | |
45 class MenuDelegate : public ui::SimpleMenuModel::Delegate { | 49 class MenuDelegate : public ui::SimpleMenuModel::Delegate { |
46 public: | 50 public: |
47 explicit MenuDelegate(PermissionBubbleController* bubble) | 51 explicit MenuDelegate(PermissionBubbleController* bubble) |
48 : bubble_controller_(bubble) {} | 52 : bubble_controller_(bubble) {} |
49 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { | 53 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { |
50 return false; | 54 return false; |
51 } | 55 } |
52 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { | 56 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { |
53 // TODO(leng): Change this to true once setting the bubble to be | 57 return true; |
54 // customizable works properly. Ideally, the bubble will alter its | |
55 // contents, rather than reshowing completely. | |
56 return false; | |
57 } | 58 } |
58 virtual bool GetAcceleratorForCommandId( | 59 virtual bool GetAcceleratorForCommandId( |
59 int command_id, | 60 int command_id, |
60 ui::Accelerator* accelerator) OVERRIDE { | 61 ui::Accelerator* accelerator) OVERRIDE { |
61 return false; | 62 return false; |
62 } | 63 } |
63 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE { | 64 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE { |
64 [bubble_controller_ onMenuItemClicked:command_id]; | 65 [bubble_controller_ onMenuItemClicked:command_id]; |
65 } | 66 } |
66 private: | 67 private: |
67 PermissionBubbleController* bubble_controller_; // Weak, owns us. | 68 PermissionBubbleController* bubble_controller_; // Weak, owns us. |
68 DISALLOW_COPY_AND_ASSIGN(MenuDelegate); | 69 DISALLOW_COPY_AND_ASSIGN(MenuDelegate); |
69 }; | 70 }; |
70 | 71 |
71 } // namespace | 72 } // namespace |
72 | 73 |
74 // NSPopUpButton with a menu containing two items: allow and block. | |
75 // One AllowBlockMenuButton is used for each requested permission, but only when | |
76 // the permission bubble is in 'customize' mode. | |
77 @interface AllowBlockMenuButton : NSPopUpButton { | |
78 @private | |
79 int index_; | |
80 scoped_ptr<PermissionMenuModel> menuModel_; | |
81 base::scoped_nsobject<MenuController> menuController_; | |
82 } | |
83 | |
84 - (id)initWithIndex:(int)index | |
85 forURL:(const GURL&)url | |
86 allowed:(BOOL)allow | |
87 withCallback:(void (^)(int, bool))callback; | |
88 @end | |
89 | |
90 @implementation AllowBlockMenuButton | |
91 | |
92 - (id)initWithIndex:(int)index | |
93 forURL:(const GURL&)url | |
94 allowed:(BOOL)allow | |
95 withCallback:(void (^)(int, bool))callback { | |
96 if (self = [super initWithFrame:NSMakeRect(0, 0, 1, 1) pullsDown:NO]) { | |
97 index_ = index; | |
98 ContentSetting setting = | |
99 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | |
100 [self setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | |
101 [self setBordered:NO]; | |
102 | |
103 PermissionMenuModel::ChangeCallback changeCallback = | |
104 base::BindBlock(^(const WebsiteSettingsUI::PermissionInfo& permission) { | |
105 callback(index_, permission.setting == CONTENT_SETTING_ALLOW); | |
106 }); | |
107 | |
108 menuModel_.reset(new PermissionMenuModel(url, setting, changeCallback)); | |
109 menuController_.reset([[MenuController alloc] initWithModel:menuModel_.get() | |
110 useWithPopUpButtonCell:NO]); | |
111 [self setMenu:[menuController_ menu]]; | |
112 [[self cell] selectItemAtIndex:menuModel_->GetIndexOfCommandId(setting)]; | |
groby-ooo-7-16
2014/04/18 18:18:18
I don't think you need the cell for selectItemAtIn
leng
2014/04/18 22:48:46
The first time I tried, it didn't work. Must've h
| |
113 [self sizeToFit]; | |
114 // Adjust the size to fit the current title. Using only -sizeToFit leaves | |
115 // an ugly amount of whitespace between the title and the arrows. | |
116 [self setFrameSize:[PermissionSelectorButton sizeForTitle:[self title] | |
groby-ooo-7-16
2014/04/18 18:18:18
I'm not happy with the tight coupling between the
leng
2014/04/18 22:48:46
As per our conversation offline, I'll make a follo
| |
117 forButton:self]]; | |
118 } | |
119 return self; | |
120 } | |
121 | |
122 // Getter for testing | |
123 - (int)index { | |
124 return index_; | |
125 } | |
126 | |
127 @end | |
128 | |
73 @interface PermissionBubbleController () | 129 @interface PermissionBubbleController () |
74 | 130 |
75 // Returns an autoreleased NSView displaying the icon and label for |request|. | 131 // Returns an autoreleased NSView displaying the icon and label for |request|. |
76 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request; | 132 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request; |
77 | 133 |
78 // Returns an autoreleased NSView displaying the title for the bubble | 134 // Returns an autoreleased NSView displaying the title for the bubble |
79 // requesting settings for |host|. | 135 // requesting settings for |host|. |
80 - (NSView*)titleWithHostname:(const std::string&)host; | 136 - (NSView*)titleWithHostname:(const std::string&)host; |
81 | 137 |
82 // Returns an autoreleased NSView displaying a checkbox for |request|. The | 138 // Returns an autoreleased NSView displaying a menu for |request|. The |
83 // checkbox will be initialized as checked if |checked| is YES. | 139 // menu will be initialized as 'allow' if |allow| is YES. |
84 - (NSView*)checkboxForRequest:(PermissionBubbleRequest*)request | 140 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request |
groby-ooo-7-16
2014/04/18 18:18:18
menuViewForRequest?
leng
2014/04/18 22:48:46
Would you like me to change the other names, as we
| |
85 checked:(BOOL)checked; | 141 atIndex:(int)index |
142 allow:(BOOL)allow; | |
86 | 143 |
87 // Returns an autoreleased NSView of a button with |title| and |action|. | 144 // Returns an autoreleased NSView of a button with |title| and |action|. |
88 - (NSView*)buttonWithTitle:(NSString*)title | 145 - (NSView*)buttonWithTitle:(NSString*)title |
89 action:(SEL)action; | 146 action:(SEL)action; |
90 | 147 |
91 // Returns an autoreleased NSView displaying a block button. | 148 // Returns an autoreleased NSView displaying a block button. |
92 - (NSView*)blockButton; | 149 - (NSView*)blockButton; |
93 | 150 |
94 // Returns an autoreleased NSView with a block button and a drop-down menu | 151 // 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. | 152 // with one item, which will change the UI to allow customizing the permissions. |
96 - (NSView*)blockButtonWithCustomizeMenu; | 153 - (NSView*)blockButtonWithCustomizeMenu; |
97 | 154 |
98 // Returns an autoreleased NSView displaying the close 'x' button. | 155 // Returns an autoreleased NSView displaying the close 'x' button. |
99 - (NSView*)closeButton; | 156 - (NSView*)closeButton; |
100 | 157 |
101 // Sets the width of both |viewA| and |viewB| to be the larger of the | 158 // 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. | 159 // two views' widths. Does not change either view's origin or height. |
103 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB; | 160 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB; |
104 | 161 |
162 // Sets the offset of |viewA| so that its vertical center is aligned with the | |
163 // vertical center of |viewB|. | |
164 - (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB; | |
groby-ooo-7-16
2014/04/18 18:18:18
I'd probably do that as a standalone function, bec
leng
2014/04/18 22:48:46
Done.
| |
165 | |
105 // Called when the 'ok' button is pressed. | 166 // Called when the 'ok' button is pressed. |
106 - (void)ok:(id)sender; | 167 - (void)ok:(id)sender; |
107 | 168 |
108 // Called when the 'allow' button is pressed. | 169 // Called when the 'allow' button is pressed. |
109 - (void)onAllow:(id)sender; | 170 - (void)onAllow:(id)sender; |
110 | 171 |
111 // Called when the 'block' button is pressed. | 172 // Called when the 'block' button is pressed. |
112 - (void)onBlock:(id)sender; | 173 - (void)onBlock:(id)sender; |
113 | 174 |
114 // Called when the 'close' button is pressed. | 175 // Called when the 'close' button is pressed. |
115 - (void)onClose:(id)sender; | 176 - (void)onClose:(id)sender; |
116 | 177 |
117 // Called when the 'customize' button is pressed. | 178 // Called when the 'customize' button is pressed. |
118 - (void)onCustomize:(id)sender; | 179 - (void)onCustomize:(id)sender; |
119 | 180 |
120 // Called when a checkbox changes from checked to unchecked, or vice versa. | |
121 - (void)onCheckboxChanged:(id)sender; | |
122 | |
123 @end | 181 @end |
124 | 182 |
125 @implementation PermissionBubbleController | 183 @implementation PermissionBubbleController |
126 | 184 |
127 - (id)initWithParentWindow:(NSWindow*)parentWindow | 185 - (id)initWithParentWindow:(NSWindow*)parentWindow |
128 bridge:(PermissionBubbleCocoa*)bridge { | 186 bridge:(PermissionBubbleCocoa*)bridge { |
129 DCHECK(parentWindow); | 187 DCHECK(parentWindow); |
130 DCHECK(bridge); | 188 DCHECK(bridge); |
131 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] | 189 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] |
132 initWithContentRect:ui::kWindowSizeDeterminedLater | 190 initWithContentRect:ui::kWindowSizeDeterminedLater |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
169 allowOrOkButton.reset([[self buttonWithTitle:okTitle | 227 allowOrOkButton.reset([[self buttonWithTitle:okTitle |
170 action:@selector(ok:)] retain]); | 228 action:@selector(ok:)] retain]); |
171 } else { | 229 } else { |
172 NSString* allowTitle = l10n_util::GetNSString(IDS_PERMISSION_ALLOW); | 230 NSString* allowTitle = l10n_util::GetNSString(IDS_PERMISSION_ALLOW); |
173 allowOrOkButton.reset([[self buttonWithTitle:allowTitle | 231 allowOrOkButton.reset([[self buttonWithTitle:allowTitle |
174 action:@selector(onAllow:)] retain]); | 232 action:@selector(onAllow:)] retain]); |
175 } | 233 } |
176 CGFloat yOffset = 2 * kVerticalPadding + NSMaxY([allowOrOkButton frame]); | 234 CGFloat yOffset = 2 * kVerticalPadding + NSMaxY([allowOrOkButton frame]); |
177 BOOL singlePermission = requests.size() == 1; | 235 BOOL singlePermission = requests.size() == 1; |
178 | 236 |
179 checkboxes_.reset(customizationMode ? [[NSMutableArray alloc] init] : nil); | 237 base::scoped_nsobject<NSMutableArray> permissionMenus; |
238 if (customizationMode) | |
239 permissionMenus.reset([[NSMutableArray alloc] init]); | |
240 | |
180 for (auto it = requests.begin(); it != requests.end(); it++) { | 241 for (auto it = requests.begin(); it != requests.end(); it++) { |
181 base::scoped_nsobject<NSView> permissionView; | 242 base::scoped_nsobject<NSView> permissionView( |
182 if (customizationMode) { | 243 [[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; | 244 NSPoint origin = [permissionView frame].origin; |
193 origin.x += kHorizontalPadding; | 245 origin.x += kHorizontalPadding; |
194 origin.y += yOffset; | 246 origin.y += yOffset; |
195 [permissionView setFrameOrigin:origin]; | 247 [permissionView setFrameOrigin:origin]; |
196 [contentView addSubview:permissionView]; | 248 [contentView addSubview:permissionView]; |
197 | 249 |
250 if (customizationMode) { | |
251 int index = it - requests.begin(); | |
252 base::scoped_nsobject<NSView> menu( | |
253 [[self menuForRequest:(*it) | |
254 atIndex:index | |
255 allow:acceptStates[index] ? YES : NO] retain]); | |
256 // Align vertically. Horizontal alignment will be adjusted once the | |
257 // widest permission is know. | |
258 [self alignCenterOf:menu verticallyToCenterOf:permissionView]; | |
259 [permissionMenus addObject:menu]; | |
260 [contentView addSubview:menu]; | |
261 } | |
198 yOffset += NSHeight([permissionView frame]); | 262 yOffset += NSHeight([permissionView frame]); |
199 } | 263 } |
200 | 264 |
201 // The maximum width of the above permissions will dictate the width of the | 265 // 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 | 266 // bubble. It is calculated here so that it can be used for the positioning |
203 // of the buttons. | 267 // of the buttons. |
204 NSRect bubbleFrame = NSZeroRect; | 268 NSRect bubbleFrame = NSZeroRect; |
205 for (NSView* view in [contentView subviews]) { | 269 for (NSView* view in [contentView subviews]) { |
206 bubbleFrame = NSUnionRect( | 270 bubbleFrame = NSUnionRect( |
207 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); | 271 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); |
208 } | 272 } |
209 | 273 |
274 if (customizationMode) { | |
275 // Adjust the horizontal origin for each menu. | |
276 CGFloat xOffset = NSWidth(bubbleFrame) - kHorizontalPadding; | |
277 for (NSView* view in permissionMenus.get()) { | |
278 [view setFrameOrigin:NSMakePoint(xOffset, NSMinY([view frame]))]; | |
279 } | |
280 // And add the menu width to the bubble's width. | |
281 NSView* menu = base::mac::ObjCCast<NSView>(permissionMenus[0]); | |
groby-ooo-7-16
2014/04/18 18:18:18
Menu 0 is OK? We don't have varying sizes?
Also:
leng
2014/04/18 22:48:46
Changed to use a max width.
The NSUnionRect, above
| |
282 bubbleFrame.size.width += NSWidth([menu frame]); | |
283 } | |
284 | |
210 base::scoped_nsobject<NSView> titleView( | 285 base::scoped_nsobject<NSView> titleView( |
211 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] | 286 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] |
212 retain]); | 287 retain]); |
213 [contentView addSubview:titleView]; | 288 [contentView addSubview:titleView]; |
214 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, | 289 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, |
215 kVerticalPadding + yOffset)]; | 290 kVerticalPadding + yOffset)]; |
216 yOffset += NSHeight([titleView frame]) + kVerticalPadding; | 291 yOffset += NSHeight([titleView frame]) + kVerticalPadding; |
217 | 292 |
218 // The title must fit within the bubble. | 293 // The title must fit within the bubble. |
219 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), | 294 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 [permissionIcon setFrameSize:[[permissionIcon image] size]]; | 358 [permissionIcon setFrameSize:[[permissionIcon image] size]]; |
284 [permissionView addSubview:permissionIcon]; | 359 [permissionView addSubview:permissionIcon]; |
285 | 360 |
286 base::scoped_nsobject<NSTextField> permissionLabel( | 361 base::scoped_nsobject<NSTextField> permissionLabel( |
287 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 362 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
288 base::string16 label = request->GetMessageTextFragment(); | 363 base::string16 label = request->GetMessageTextFragment(); |
289 [permissionLabel setDrawsBackground:NO]; | 364 [permissionLabel setDrawsBackground:NO]; |
290 [permissionLabel setBezeled:NO]; | 365 [permissionLabel setBezeled:NO]; |
291 [permissionLabel setEditable:NO]; | 366 [permissionLabel setEditable:NO]; |
292 [permissionLabel setSelectable:NO]; | 367 [permissionLabel setSelectable:NO]; |
368 [permissionLabel setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | |
293 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; | 369 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; |
294 [permissionLabel sizeToFit]; | 370 [permissionLabel sizeToFit]; |
295 [permissionLabel setFrameOrigin: | 371 [permissionLabel setFrameOrigin: |
296 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; | 372 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; |
297 [permissionView addSubview:permissionLabel]; | 373 [permissionView addSubview:permissionLabel]; |
298 | 374 |
299 // Match the horizontal centers of the two subviews. Note that the label's | 375 // 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 | 376 // 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 | 377 // way - with the text's center slightly lower than the icon's center - if the |
302 // height delta is not evenly split. | 378 // height delta is not evenly split. |
(...skipping 16 matching lines...) Expand all Loading... | |
319 - (NSView*)titleWithHostname:(const std::string&)host { | 395 - (NSView*)titleWithHostname:(const std::string&)host { |
320 base::scoped_nsobject<NSTextField> titleView( | 396 base::scoped_nsobject<NSTextField> titleView( |
321 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 397 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
322 [titleView setDrawsBackground:NO]; | 398 [titleView setDrawsBackground:NO]; |
323 [titleView setBezeled:NO]; | 399 [titleView setBezeled:NO]; |
324 [titleView setEditable:NO]; | 400 [titleView setEditable:NO]; |
325 [titleView setSelectable:NO]; | 401 [titleView setSelectable:NO]; |
326 [titleView setStringValue: | 402 [titleView setStringValue: |
327 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, | 403 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, |
328 base::UTF8ToUTF16(host))]; | 404 base::UTF8ToUTF16(host))]; |
329 [titleView setFont:[NSFont systemFontOfSize:kFontSize]]; | 405 [titleView setFont:[NSFont systemFontOfSize:kTitleFontSize]]; |
330 [titleView sizeToFit]; | 406 [titleView sizeToFit]; |
331 NSRect titleFrame = [titleView frame]; | 407 NSRect titleFrame = [titleView frame]; |
332 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, | 408 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, |
333 NSHeight(titleFrame))]; | 409 NSHeight(titleFrame))]; |
334 return titleView.autorelease(); | 410 return titleView.autorelease(); |
335 } | 411 } |
336 | 412 |
337 - (NSView*)checkboxForRequest:(PermissionBubbleRequest*)request | 413 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request |
338 checked:(BOOL)checked { | 414 atIndex:(int)index |
415 allow:(BOOL)allow { | |
339 DCHECK(request); | 416 DCHECK(request); |
340 base::scoped_nsobject<NSButton> checkbox( | 417 DCHECK(delegate_); |
341 [[NSButton alloc] initWithFrame:NSZeroRect]); | 418 PermissionBubbleView::Delegate* blockDelegate = delegate_; |
342 [checkbox setButtonType:NSSwitchButton]; | 419 base::scoped_nsobject<AllowBlockMenuButton> button( |
343 base::string16 permission = request->GetMessageTextFragment(); | 420 [[AllowBlockMenuButton alloc] |
344 [checkbox setTitle:base::SysUTF16ToNSString(permission)]; | 421 initWithIndex:index |
345 [checkbox setState:(checked ? NSOnState : NSOffState)]; | 422 forURL:request->GetRequestingHostname() |
346 [checkbox setTarget:self]; | 423 allowed:allow |
347 [checkbox setAction:@selector(onCheckboxChanged:)]; | 424 withCallback:^(int index, bool allow) { |
groby-ooo-7-16
2014/04/18 18:18:18
Why not just pass down the blockDelegate and save
leng
2014/04/18 22:48:46
Good idea. Done. I did the simplest version, whi
| |
348 [checkbox sizeToFit]; | 425 blockDelegate->ToggleAccept(index, allow); |
349 [checkbox setFrameOrigin:NSMakePoint(0, kCheckboxYAdjustment)]; | 426 }]); |
350 return checkbox.autorelease(); | 427 return button.autorelease(); |
351 } | 428 } |
352 | 429 |
353 - (NSView*)buttonWithTitle:(NSString*)title | 430 - (NSView*)buttonWithTitle:(NSString*)title |
354 action:(SEL)action { | 431 action:(SEL)action { |
355 base::scoped_nsobject<NSButton> button( | 432 base::scoped_nsobject<NSButton> button( |
356 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); | 433 [[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]); |
357 [button setButtonType:NSMomentaryPushInButton]; | 434 [button setButtonType:NSMomentaryPushInButton]; |
358 [button setTitle:title]; | 435 [button setTitle:title]; |
359 [button setTarget:self]; | 436 [button setTarget:self]; |
360 [button setAction:action]; | 437 [button setAction:action]; |
(...skipping 30 matching lines...) Expand all Loading... | |
391 | 468 |
392 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { | 469 - (CGFloat)matchWidthsOf:(NSView*)viewA andOf:(NSView*)viewB { |
393 NSRect frameA = [viewA frame]; | 470 NSRect frameA = [viewA frame]; |
394 NSRect frameB = [viewB frame]; | 471 NSRect frameB = [viewB frame]; |
395 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); | 472 CGFloat width = std::max(NSWidth(frameA), NSWidth(frameB)); |
396 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; | 473 [viewA setFrameSize:NSMakeSize(width, NSHeight(frameA))]; |
397 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; | 474 [viewB setFrameSize:NSMakeSize(width, NSHeight(frameB))]; |
398 return width; | 475 return width; |
399 } | 476 } |
400 | 477 |
478 - (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { | |
groby-ooo-7-16
2014/04/18 18:18:18
Grumble. I wish we had helper functions for this.
leng
2014/04/18 22:48:46
Me, too.
| |
479 NSRect frameA = [viewA frame]; | |
480 NSRect frameB = [viewB frame]; | |
481 frameA.origin.y = | |
482 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); | |
483 [viewA setFrameOrigin:frameA.origin]; | |
484 } | |
485 | |
401 - (void)ok:(id)sender { | 486 - (void)ok:(id)sender { |
402 DCHECK(delegate_); | 487 DCHECK(delegate_); |
403 delegate_->Closing(); | 488 delegate_->Closing(); |
404 } | 489 } |
405 | 490 |
406 - (void)onAllow:(id)sender { | 491 - (void)onAllow:(id)sender { |
407 DCHECK(delegate_); | 492 DCHECK(delegate_); |
408 delegate_->Accept(); | 493 delegate_->Accept(); |
409 } | 494 } |
410 | 495 |
411 - (void)onBlock:(id)sender { | 496 - (void)onBlock:(id)sender { |
412 DCHECK(delegate_); | 497 DCHECK(delegate_); |
413 delegate_->Deny(); | 498 delegate_->Deny(); |
414 } | 499 } |
415 | 500 |
416 - (void)onClose:(id)sender { | 501 - (void)onClose:(id)sender { |
417 DCHECK(delegate_); | 502 DCHECK(delegate_); |
418 delegate_->Closing(); | 503 delegate_->Closing(); |
419 } | 504 } |
420 | 505 |
421 - (void)onCustomize:(id)sender { | 506 - (void)onCustomize:(id)sender { |
422 DCHECK(delegate_); | 507 DCHECK(delegate_); |
423 delegate_->SetCustomizationMode(); | 508 delegate_->SetCustomizationMode(); |
424 } | 509 } |
425 | 510 |
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 { | 511 - (void)onMenuItemClicked:(int)commandId { |
433 DCHECK(commandId == 0); | 512 DCHECK(commandId == 0); |
434 [self onCustomize:nil]; | 513 [self onCustomize:nil]; |
435 } | 514 } |
436 | 515 |
437 @end // implementation PermissionBubbleController | 516 @end // implementation PermissionBubbleController |
OLD | NEW |