| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/location_bar/action_box_menu_bubble_controller.
h" | 5 #import "chrome/browser/ui/cocoa/location_bar/action_box_menu_bubble_controller.
h" |
| 6 | 6 |
| 7 #include "base/mac/bundle_locations.h" | 7 #include "base/mac/bundle_locations.h" |
| 8 #include "base/mac/foundation_util.h" | 8 #include "base/mac/foundation_util.h" |
| 9 #include "base/mac/mac_util.h" | 9 #include "base/mac/mac_util.h" |
| 10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
| 11 #include "chrome/browser/extensions/extension_icon_image.h" | 11 #include "chrome/browser/extensions/extension_icon_image.h" |
| 12 #import "chrome/browser/ui/cocoa/browser_window_utils.h" | 12 #import "chrome/browser/ui/cocoa/browser_window_utils.h" |
| 13 #import "chrome/browser/ui/cocoa/event_utils.h" | 13 #import "chrome/browser/ui/cocoa/event_utils.h" |
| 14 #import "chrome/browser/ui/cocoa/info_bubble_view.h" | 14 #import "chrome/browser/ui/cocoa/info_bubble_view.h" |
| 15 #import "chrome/browser/ui/cocoa/info_bubble_window.h" | 15 #import "chrome/browser/ui/cocoa/info_bubble_window.h" |
| 16 #include "chrome/browser/ui/toolbar/action_box_menu_model.h" | 16 #include "chrome/browser/ui/toolbar/action_box_menu_model.h" |
| 17 #include "chrome/common/extensions/api/extension_action/action_info.h" | 17 #include "chrome/common/extensions/api/extension_action/action_info.h" |
| 18 #include "chrome/common/extensions/extension.h" | 18 #include "chrome/common/extensions/extension.h" |
| 19 #include "chrome/common/extensions/extension_constants.h" | 19 #include "chrome/common/extensions/extension_constants.h" |
| 20 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
| 21 #include "grit/theme_resources.h" | 21 #include "grit/theme_resources.h" |
| 22 #include "skia/ext/skia_utils_mac.h" |
| 22 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" | 23 #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" |
| 23 #include "ui/base/resource/resource_bundle.h" | 24 #include "ui/base/resource/resource_bundle.h" |
| 24 #include "ui/gfx/image/image.h" | 25 #include "ui/gfx/image/image.h" |
| 25 #include "ui/gfx/image/image_skia_util_mac.h" | 26 #include "ui/gfx/image/image_skia_util_mac.h" |
| 27 #include "ui/native_theme/native_theme.h" |
| 26 | 28 |
| 27 @interface ActionBoxMenuBubbleController (Private) | 29 @interface ActionBoxMenuBubbleController (Private) |
| 28 - (id)highlightedItem; | 30 - (id)highlightedItem; |
| 29 - (void)keyDown:(NSEvent*)theEvent; | 31 - (void)keyDown:(NSEvent*)theEvent; |
| 30 - (void)moveDown:(id)sender; | 32 - (void)moveDown:(id)sender; |
| 31 - (void)moveUp:(id)sender; | 33 - (void)moveUp:(id)sender; |
| 32 - (void)highlightNextItemByDelta:(NSInteger)delta; | 34 - (void)highlightNextItemByDelta:(NSInteger)delta; |
| 33 - (void)highlightItem:(ActionBoxMenuItemController*)newItem; | 35 - (void)highlightItem:(ActionBoxMenuItemController*)newItem; |
| 34 @end | 36 @end |
| 35 | 37 |
| 38 @interface ActionBoxMenuItemView (Private) |
| 39 - (NSColor*)highlightedMenuItemBackgroundColor; |
| 40 @end |
| 41 |
| 36 namespace { | 42 namespace { |
| 37 | 43 |
| 38 // Some reasonable values for the menu geometry. | 44 // Some reasonable values for the menu geometry. |
| 39 const CGFloat kBubbleMinWidth = 175; | 45 const CGFloat kBubbleMinWidth = 175; |
| 40 const CGFloat kBubbleMaxWidth = 800; | 46 const CGFloat kBubbleMaxWidth = 800; |
| 41 | 47 |
| 42 // Distance between the top/bottom of the bubble and the first/last menu item. | 48 // Distance between the top/bottom of the bubble and the first/last menu item. |
| 43 const CGFloat kVerticalPadding = 7.0; | 49 const CGFloat kVerticalPadding = 7.0; |
| 44 | 50 |
| 45 // Minimum distance between the right of a menu item and the right border. | 51 // Minimum distance between the right of a menu item and the right border. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 anchoredAt:(NSPoint)point | 97 anchoredAt:(NSPoint)point |
| 92 profile:(Profile*)profile { | 98 profile:(Profile*)profile { |
| 93 // Use an arbitrary height because it will reflect the size of the content. | 99 // Use an arbitrary height because it will reflect the size of the content. |
| 94 NSRect contentRect = NSMakeRect(0, 0, kBubbleMinWidth, 150); | 100 NSRect contentRect = NSMakeRect(0, 0, kBubbleMinWidth, 150); |
| 95 // Create an empty window into which content is placed. | 101 // Create an empty window into which content is placed. |
| 96 scoped_nsobject<InfoBubbleWindow> window( | 102 scoped_nsobject<InfoBubbleWindow> window( |
| 97 [[InfoBubbleWindow alloc] initWithContentRect:contentRect | 103 [[InfoBubbleWindow alloc] initWithContentRect:contentRect |
| 98 styleMask:NSBorderlessWindowMask | 104 styleMask:NSBorderlessWindowMask |
| 99 backing:NSBackingStoreBuffered | 105 backing:NSBackingStoreBuffered |
| 100 defer:NO]); | 106 defer:NO]); |
| 107 [window setAllowedAnimations:info_bubble::kAnimateNone]; |
| 101 if (self = [super initWithWindow:window | 108 if (self = [super initWithWindow:window |
| 102 parentWindow:parent | 109 parentWindow:parent |
| 103 anchoredAt:point]) { | 110 anchoredAt:point]) { |
| 104 profile_ = profile; | 111 profile_ = profile; |
| 105 model_.reset(model.release()); | 112 model_.reset(model.release()); |
| 106 | 113 |
| 107 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; | 114 [[self bubble] setAlignment:info_bubble::kAlignRightEdgeToAnchorEdge]; |
| 108 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; | 115 [[self bubble] setArrowLocation:info_bubble::kNoArrow]; |
| 116 ui::NativeTheme* nativeTheme = ui::NativeTheme::instance(); |
| 109 [[self bubble] setBackgroundColor: | 117 [[self bubble] setBackgroundColor: |
| 110 [NSColor colorWithDeviceWhite:(251.0f/255.0f) | 118 gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor( |
| 111 alpha:1.0]]; | 119 ui::NativeTheme::kColorId_DialogBackground))]; |
| 112 [self performLayout]; | 120 [self performLayout]; |
| 113 } | 121 } |
| 114 return self; | 122 return self; |
| 115 } | 123 } |
| 116 | 124 |
| 117 - (ActionBoxMenuModel*)model { | 125 - (ActionBoxMenuModel*)model { |
| 118 return model_.get(); | 126 return model_.get(); |
| 119 } | 127 } |
| 120 | 128 |
| 121 - (NSMutableArray*)items { | 129 - (NSMutableArray*)items { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 151 CGFloat yOffset = kVerticalPadding; | 159 CGFloat yOffset = kVerticalPadding; |
| 152 | 160 |
| 153 // Keep track of a potential separator to resize it when we know the width. | 161 // Keep track of a potential separator to resize it when we know the width. |
| 154 scoped_nsobject<NSBox> separatorView; | 162 scoped_nsobject<NSBox> separatorView; |
| 155 | 163 |
| 156 // Loop over the items in reverse, constructing the menu items. | 164 // Loop over the items in reverse, constructing the menu items. |
| 157 CGFloat width = kBubbleMinWidth; | 165 CGFloat width = kBubbleMinWidth; |
| 158 CGFloat minX = NSMinX([contentView bounds]); | 166 CGFloat minX = NSMinX([contentView bounds]); |
| 159 for (int i = model_->GetItemCount() - 1; i >= 0; --i) { | 167 for (int i = model_->GetItemCount() - 1; i >= 0; --i) { |
| 160 if (model_->GetTypeAt(i) == ui::MenuModel::TYPE_SEPARATOR) { | 168 if (model_->GetTypeAt(i) == ui::MenuModel::TYPE_SEPARATOR) { |
| 169 const CGFloat kSeparatorHeight = 1.0; |
| 161 // Only supports one separator. | 170 // Only supports one separator. |
| 162 DCHECK(!separatorView); | 171 DCHECK(!separatorView); |
| 163 yOffset += kVerticalPadding; | 172 yOffset += kVerticalPadding + kSeparatorHeight; |
| 164 separatorView.reset([[NSBox alloc] | 173 separatorView.reset([[NSBox alloc] |
| 165 initWithFrame:NSMakeRect(0, yOffset, width, 1)]); | 174 initWithFrame:NSMakeRect(0, yOffset, width, kSeparatorHeight)]); |
| 166 [separatorView setBorderType:NSNoBorder]; | |
| 167 [separatorView setBoxType:NSBoxCustom]; | 175 [separatorView setBoxType:NSBoxCustom]; |
| 168 [separatorView setFillColor:[NSColor grayColor]]; | 176 ui::NativeTheme* nativeTheme = ui::NativeTheme::instance(); |
| 177 [separatorView setBorderColor: |
| 178 gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor( |
| 179 ui::NativeTheme::kColorId_MenuSeparatorColor))]; |
| 169 [contentView addSubview:separatorView]; | 180 [contentView addSubview:separatorView]; |
| 170 yOffset += kVerticalPadding; | 181 yOffset += kVerticalPadding; |
| 171 } else { | 182 } else { |
| 172 // Create the item controller. Autorelease it because it will be owned | 183 // Create the item controller. Autorelease it because it will be owned |
| 173 // by the |items_| array. | 184 // by the |items_| array. |
| 174 scoped_nsobject<ActionBoxMenuItemController> itemController( | 185 scoped_nsobject<ActionBoxMenuItemController> itemController( |
| 175 [[ActionBoxMenuItemController alloc] | 186 [[ActionBoxMenuItemController alloc] |
| 176 initWithModelIndex:i | 187 initWithModelIndex:i |
| 177 menuController:self | 188 menuController:self |
| 178 profile:profile_]); | 189 profile:profile_]); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 [viewController_ highlightForEvent:theEvent]; | 400 [viewController_ highlightForEvent:theEvent]; |
| 390 } | 401 } |
| 391 | 402 |
| 392 - (void)mouseExited:(NSEvent*)theEvent { | 403 - (void)mouseExited:(NSEvent*)theEvent { |
| 393 [viewController_ highlightForEvent:theEvent]; | 404 [viewController_ highlightForEvent:theEvent]; |
| 394 } | 405 } |
| 395 | 406 |
| 396 - (void)drawRect:(NSRect)dirtyRect { | 407 - (void)drawRect:(NSRect)dirtyRect { |
| 397 NSColor* backgroundColor = nil; | 408 NSColor* backgroundColor = nil; |
| 398 if ([viewController_ isHighlighted]) { | 409 if ([viewController_ isHighlighted]) { |
| 399 backgroundColor = [NSColor colorWithDeviceWhite:0.0 alpha:kSelectionAlpha]; | 410 ui::NativeTheme* nativeTheme = ui::NativeTheme::instance(); |
| 411 backgroundColor = gfx::SkColorToCalibratedNSColor( |
| 412 nativeTheme->GetSystemColor( |
| 413 ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor)); |
| 400 } else { | 414 } else { |
| 401 backgroundColor = [NSColor clearColor]; | 415 backgroundColor = [NSColor clearColor]; |
| 402 } | 416 } |
| 403 | 417 |
| 404 [backgroundColor set]; | 418 [backgroundColor set]; |
| 405 [NSBezierPath fillRect:[self bounds]]; | 419 [NSBezierPath fillRect:[self bounds]]; |
| 406 } | 420 } |
| 407 | 421 |
| 408 // Make sure the element is focusable for accessibility. | 422 // Make sure the element is focusable for accessibility. |
| 409 - (BOOL)canBecomeKeyView { | 423 - (BOOL)canBecomeKeyView { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 457 |
| 444 - (void)accessibilityPerformAction:(NSString*)action { | 458 - (void)accessibilityPerformAction:(NSString*)action { |
| 445 if ([action isEqual:NSAccessibilityPressAction]) { | 459 if ([action isEqual:NSAccessibilityPressAction]) { |
| 446 [viewController_ itemSelected:self]; | 460 [viewController_ itemSelected:self]; |
| 447 return; | 461 return; |
| 448 } | 462 } |
| 449 | 463 |
| 450 [super accessibilityPerformAction:action]; | 464 [super accessibilityPerformAction:action]; |
| 451 } | 465 } |
| 452 | 466 |
| 467 - (NSColor*)highlightedMenuItemBackgroundColor { |
| 468 ui::NativeTheme* nativeTheme = ui::NativeTheme::instance(); |
| 469 return gfx::SkColorToCalibratedNSColor(nativeTheme->GetSystemColor( |
| 470 ui::NativeTheme::kColorId_FocusedMenuItemBackgroundColor)); |
| 471 } |
| 472 |
| 453 @end | 473 @end |
| OLD | NEW |