Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "webkit/glue/webmenurunner_mac.h" | |
| 6 | |
| 7 #include "base/sys_string_conversions.h" | |
| 8 | |
| 9 @implementation WebMenuRunner | |
| 10 | |
| 11 - (id)initWithItems:(const std::vector<WebMenuItem>&)items { | |
| 12 if ((self = [super init])) { | |
| 13 menu_ = [[NSMenu alloc] initWithTitle:@""]; | |
| 14 [menu_ setAutoenablesItems:NO]; | |
| 15 menuItemWasChosen_ = NO; | |
|
pink (ping after 24hrs)
2009/04/27 14:14:59
not necessary, the runtime zero's for you.
| |
| 16 index_ = -1; | |
| 17 for (int i = 0; i < static_cast<int>(items.size()); ++i) | |
| 18 [self addItem:items[i]]; | |
| 19 } | |
| 20 return self; | |
| 21 } | |
| 22 | |
| 23 - (void)dealloc { | |
| 24 [menu_ release]; | |
| 25 [super dealloc]; | |
| 26 } | |
| 27 | |
| 28 - (void)addItem:(const WebMenuItem&)item { | |
| 29 if (item.type == WebMenuItem::SEPARATOR) { | |
| 30 [menu_ addItem:[NSMenuItem separatorItem]]; | |
| 31 return; | |
| 32 } | |
| 33 | |
| 34 NSString* title = base::SysUTF16ToNSString(item.label); | |
| 35 NSMenuItem* menu_item = [menu_ addItemWithTitle:title | |
|
pink (ping after 24hrs)
2009/04/27 14:14:59
in obj-c @implementation, use obj-c naming. This s
| |
| 36 action:@selector(menuItemSelected:) | |
| 37 keyEquivalent:@""]; | |
| 38 [menu_item setEnabled:(item.enabled && item.type != WebMenuItem::GROUP)]; | |
| 39 [menu_item setTarget:self]; | |
| 40 } | |
| 41 | |
| 42 // Reflects the result of the user's interaction with the popup menu. If NO, the | |
| 43 // menu was dismissed without the user choosing an item, which can happen if the | |
| 44 // user clicked outside the menu region or hit the escape key. If YES, the user | |
| 45 // selected an item from the menu. | |
| 46 - (BOOL)menuItemWasChosen { | |
| 47 return menuItemWasChosen_; | |
| 48 } | |
| 49 | |
| 50 - (void)menuItemSelected:(id)sender { | |
| 51 menuItemWasChosen_ = YES; | |
| 52 } | |
| 53 | |
| 54 - (void)runMenuInView:(NSView*)view | |
| 55 withBounds:(NSRect)bounds | |
| 56 initialIndex:(int)index { | |
| 57 // Set up the button cell, converting to NSView coordinates. The menu is | |
| 58 // positioned such that the currently selected menu item appears over the | |
| 59 // popup button, which is the expected Mac popup menu behavior. | |
| 60 NSPopUpButtonCell* button = [[NSPopUpButtonCell alloc] initTextCell:@"" | |
| 61 pullsDown:NO]; | |
| 62 [button autorelease]; | |
| 63 [button setMenu:menu_]; | |
| 64 [button selectItemAtIndex:index]; | |
| 65 | |
| 66 // Display the menu, and set a flag if a menu item was chosen. | |
| 67 [button performClickWithFrame:bounds inView:view]; | |
| 68 | |
| 69 if ([self menuItemWasChosen]) | |
| 70 index_ = [button indexOfSelectedItem]; | |
| 71 } | |
| 72 | |
| 73 - (int)indexOfSelectedItem { | |
| 74 return index_; | |
| 75 } | |
| 76 | |
| 77 @end // WebMenuRunner | |
| 78 | |
| 79 // Helper function for manufacturing input events to send to WebKit. | |
| 80 NSEvent* CreateEventForMenuAction(BOOL item_chosen, int window_num, | |
| 81 int item_height, int selected_index, | |
| 82 NSRect menu_bounds, NSRect view_bounds) { | |
| 83 NSEvent* event = nil; | |
| 84 double event_time = (double)(AbsoluteToDuration(UpTime())) / 1000.0; | |
| 85 | |
| 86 if (item_chosen) { | |
| 87 // Construct a mouse up event to simulate the selection of an appropriate | |
| 88 // menu item. | |
| 89 NSPoint click_pos; | |
| 90 click_pos.x = menu_bounds.size.width / 2; | |
| 91 | |
| 92 // This is going to be hard to calculate since the button is painted by | |
| 93 // WebKit, the menu by Cocoa, and we have to translate the selected_item | |
| 94 // index to a coordinate that WebKit's PopupMenu expects which uses a | |
| 95 // different font *and* expects to draw the menu below the button like we do | |
| 96 // on Windows. | |
| 97 // The WebKit popup menu thinks it will draw just below the button, so | |
| 98 // create the click at the offset based on the selected item's index and | |
| 99 // account for the different coordinate system used by NSView. | |
| 100 int item_offset = selected_index * item_height + item_height / 2; | |
| 101 click_pos.y = view_bounds.size.height - item_offset; | |
| 102 event = [NSEvent mouseEventWithType:NSLeftMouseUp | |
| 103 location:click_pos | |
| 104 modifierFlags:0 | |
| 105 timestamp:event_time | |
| 106 windowNumber:window_num | |
| 107 context:nil | |
| 108 eventNumber:0 | |
| 109 clickCount:1 | |
| 110 pressure:1.0]; | |
| 111 } else { | |
| 112 // Fake an ESC key event (keyCode = 0x1B, from webinputevent_mac.mm) and | |
| 113 // forward that to WebKit. | |
| 114 NSPoint key_pos; | |
| 115 key_pos.x = 0; | |
| 116 key_pos.y = 0; | |
| 117 event = [NSEvent keyEventWithType:NSKeyUp | |
| 118 location:key_pos | |
| 119 modifierFlags:0 | |
| 120 timestamp:event_time | |
| 121 windowNumber:window_num | |
| 122 context:nil | |
| 123 characters:@"" | |
| 124 charactersIgnoringModifiers:@"" | |
| 125 isARepeat:NO | |
| 126 keyCode:0x1B]; | |
| 127 } | |
| 128 | |
| 129 return event; | |
| 130 } | |
| OLD | NEW |