| Index: webkit/glue/webmenurunner_mac.mm
|
| ===================================================================
|
| --- webkit/glue/webmenurunner_mac.mm (revision 73989)
|
| +++ webkit/glue/webmenurunner_mac.mm (working copy)
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -6,28 +6,31 @@
|
|
|
| #include "base/sys_string_conversions.h"
|
|
|
| -namespace {
|
| -
|
| -const CGFloat kPopupXOffset = -10.0f;
|
| -BOOL gNewNSMenuAPI;
|
| -
|
| -} // namespace
|
| -
|
| #if !defined(MAC_OS_X_VERSION_10_6) || \
|
| MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
|
| -@interface NSMenu (SnowLeopardSDKDeclarations)
|
| -- (BOOL)popUpMenuPositioningItem:(NSMenuItem *)item
|
| - atLocation:(NSPoint)location
|
| - inView:(NSView *)view;
|
| -- (void)setFont:(NSFont *)font;
|
| +enum {
|
| + NSUserInterfaceLayoutDirectionLeftToRight = 0,
|
| + NSUserInterfaceLayoutDirectionRightToLeft = 1
|
| +};
|
| +typedef NSInteger NSUserInterfaceLayoutDirection;
|
| +
|
| +@interface NSCell (SnowLeopardSDKDeclarations)
|
| +- (void)setUserInterfaceLayoutDirection:
|
| + (NSUserInterfaceLayoutDirection)layoutDirection;
|
| @end
|
| +
|
| +enum {
|
| + NSTextWritingDirectionEmbedding = (0 << 1),
|
| + NSTextWritingDirectionOverride = (1 << 1)
|
| +};
|
| +
|
| +static NSString* NSWritingDirectionAttributeName = @"NSWritingDirection";
|
| #endif
|
|
|
| @interface WebMenuRunner (PrivateAPI)
|
|
|
| // Worker function used during initialization.
|
| -- (void)addItem:(const WebMenuItem&)item
|
| - withAttributes:(NSDictionary*)attrs;
|
| +- (void)addItem:(const WebMenuItem&)item;
|
|
|
| // A callback for the menu controller object to call when an item is selected
|
| // from the menu. This is not called if the menu is dismissed without a
|
| @@ -41,39 +44,19 @@
|
| - (id)initWithItems:(const std::vector<WebMenuItem>&)items
|
| fontSize:(CGFloat)fontSize
|
| rightAligned:(BOOL)rightAligned {
|
| - static BOOL newNSMenuAPIInitialized = NO;
|
| - if (!newNSMenuAPIInitialized) {
|
| - newNSMenuAPIInitialized = YES;
|
| - gNewNSMenuAPI = [NSMenu instancesRespondToSelector:
|
| - @selector(popUpMenuPositioningItem:atLocation:inView:)] &&
|
| - [NSMenu instancesRespondToSelector:@selector(setFont:)];
|
| - }
|
| -
|
| if ((self = [super init])) {
|
| menu_.reset([[NSMenu alloc] initWithTitle:@""]);
|
| - if (gNewNSMenuAPI)
|
| - [menu_ setFont:[NSFont menuFontOfSize:fontSize]];
|
| [menu_ setAutoenablesItems:NO];
|
| index_ = -1;
|
| fontSize_ = fontSize;
|
| - scoped_nsobject<NSDictionary> attrs;
|
| - if (rightAligned) {
|
| - // NB: Right-aligning menu items in this manner is known to not work in
|
| - // Mac OS X 10.5.
|
| - scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
|
| - [[NSMutableParagraphStyle alloc] init]);
|
| - [paragraphStyle setAlignment:NSRightTextAlignment];
|
| - attrs.reset([[NSDictionary alloc] initWithObjectsAndKeys:
|
| - paragraphStyle, NSParagraphStyleAttributeName, nil]);
|
| - }
|
| + rightAligned_ = rightAligned;
|
| for (size_t i = 0; i < items.size(); ++i)
|
| - [self addItem:items[i] withAttributes:attrs];
|
| + [self addItem:items[i]];
|
| }
|
| return self;
|
| }
|
|
|
| -- (void)addItem:(const WebMenuItem&)item
|
| - withAttributes:(NSDictionary*)attrs {
|
| +- (void)addItem:(const WebMenuItem&)item {
|
| if (item.type == WebMenuItem::SEPARATOR) {
|
| [menu_ addItem:[NSMenuItem separatorItem]];
|
| return;
|
| @@ -85,12 +68,38 @@
|
| keyEquivalent:@""];
|
| [menuItem setEnabled:(item.enabled && item.type != WebMenuItem::GROUP)];
|
| [menuItem setTarget:self];
|
| - if (attrs) {
|
| - scoped_nsobject<NSAttributedString> attrTitle(
|
| - [[NSAttributedString alloc] initWithString:title
|
| - attributes:attrs]);
|
| - [menuItem setAttributedTitle:attrTitle];
|
| +
|
| + // Set various alignment/language attributes. Note that many (if not most) of
|
| + // these attributes are functional only on 10.6 and above.
|
| + scoped_nsobject<NSMutableDictionary> attrs(
|
| + [[NSMutableDictionary alloc] initWithCapacity:3]);
|
| + scoped_nsobject<NSMutableParagraphStyle> paragraphStyle(
|
| + [[NSMutableParagraphStyle alloc] init]);
|
| + [paragraphStyle setAlignment:rightAligned_ ? NSRightTextAlignment
|
| + : NSLeftTextAlignment];
|
| + NSWritingDirection writingDirection =
|
| + item.rtl ? NSWritingDirectionRightToLeft
|
| + : NSWritingDirectionLeftToRight;
|
| + [paragraphStyle setBaseWritingDirection:writingDirection];
|
| + [attrs setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
|
| +
|
| + if (item.directional_override) {
|
| + scoped_nsobject<NSNumber> directionValue(
|
| + [[NSNumber alloc] initWithInteger:
|
| + writingDirection + NSTextWritingDirectionOverride]);
|
| + scoped_nsobject<NSArray> directionArray(
|
| + [[NSArray alloc] initWithObjects:directionValue.get(), nil]);
|
| + [attrs setObject:directionArray forKey:NSWritingDirectionAttributeName];
|
| }
|
| +
|
| + [attrs setObject:[NSFont menuFontOfSize:fontSize_]
|
| + forKey:NSFontAttributeName];
|
| +
|
| + scoped_nsobject<NSAttributedString> attrTitle(
|
| + [[NSAttributedString alloc] initWithString:title
|
| + attributes:attrs]);
|
| + [menuItem setAttributedTitle:attrTitle];
|
| +
|
| [menuItem setTag:[menu_ numberOfItems] - 1];
|
| }
|
|
|
| @@ -104,53 +113,41 @@
|
|
|
| - (void)menuItemSelected:(id)sender {
|
| menuItemWasChosen_ = YES;
|
| - if (gNewNSMenuAPI)
|
| - index_ = [sender tag];
|
| }
|
|
|
| - (void)runMenuInView:(NSView*)view
|
| withBounds:(NSRect)bounds
|
| initialIndex:(int)index {
|
| - if (gNewNSMenuAPI) {
|
| - // index might be out of bounds, in which case we set no selection.
|
| - NSMenuItem* selectedItem = [menu_ itemWithTag:index];
|
| - if (selectedItem) {
|
| - [selectedItem setState:NSOnState];
|
| - } else {
|
| - selectedItem = [menu_ itemWithTag:0];
|
| - }
|
| - NSPoint anchor = NSMakePoint(NSMinX(bounds) + kPopupXOffset,
|
| - NSMaxY(bounds));
|
| - [menu_ popUpMenuPositioningItem:selectedItem
|
| - atLocation:anchor
|
| - inView:view];
|
| - } else {
|
| - // Set up the button cell, converting to NSView coordinates. The menu is
|
| - // positioned such that the currently selected menu item appears over the
|
| - // popup button, which is the expected Mac popup menu behavior.
|
| - NSPopUpButtonCell* button = [[NSPopUpButtonCell alloc] initTextCell:@""
|
| - pullsDown:NO];
|
| - [button autorelease];
|
| - [button setMenu:menu_];
|
| - // We use selectItemWithTag below so if the index is out-of-bounds nothing
|
| - // bad happens.
|
| - [button selectItemWithTag:index];
|
| - [button setFont:[NSFont menuFontOfSize:fontSize_]];
|
| + // Set up the button cell, converting to NSView coordinates. The menu is
|
| + // positioned such that the currently selected menu item appears over the
|
| + // popup button, which is the expected Mac popup menu behavior.
|
| + NSPopUpButtonCell* button = [[NSPopUpButtonCell alloc] initTextCell:@""
|
| + pullsDown:NO];
|
| + [button autorelease];
|
| + [button setMenu:menu_];
|
| + // We use selectItemWithTag below so if the index is out-of-bounds nothing
|
| + // bad happens.
|
| + [button selectItemWithTag:index];
|
|
|
| - // Create a dummy view to associate the popup with, since the OS will use
|
| - // that view for positioning the menu.
|
| - NSView* dummyView = [[[NSView alloc] initWithFrame:bounds] autorelease];
|
| - [view addSubview:dummyView];
|
| - NSRect dummyBounds = [dummyView convertRect:bounds fromView:view];
|
| + if (rightAligned_ &&
|
| + [button respondsToSelector:@selector(setUserInterfaceLayoutDirection:)]) {
|
| + [button setUserInterfaceLayoutDirection:
|
| + NSUserInterfaceLayoutDirectionRightToLeft];
|
| + }
|
|
|
| - // Display the menu, and set a flag if a menu item was chosen.
|
| - [button performClickWithFrame:dummyBounds inView:dummyView];
|
| + // Create a dummy view to associate the popup with, since the OS will use
|
| + // that view for positioning the menu.
|
| + NSView* dummyView = [[[NSView alloc] initWithFrame:bounds] autorelease];
|
| + [view addSubview:dummyView];
|
| + NSRect dummyBounds = [dummyView convertRect:bounds fromView:view];
|
|
|
| - if ([self menuItemWasChosen])
|
| - index_ = [button indexOfSelectedItem];
|
| + // Display the menu, and set a flag if a menu item was chosen.
|
| + [button performClickWithFrame:dummyBounds inView:dummyView];
|
|
|
| - [dummyView removeFromSuperview];
|
| - }
|
| + if ([self menuItemWasChosen])
|
| + index_ = [button indexOfSelectedItem];
|
| +
|
| + [dummyView removeFromSuperview];
|
| }
|
|
|
| - (int)indexOfSelectedItem {
|
|
|