Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm

Issue 242443005: Changes cocoa implementation of permission bubble to better match mocks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698