Chromium Code Reviews| 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 |