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/bind_objc_block.h" |
| 10 #include "base/mac/foundation_util.h" | 10 #include "base/mac/foundation_util.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 #import "ui/base/cocoa/menu_controller.h" | 35 #import "ui/base/cocoa/menu_controller.h" |
| 36 #include "ui/base/cocoa/window_size_constants.h" | 36 #include "ui/base/cocoa/window_size_constants.h" |
| 37 #import "ui/base/cocoa/menu_controller.h" | 37 #import "ui/base/cocoa/menu_controller.h" |
| 38 #include "ui/base/l10n/l10n_util_mac.h" | 38 #include "ui/base/l10n/l10n_util_mac.h" |
| 39 #include "ui/base/models/simple_menu_model.h" | 39 #include "ui/base/models/simple_menu_model.h" |
| 40 | 40 |
| 41 using base::UserMetricsAction; | 41 using base::UserMetricsAction; |
| 42 | 42 |
| 43 namespace { | 43 namespace { |
| 44 | 44 |
| 45 const CGFloat kHorizontalPadding = 20.0f; | 45 const CGFloat kHorizontalPadding = 13.0f; |
| 46 const CGFloat kVerticalPadding = 20.0f; | 46 const CGFloat kVerticalPadding = 13.0f; |
| 47 const CGFloat kButtonPadding = 10.0f; | 47 const CGFloat kBetweenButtonsPadding = 10.0f; |
| 48 const CGFloat kButtonRightEdgePadding = 17.0f; | |
| 48 const CGFloat kTitlePaddingX = 50.0f; | 49 const CGFloat kTitlePaddingX = 50.0f; |
| 49 const CGFloat kTitleFontSize = 15.0f; | 50 const CGFloat kBubbleMinWidth = 315.0f; |
| 50 const CGFloat kPermissionFontSize = 12.0f; | 51 const NSSize kPermissionIconSize = {18, 18}; |
|
groby-ooo-7-16
2014/05/21 18:28:37
General question: Are some of those constants shar
leng
2014/05/21 22:33:51
This one currently is not, but may be used by the
groby-ooo-7-16
2014/05/21 23:50:28
Let's not add another namespace. If there's no nat
| |
| 51 | 52 |
| 52 class MenuDelegate : public ui::SimpleMenuModel::Delegate { | 53 class MenuDelegate : public ui::SimpleMenuModel::Delegate { |
| 53 public: | 54 public: |
| 54 explicit MenuDelegate(PermissionBubbleController* bubble) | 55 explicit MenuDelegate(PermissionBubbleController* bubble) |
| 55 : bubble_controller_(bubble) {} | 56 : bubble_controller_(bubble) {} |
| 56 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { | 57 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE { |
| 57 return false; | 58 return false; |
| 58 } | 59 } |
| 59 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { | 60 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE { |
| 60 return true; | 61 return true; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 91 | 92 |
| 92 @implementation AllowBlockMenuButton | 93 @implementation AllowBlockMenuButton |
| 93 | 94 |
| 94 - (id)initForURL:(const GURL&)url | 95 - (id)initForURL:(const GURL&)url |
| 95 allowed:(BOOL)allow | 96 allowed:(BOOL)allow |
| 96 index:(int)index | 97 index:(int)index |
| 97 delegate:(PermissionBubbleView::Delegate*)delegate { | 98 delegate:(PermissionBubbleView::Delegate*)delegate { |
| 98 if (self = [super initWithFrame:NSZeroRect pullsDown:NO]) { | 99 if (self = [super initWithFrame:NSZeroRect pullsDown:NO]) { |
| 99 ContentSetting setting = | 100 ContentSetting setting = |
| 100 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; | 101 allow ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
| 101 [self setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | 102 [self setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 102 [self setBordered:NO]; | 103 [self setBordered:NO]; |
| 103 | 104 |
| 104 __block PermissionBubbleView::Delegate* blockDelegate = delegate; | 105 __block PermissionBubbleView::Delegate* blockDelegate = delegate; |
| 105 __block AllowBlockMenuButton* blockSelf = self; | 106 __block AllowBlockMenuButton* blockSelf = self; |
| 106 PermissionMenuModel::ChangeCallback changeCallback = | 107 PermissionMenuModel::ChangeCallback changeCallback = |
| 107 base::BindBlock(^(const WebsiteSettingsUI::PermissionInfo& permission) { | 108 base::BindBlock(^(const WebsiteSettingsUI::PermissionInfo& permission) { |
| 108 blockDelegate->ToggleAccept( | 109 blockDelegate->ToggleAccept( |
| 109 index, permission.setting == CONTENT_SETTING_ALLOW); | 110 index, permission.setting == CONTENT_SETTING_ALLOW); |
| 110 [blockSelf setFrameSize: | 111 [blockSelf setFrameSize: |
| 111 SizeForWebsiteSettingsButtonTitle(blockSelf, | 112 SizeForWebsiteSettingsButtonTitle(blockSelf, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 verticallyToCenterOf:permissionView]; | 281 verticallyToCenterOf:permissionView]; |
| 281 [permissionMenus addObject:menu]; | 282 [permissionMenus addObject:menu]; |
| 282 [contentView addSubview:menu]; | 283 [contentView addSubview:menu]; |
| 283 } | 284 } |
| 284 yOffset += NSHeight([permissionView frame]); | 285 yOffset += NSHeight([permissionView frame]); |
| 285 } | 286 } |
| 286 | 287 |
| 287 // The maximum width of the above permissions will dictate the width of the | 288 // The maximum width of the above permissions will dictate the width of the |
| 288 // bubble. It is calculated here so that it can be used for the positioning | 289 // bubble. It is calculated here so that it can be used for the positioning |
| 289 // of the buttons. | 290 // of the buttons. |
| 290 NSRect bubbleFrame = NSZeroRect; | 291 NSRect bubbleFrame = NSMakeRect(0, 0, kVerticalPadding, kBubbleMinWidth); |
| 291 for (NSView* view in [contentView subviews]) { | 292 for (NSView* view in [contentView subviews]) { |
| 292 bubbleFrame = NSUnionRect( | 293 bubbleFrame = NSUnionRect( |
| 293 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); | 294 bubbleFrame, NSInsetRect([view frame], -kHorizontalPadding, 0)); |
| 294 } | 295 } |
| 295 | 296 |
| 296 if (customizationMode) { | 297 if (customizationMode) { |
| 297 // Adjust the horizontal origin for each menu. | 298 // Adjust the horizontal origin for each menu. |
| 298 CGFloat xOffset = NSWidth(bubbleFrame) - kHorizontalPadding; | 299 CGFloat xOffset = NSWidth(bubbleFrame) - kHorizontalPadding; |
| 299 CGFloat maxMenuWidth = 0; | 300 CGFloat maxMenuWidth = 0; |
| 300 for (NSView* view in permissionMenus.get()) { | 301 for (NSView* view in permissionMenus.get()) { |
| 301 [view setFrameOrigin:NSMakePoint(xOffset, NSMinY([view frame]))]; | 302 [view setFrameOrigin:NSMakePoint(xOffset, NSMinY([view frame]))]; |
| 302 maxMenuWidth = std::max(maxMenuWidth, NSWidth([view frame])); | 303 maxMenuWidth = std::max(maxMenuWidth, NSWidth([view frame])); |
| 303 } | 304 } |
| 304 // And add the menu width to the bubble's width. | 305 // And add the menu width to the bubble's width. |
| 305 bubbleFrame.size.width += maxMenuWidth; | 306 bubbleFrame.size.width += maxMenuWidth; |
| 306 } | 307 } |
| 307 | 308 |
| 308 base::scoped_nsobject<NSView> titleView( | 309 base::scoped_nsobject<NSView> titleView( |
| 309 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] | 310 [[self titleWithHostname:requests[0]->GetRequestingHostname().host()] |
| 310 retain]); | 311 retain]); |
| 311 [contentView addSubview:titleView]; | 312 [contentView addSubview:titleView]; |
| 312 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, | 313 [titleView setFrameOrigin:NSMakePoint(kHorizontalPadding, |
| 313 kVerticalPadding + yOffset)]; | 314 kVerticalPadding + yOffset)]; |
| 314 yOffset += NSHeight([titleView frame]) + kVerticalPadding; | 315 |
| 316 // Fix the height of the bubble relative to the title. | |
| 317 bubbleFrame.size.height = NSMaxY([titleView frame]) + kVerticalPadding + | |
| 318 info_bubble::kBubbleArrowHeight; | |
| 315 | 319 |
| 316 // The title must fit within the bubble. | 320 // The title must fit within the bubble. |
| 317 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), | 321 bubbleFrame.size.width = std::max(NSWidth(bubbleFrame), |
| 318 NSWidth([titleView frame])); | 322 NSWidth([titleView frame])); |
| 319 | 323 |
| 320 // 'x' button in the upper-right-hand corner. | 324 // 'x' button in the upper-right-hand corner. |
| 321 base::scoped_nsobject<NSView> closeButton([[self closeButton] retain]); | 325 base::scoped_nsobject<NSView> closeButton([[self closeButton] retain]); |
| 326 CGFloat offsetFromTop = chrome_style::kCloseButtonPadding + | |
| 327 NSHeight([closeButton frame]) + | |
| 328 info_bubble::kBubbleArrowHeight; | |
| 322 // Place the close button at the rightmost edge of the bubble. | 329 // Place the close button at the rightmost edge of the bubble. |
| 323 [closeButton setFrameOrigin:NSMakePoint( | 330 [closeButton |
| 324 NSMaxX(bubbleFrame), yOffset - chrome_style::kCloseButtonPadding)]; | 331 setFrameOrigin:NSMakePoint(NSWidth(bubbleFrame), |
| 332 NSHeight(bubbleFrame) - offsetFromTop)]; | |
| 325 // Increase the size of the bubble by the width of the close button and its | 333 // Increase the size of the bubble by the width of the close button and its |
| 326 // padding. | 334 // padding. |
| 327 bubbleFrame.size.width += | 335 bubbleFrame.size.width += |
| 328 NSWidth([closeButton frame]) + chrome_style::kCloseButtonPadding; | 336 NSWidth([closeButton frame]) + chrome_style::kCloseButtonPadding; |
| 329 [contentView addSubview:closeButton]; | 337 [contentView addSubview:closeButton]; |
| 330 | 338 |
| 331 // Position the allow/ok button. | 339 // Position the allow/ok button. |
| 332 CGFloat xOrigin = NSWidth(bubbleFrame) - NSWidth([allowOrOkButton frame]) - | 340 CGFloat xOrigin = NSWidth(bubbleFrame) - NSWidth([allowOrOkButton frame]) - |
| 333 kHorizontalPadding; | 341 kButtonRightEdgePadding; |
| 334 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 342 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
| 335 [contentView addSubview:allowOrOkButton]; | 343 [contentView addSubview:allowOrOkButton]; |
| 336 | 344 |
| 337 if (!customizationMode) { | 345 if (!customizationMode) { |
| 338 base::scoped_nsobject<NSView> blockButton; | 346 base::scoped_nsobject<NSView> blockButton; |
| 339 if (singlePermission) | 347 if (singlePermission) |
| 340 blockButton.reset([[self blockButton] retain]); | 348 blockButton.reset([[self blockButton] retain]); |
| 341 else | 349 else |
| 342 blockButton.reset([[self blockButtonWithCustomizeMenu] retain]); | 350 blockButton.reset([[self blockButtonWithCustomizeMenu] retain]); |
| 343 CGFloat width = [PermissionBubbleController matchWidthsOf:blockButton | 351 CGFloat width = [PermissionBubbleController matchWidthsOf:blockButton |
| 344 andOf:allowOrOkButton]; | 352 andOf:allowOrOkButton]; |
| 345 // Ensure the allow/ok button is still in the correct position. | 353 // Ensure the allow/ok button is still in the correct position. |
| 346 xOrigin = NSWidth(bubbleFrame) - width - kHorizontalPadding; | 354 xOrigin = NSWidth(bubbleFrame) - width - kHorizontalPadding; |
| 347 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 355 [allowOrOkButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
| 348 // Line up the block button. | 356 // Line up the block button. |
| 349 xOrigin = NSMinX([allowOrOkButton frame]) - width - kButtonPadding; | 357 xOrigin = NSMinX([allowOrOkButton frame]) - width - kBetweenButtonsPadding; |
| 350 [blockButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; | 358 [blockButton setFrameOrigin:NSMakePoint(xOrigin, kVerticalPadding)]; |
| 351 [contentView addSubview:blockButton]; | 359 [contentView addSubview:blockButton]; |
| 352 } | 360 } |
| 353 | 361 |
| 354 bubbleFrame.size.height = yOffset + kVerticalPadding; | |
| 355 bubbleFrame = [[self window] frameRectForContentRect:bubbleFrame]; | 362 bubbleFrame = [[self window] frameRectForContentRect:bubbleFrame]; |
| 356 | |
| 357 if ([[self window] isVisible]) { | 363 if ([[self window] isVisible]) { |
| 358 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called | 364 // Unfortunately, calling -setFrame followed by -setFrameOrigin (called |
| 359 // within -setAnchorPoint) causes flickering. Avoid the flickering by | 365 // within -setAnchorPoint) causes flickering. Avoid the flickering by |
| 360 // manually adjusting the new frame's origin so that the top left stays the | 366 // manually adjusting the new frame's origin so that the top left stays the |
| 361 // same, and only calling -setFrame. | 367 // same, and only calling -setFrame. |
| 362 NSRect currentWindowFrame = [[self window] frame]; | 368 NSRect currentWindowFrame = [[self window] frame]; |
| 363 bubbleFrame.origin = currentWindowFrame.origin; | 369 bubbleFrame.origin = currentWindowFrame.origin; |
| 364 bubbleFrame.origin.y = bubbleFrame.origin.y + | 370 bubbleFrame.origin.y = bubbleFrame.origin.y + |
| 365 currentWindowFrame.size.height - bubbleFrame.size.height; | 371 currentWindowFrame.size.height - bubbleFrame.size.height; |
| 366 [[self window] setFrame:bubbleFrame display:YES]; | 372 [[self window] setFrame:bubbleFrame display:YES]; |
| 367 } else { | 373 } else { |
| 368 [[self window] setFrame:bubbleFrame display:NO]; | 374 [[self window] setFrame:bubbleFrame display:NO]; |
| 369 [self setAnchorPoint:anchorPoint]; | 375 [self setAnchorPoint:anchorPoint]; |
| 370 [self showWindow:nil]; | 376 [self showWindow:nil]; |
| 371 } | 377 } |
| 372 } | 378 } |
| 373 | 379 |
| 374 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request { | 380 - (NSView*)labelForRequest:(PermissionBubbleRequest*)request { |
| 375 DCHECK(request); | 381 DCHECK(request); |
| 376 base::scoped_nsobject<NSView> permissionView( | 382 base::scoped_nsobject<NSView> permissionView( |
| 377 [[NSView alloc] initWithFrame:NSZeroRect]); | 383 [[NSView alloc] initWithFrame:NSZeroRect]); |
| 378 base::scoped_nsobject<NSImageView> permissionIcon( | 384 base::scoped_nsobject<NSImageView> permissionIcon( |
| 379 [[NSImageView alloc] initWithFrame:NSZeroRect]); | 385 [[NSImageView alloc] initWithFrame:NSZeroRect]); |
| 380 [permissionIcon setImage:ui::ResourceBundle::GetSharedInstance(). | 386 [permissionIcon setImage:ui::ResourceBundle::GetSharedInstance(). |
| 381 GetNativeImageNamed(request->GetIconID()).ToNSImage()]; | 387 GetNativeImageNamed(request->GetIconID()).ToNSImage()]; |
| 382 [permissionIcon setFrameSize:[[permissionIcon image] size]]; | 388 [permissionIcon setFrameSize:kPermissionIconSize]; |
|
groby-ooo-7-16
2014/05/21 18:28:37
Are you sure you want scaling if the icon is not 1
leng
2014/05/21 22:33:51
The scaling is deliberate - I didn't want to recre
groby-ooo-7-16
2014/05/21 23:50:28
Done.
| |
| 383 [permissionView addSubview:permissionIcon]; | 389 [permissionView addSubview:permissionIcon]; |
| 384 | 390 |
| 385 base::scoped_nsobject<NSTextField> permissionLabel( | 391 base::scoped_nsobject<NSTextField> permissionLabel( |
| 386 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 392 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
| 387 base::string16 label = request->GetMessageTextFragment(); | 393 base::string16 label = request->GetMessageTextFragment(); |
| 388 [permissionLabel setDrawsBackground:NO]; | 394 [permissionLabel setDrawsBackground:NO]; |
| 389 [permissionLabel setBezeled:NO]; | 395 [permissionLabel setBezeled:NO]; |
| 390 [permissionLabel setEditable:NO]; | 396 [permissionLabel setEditable:NO]; |
| 391 [permissionLabel setSelectable:NO]; | 397 [permissionLabel setSelectable:NO]; |
| 392 [permissionLabel setFont:[NSFont systemFontOfSize:kPermissionFontSize]]; | 398 [permissionLabel |
| 399 setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; | |
| 393 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; | 400 [permissionLabel setStringValue:base::SysUTF16ToNSString(label)]; |
| 394 [permissionLabel sizeToFit]; | 401 [permissionLabel sizeToFit]; |
| 395 [permissionLabel setFrameOrigin: | 402 [permissionLabel setFrameOrigin: |
| 396 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; | 403 NSMakePoint(NSWidth([permissionIcon frame]), 0)]; |
| 397 [permissionView addSubview:permissionLabel]; | 404 [permissionView addSubview:permissionLabel]; |
| 398 | 405 |
| 399 // Match the horizontal centers of the two subviews. Note that the label's | 406 // Match the horizontal centers of the two subviews. Note that the label's |
| 400 // center is rounded down, and the icon's center, up. It looks better that | 407 // center is rounded down, and the icon's center, up. It looks better that |
| 401 // way - with the text's center slightly lower than the icon's center - if the | 408 // way - with the text's center slightly lower than the icon's center - if the |
| 402 // height delta is not evenly split. | 409 // height delta is not evenly split. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 419 - (NSView*)titleWithHostname:(const std::string&)host { | 426 - (NSView*)titleWithHostname:(const std::string&)host { |
| 420 base::scoped_nsobject<NSTextField> titleView( | 427 base::scoped_nsobject<NSTextField> titleView( |
| 421 [[NSTextField alloc] initWithFrame:NSZeroRect]); | 428 [[NSTextField alloc] initWithFrame:NSZeroRect]); |
| 422 [titleView setDrawsBackground:NO]; | 429 [titleView setDrawsBackground:NO]; |
| 423 [titleView setBezeled:NO]; | 430 [titleView setBezeled:NO]; |
| 424 [titleView setEditable:NO]; | 431 [titleView setEditable:NO]; |
| 425 [titleView setSelectable:NO]; | 432 [titleView setSelectable:NO]; |
| 426 [titleView setStringValue: | 433 [titleView setStringValue: |
| 427 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, | 434 l10n_util::GetNSStringF(IDS_PERMISSIONS_BUBBLE_PROMPT, |
| 428 base::UTF8ToUTF16(host))]; | 435 base::UTF8ToUTF16(host))]; |
| 429 [titleView setFont:[NSFont systemFontOfSize:kTitleFontSize]]; | 436 [titleView setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; |
| 430 [titleView sizeToFit]; | 437 [titleView sizeToFit]; |
| 431 NSRect titleFrame = [titleView frame]; | 438 NSRect titleFrame = [titleView frame]; |
| 432 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, | 439 [titleView setFrameSize:NSMakeSize(NSWidth(titleFrame) + kTitlePaddingX, |
| 433 NSHeight(titleFrame))]; | 440 NSHeight(titleFrame))]; |
| 434 return titleView.autorelease(); | 441 return titleView.autorelease(); |
| 435 } | 442 } |
| 436 | 443 |
| 437 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request | 444 - (NSView*)menuForRequest:(PermissionBubbleRequest*)request |
| 438 atIndex:(int)index | 445 atIndex:(int)index |
| 439 allow:(BOOL)allow { | 446 allow:(BOOL)allow { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 535 | 542 |
| 536 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { | 543 + (void)alignCenterOf:(NSView*)viewA verticallyToCenterOf:(NSView*)viewB { |
| 537 NSRect frameA = [viewA frame]; | 544 NSRect frameA = [viewA frame]; |
| 538 NSRect frameB = [viewB frame]; | 545 NSRect frameB = [viewB frame]; |
| 539 frameA.origin.y = | 546 frameA.origin.y = |
| 540 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); | 547 NSMinY(frameB) + std::floor((NSHeight(frameB) - NSHeight(frameA)) / 2); |
| 541 [viewA setFrameOrigin:frameA.origin]; | 548 [viewA setFrameOrigin:frameA.origin]; |
| 542 } | 549 } |
| 543 | 550 |
| 544 @end // implementation PermissionBubbleController | 551 @end // implementation PermissionBubbleController |
| OLD | NEW |