| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 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 #include "app/l10n_util_mac.h" | 5 #include "app/l10n_util_mac.h" |
| 6 #include "base/mac_util.h" | 6 #include "base/mac_util.h" |
| 7 #import "chrome/browser/cocoa/menu_controller.h" |
| 7 #import "chrome/browser/cocoa/tab_controller.h" | 8 #import "chrome/browser/cocoa/tab_controller.h" |
| 8 #import "chrome/browser/cocoa/tab_controller_target.h" | 9 #import "chrome/browser/cocoa/tab_controller_target.h" |
| 9 #import "chrome/browser/cocoa/tab_view.h" | 10 #import "chrome/browser/cocoa/tab_view.h" |
| 10 #include "grit/generated_resources.h" | 11 #include "grit/generated_resources.h" |
| 11 #import "third_party/GTM/AppKit/GTMTheme.h" | 12 #import "third_party/GTM/AppKit/GTMTheme.h" |
| 12 | 13 |
| 13 @implementation TabController | 14 @implementation TabController |
| 14 | 15 |
| 15 @synthesize loadingState = loadingState_; | 16 @synthesize loadingState = loadingState_; |
| 16 @synthesize pinned = pinned_; | 17 @synthesize pinned = pinned_; |
| 17 @synthesize target = target_; | 18 @synthesize target = target_; |
| 18 @synthesize action = action_; | 19 @synthesize action = action_; |
| 19 | 20 |
| 21 namespace TabControllerInternal { |
| 22 |
| 23 // A C++ delegate that handles enabling/disabling menu items and handling when |
| 24 // a menu command is chosen. Also fixes up the menu item label for "pin/unpin |
| 25 // tab". |
| 26 class MenuDelegate : public menus::SimpleMenuModel::Delegate { |
| 27 public: |
| 28 explicit MenuDelegate(id<TabControllerTarget> target, TabController* owner) |
| 29 : target_(target), owner_(owner) { } |
| 30 |
| 31 // Overridden from menus::SimpleMenuModel::Delegate |
| 32 virtual bool IsCommandIdChecked(int command_id) const { return false; } |
| 33 virtual bool IsCommandIdEnabled(int command_id) const { |
| 34 TabStripModel::ContextMenuCommand command = |
| 35 static_cast<TabStripModel::ContextMenuCommand>(command_id); |
| 36 return [target_ isCommandEnabled:command forController:owner_]; |
| 37 } |
| 38 virtual bool GetAcceleratorForCommandId( |
| 39 int command_id, |
| 40 menus::Accelerator* accelerator) { return false; } |
| 41 virtual void ExecuteCommand(int command_id) { |
| 42 TabStripModel::ContextMenuCommand command = |
| 43 static_cast<TabStripModel::ContextMenuCommand>(command_id); |
| 44 [target_ commandDispatch:command forController:owner_]; |
| 45 } |
| 46 |
| 47 virtual bool IsLabelForCommandIdDynamic(int command_id) const { |
| 48 return command_id == TabStripModel::CommandTogglePinned; |
| 49 } |
| 50 virtual string16 GetLabelForCommandId(int command_id) const { |
| 51 // Display "Pin Tab" when the tab is not pinned and "Unpin Tab" when it is |
| 52 // (this is not a checkmark menu item, per Apple's HIG). |
| 53 if (command_id == TabStripModel::CommandTogglePinned) { |
| 54 return l10n_util::GetStringUTF16( |
| 55 [owner_ pinned] ? IDS_TAB_CXMENU_UNPIN_TAB_MAC |
| 56 : IDS_TAB_CXMENU_PIN_TAB_MAC); |
| 57 } |
| 58 return string16(); |
| 59 } |
| 60 |
| 61 private: |
| 62 id<TabControllerTarget> target_; // weak |
| 63 TabController* owner_; // weak, owns me |
| 64 }; |
| 65 |
| 66 } // namespace |
| 67 |
| 20 // The min widths match the windows values and are sums of left + right | 68 // The min widths match the windows values and are sums of left + right |
| 21 // padding, of which we have no comparable constants (we draw using paths, not | 69 // padding, of which we have no comparable constants (we draw using paths, not |
| 22 // images). The selected tab width includes the close button width. | 70 // images). The selected tab width includes the close button width. |
| 23 + (CGFloat)minTabWidth { return 31; } | 71 + (CGFloat)minTabWidth { return 31; } |
| 24 + (CGFloat)minSelectedTabWidth { return 47; } | 72 + (CGFloat)minSelectedTabWidth { return 47; } |
| 25 + (CGFloat)maxTabWidth { return 220; } | 73 + (CGFloat)maxTabWidth { return 220; } |
| 26 + (CGFloat)pinnedTabWidth { return 53; } | 74 + (CGFloat)pinnedTabWidth { return 53; } |
| 27 | 75 |
| 28 - (TabView*)tabView { | 76 - (TabView*)tabView { |
| 29 return static_cast<TabView*>([self view]); | 77 return static_cast<TabView*>([self view]); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 // left by the icon. When the close button is removed, the title expands to | 120 // left by the icon. When the close button is removed, the title expands to |
| 73 // the right to fill its space. These are the amounts to expand and contract | 121 // the right to fill its space. These are the amounts to expand and contract |
| 74 // titleView_ under those conditions. | 122 // titleView_ under those conditions. |
| 75 NSRect titleFrame = [titleView_ frame]; | 123 NSRect titleFrame = [titleView_ frame]; |
| 76 iconTitleXOffset_ = NSMinX(titleFrame) - NSMinX(originalIconFrame_); | 124 iconTitleXOffset_ = NSMinX(titleFrame) - NSMinX(originalIconFrame_); |
| 77 titleCloseWidthOffset_ = NSMaxX([closeButton_ frame]) - NSMaxX(titleFrame); | 125 titleCloseWidthOffset_ = NSMaxX([closeButton_ frame]) - NSMaxX(titleFrame); |
| 78 | 126 |
| 79 [self internalSetSelected:selected_]; | 127 [self internalSetSelected:selected_]; |
| 80 } | 128 } |
| 81 | 129 |
| 130 // Called when Cocoa wants to display the context menu. Lazily instantiate |
| 131 // the menu based off of the cross-platform model. Re-create the menu and |
| 132 // model every time to get the correct labels and enabling. |
| 133 - (NSMenu*)menu { |
| 134 contextMenuDelegate_.reset( |
| 135 new TabControllerInternal::MenuDelegate(target_, self)); |
| 136 contextMenuModel_.reset(new TabMenuModel(contextMenuDelegate_.get())); |
| 137 contextMenuController_.reset( |
| 138 [[MenuController alloc] initWithModel:contextMenuModel_.get() |
| 139 useWithPopUpButtonCell:NO]); |
| 140 return [contextMenuController_ menu]; |
| 141 } |
| 142 |
| 82 - (IBAction)closeTab:(id)sender { | 143 - (IBAction)closeTab:(id)sender { |
| 83 if ([[self target] respondsToSelector:@selector(closeTab:)]) { | 144 if ([[self target] respondsToSelector:@selector(closeTab:)]) { |
| 84 [[self target] performSelector:@selector(closeTab:) | 145 [[self target] performSelector:@selector(closeTab:) |
| 85 withObject:[self view]]; | 146 withObject:[self view]]; |
| 86 } | 147 } |
| 87 } | 148 } |
| 88 | 149 |
| 89 // Dispatches the command in the tag to the registered target object. | |
| 90 - (IBAction)commandDispatch:(id)sender { | |
| 91 TabStripModel::ContextMenuCommand command = | |
| 92 static_cast<TabStripModel::ContextMenuCommand>([sender tag]); | |
| 93 [[self target] commandDispatch:command forController:self]; | |
| 94 } | |
| 95 | |
| 96 // Called for each menu item on its target, which would be this controller. | |
| 97 // Returns YES if the menu item should be enabled. We ask the tab's | |
| 98 // target for the proper answer. | |
| 99 - (BOOL)validateMenuItem:(NSMenuItem*)item { | |
| 100 TabStripModel::ContextMenuCommand command = | |
| 101 static_cast<TabStripModel::ContextMenuCommand>([item tag]); | |
| 102 return [[self target] isCommandEnabled:command forController:self]; | |
| 103 } | |
| 104 | |
| 105 - (void)setTitle:(NSString*)title { | 150 - (void)setTitle:(NSString*)title { |
| 106 [[self view] setToolTip:title]; | 151 [[self view] setToolTip:title]; |
| 107 [super setTitle:title]; | 152 [super setTitle:title]; |
| 108 } | 153 } |
| 109 | 154 |
| 110 - (void)setSelected:(BOOL)selected { | 155 - (void)setSelected:(BOOL)selected { |
| 111 if (selected_ != selected) | 156 if (selected_ != selected) |
| 112 [self internalSetSelected:selected]; | 157 [self internalSetSelected:selected]; |
| 113 } | 158 } |
| 114 | 159 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 | 297 |
| 253 // Called by the tabs to determine whether we are in rapid (tab) closure mode. | 298 // Called by the tabs to determine whether we are in rapid (tab) closure mode. |
| 254 - (BOOL)inRapidClosureMode { | 299 - (BOOL)inRapidClosureMode { |
| 255 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { | 300 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { |
| 256 return [[self target] performSelector:@selector(inRapidClosureMode)] ? | 301 return [[self target] performSelector:@selector(inRapidClosureMode)] ? |
| 257 YES : NO; | 302 YES : NO; |
| 258 } | 303 } |
| 259 return NO; | 304 return NO; |
| 260 } | 305 } |
| 261 | 306 |
| 262 // Delegate method for context menu. Called before the menu is displayed to | |
| 263 // update the menu. We need to display "Pin Tab" when the tab is not pinned and | |
| 264 // "Unpin Tab" when it is (this is not a checkmark menu item, per Apple's HIG). | |
| 265 - (void)menuNeedsUpdate:(NSMenu*)menu { | |
| 266 NSMenuItem* togglePinned = | |
| 267 [menu itemWithTag:TabStripModel::CommandTogglePinned]; | |
| 268 NSString* menuItemText = l10n_util::GetNSStringWithFixup( | |
| 269 [self pinned] ? IDS_TAB_CXMENU_UNPIN_TAB_MAC | |
| 270 : IDS_TAB_CXMENU_PIN_TAB_MAC); | |
| 271 [togglePinned setTitle:menuItemText]; | |
| 272 } | |
| 273 | |
| 274 @end | 307 @end |
| OLD | NEW |