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 |