OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/browser_theme_provider.h" | 7 #import "chrome/browser/browser_theme_provider.h" |
8 #import "chrome/browser/cocoa/menu_controller.h" | 8 #import "chrome/browser/cocoa/menu_controller.h" |
9 #import "chrome/browser/cocoa/tab_controller.h" | 9 #import "chrome/browser/cocoa/tab_controller.h" |
10 #import "chrome/browser/cocoa/tab_controller_target.h" | 10 #import "chrome/browser/cocoa/tab_controller_target.h" |
11 #import "chrome/browser/cocoa/tab_view.h" | 11 #import "chrome/browser/cocoa/tab_view.h" |
12 #import "chrome/browser/cocoa/themed_window.h" | 12 #import "chrome/browser/cocoa/themed_window.h" |
13 #include "grit/generated_resources.h" | 13 #include "grit/generated_resources.h" |
14 | 14 |
15 @implementation TabController | 15 @implementation TabController |
16 | 16 |
17 @synthesize loadingState = loadingState_; | 17 @synthesize loadingState = loadingState_; |
18 @synthesize pinned = pinned_; | 18 @synthesize mini = mini_; |
| 19 @synthesize phantom = phantom_; |
19 @synthesize target = target_; | 20 @synthesize target = target_; |
20 @synthesize action = action_; | 21 @synthesize action = action_; |
21 | 22 |
| 23 namespace { |
| 24 |
| 25 // If the tab is phantom, the opacity of the TabView is adjusted to this value. |
| 26 const CGFloat kPhantomTabAlpha = 105.0 / 255.0; |
| 27 |
| 28 }; // anonymous namespace |
| 29 |
22 namespace TabControllerInternal { | 30 namespace TabControllerInternal { |
23 | 31 |
24 // A C++ delegate that handles enabling/disabling menu items and handling when | 32 // A C++ delegate that handles enabling/disabling menu items and handling when |
25 // a menu command is chosen. Also fixes up the menu item label for "pin/unpin | 33 // a menu command is chosen. Also fixes up the menu item label for "pin/unpin |
26 // tab". | 34 // tab". |
27 class MenuDelegate : public menus::SimpleMenuModel::Delegate { | 35 class MenuDelegate : public menus::SimpleMenuModel::Delegate { |
28 public: | 36 public: |
29 explicit MenuDelegate(id<TabControllerTarget> target, TabController* owner) | 37 explicit MenuDelegate(id<TabControllerTarget> target, TabController* owner) |
30 : target_(target), owner_(owner) { } | 38 : target_(target), owner_(owner) { } |
31 | 39 |
(...skipping 14 matching lines...) Expand all Loading... |
46 } | 54 } |
47 | 55 |
48 virtual bool IsLabelForCommandIdDynamic(int command_id) const { | 56 virtual bool IsLabelForCommandIdDynamic(int command_id) const { |
49 return command_id == TabStripModel::CommandTogglePinned; | 57 return command_id == TabStripModel::CommandTogglePinned; |
50 } | 58 } |
51 virtual string16 GetLabelForCommandId(int command_id) const { | 59 virtual string16 GetLabelForCommandId(int command_id) const { |
52 // Display "Pin Tab" when the tab is not pinned and "Unpin Tab" when it is | 60 // Display "Pin Tab" when the tab is not pinned and "Unpin Tab" when it is |
53 // (this is not a checkmark menu item, per Apple's HIG). | 61 // (this is not a checkmark menu item, per Apple's HIG). |
54 if (command_id == TabStripModel::CommandTogglePinned) { | 62 if (command_id == TabStripModel::CommandTogglePinned) { |
55 return l10n_util::GetStringUTF16( | 63 return l10n_util::GetStringUTF16( |
56 [owner_ pinned] ? IDS_TAB_CXMENU_UNPIN_TAB_MAC | 64 [owner_ mini] ? IDS_TAB_CXMENU_UNPIN_TAB_MAC |
57 : IDS_TAB_CXMENU_PIN_TAB_MAC); | 65 : IDS_TAB_CXMENU_PIN_TAB_MAC); |
58 } | 66 } |
59 return string16(); | 67 return string16(); |
60 } | 68 } |
61 | 69 |
62 private: | 70 private: |
63 id<TabControllerTarget> target_; // weak | 71 id<TabControllerTarget> target_; // weak |
64 TabController* owner_; // weak, owns me | 72 TabController* owner_; // weak, owns me |
65 }; | 73 }; |
66 | 74 |
67 } // namespace | 75 } // TabControllerInternal namespace |
68 | 76 |
69 // The min widths match the windows values and are sums of left + right | 77 // The min widths match the windows values and are sums of left + right |
70 // padding, of which we have no comparable constants (we draw using paths, not | 78 // padding, of which we have no comparable constants (we draw using paths, not |
71 // images). The selected tab width includes the close button width. | 79 // images). The selected tab width includes the close button width. |
72 + (CGFloat)minTabWidth { return 31; } | 80 + (CGFloat)minTabWidth { return 31; } |
73 + (CGFloat)minSelectedTabWidth { return 47; } | 81 + (CGFloat)minSelectedTabWidth { return 47; } |
74 + (CGFloat)maxTabWidth { return 220; } | 82 + (CGFloat)maxTabWidth { return 220; } |
75 + (CGFloat)pinnedTabWidth { return 53; } | 83 + (CGFloat)miniTabWidth { return 53; } |
76 | 84 |
77 - (TabView*)tabView { | 85 - (TabView*)tabView { |
78 return static_cast<TabView*>([self view]); | 86 return static_cast<TabView*>([self view]); |
79 } | 87 } |
80 | 88 |
81 - (id)init { | 89 - (id)init { |
82 self = [super initWithNibName:@"TabView" bundle:mac_util::MainAppBundle()]; | 90 self = [super initWithNibName:@"TabView" bundle:mac_util::MainAppBundle()]; |
83 if (self != nil) { | 91 if (self != nil) { |
84 isIconShowing_ = YES; | 92 isIconShowing_ = YES; |
85 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; | 93 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 153 |
146 - (IBAction)closeTab:(id)sender { | 154 - (IBAction)closeTab:(id)sender { |
147 if ([[self target] respondsToSelector:@selector(closeTab:)]) { | 155 if ([[self target] respondsToSelector:@selector(closeTab:)]) { |
148 [[self target] performSelector:@selector(closeTab:) | 156 [[self target] performSelector:@selector(closeTab:) |
149 withObject:[self view]]; | 157 withObject:[self view]]; |
150 } | 158 } |
151 } | 159 } |
152 | 160 |
153 - (void)setTitle:(NSString*)title { | 161 - (void)setTitle:(NSString*)title { |
154 [[self view] setToolTip:title]; | 162 [[self view] setToolTip:title]; |
155 if ([self pinned] && ![self selected]) { | 163 if ([self mini] && ![self selected]) { |
156 TabView* tabView = static_cast<TabView*>([self view]); | 164 TabView* tabView = static_cast<TabView*>([self view]); |
157 DCHECK([tabView isKindOfClass:[TabView class]]); | 165 DCHECK([tabView isKindOfClass:[TabView class]]); |
158 [tabView startAlert]; | 166 [tabView startAlert]; |
159 } | 167 } |
160 [super setTitle:title]; | 168 [super setTitle:title]; |
161 } | 169 } |
162 | 170 |
163 - (void)setSelected:(BOOL)selected { | 171 - (void)setSelected:(BOOL)selected { |
164 if (selected_ != selected) | 172 if (selected_ != selected) |
165 [self internalSetSelected:selected]; | 173 [self internalSetSelected:selected]; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 } | 209 } |
202 | 210 |
203 // Returns YES if we should show the icon. When tabs get too small, we clip | 211 // Returns YES if we should show the icon. When tabs get too small, we clip |
204 // the favicon before the close button for selected tabs, and prefer the | 212 // the favicon before the close button for selected tabs, and prefer the |
205 // favicon for unselected tabs. The icon can also be suppressed more directly | 213 // favicon for unselected tabs. The icon can also be suppressed more directly |
206 // by clearing iconView_. | 214 // by clearing iconView_. |
207 - (BOOL)shouldShowIcon { | 215 - (BOOL)shouldShowIcon { |
208 if (!iconView_) | 216 if (!iconView_) |
209 return NO; | 217 return NO; |
210 | 218 |
211 if ([self pinned]) | 219 if ([self mini]) |
212 return YES; | 220 return YES; |
213 | 221 |
214 int iconCapacity = [self iconCapacity]; | 222 int iconCapacity = [self iconCapacity]; |
215 if ([self selected]) | 223 if ([self selected]) |
216 return iconCapacity >= 2; | 224 return iconCapacity >= 2; |
217 return iconCapacity >= 1; | 225 return iconCapacity >= 1; |
218 } | 226 } |
219 | 227 |
220 // Returns YES if we should be showing the close button. The selected tab | 228 // Returns YES if we should be showing the close button. The selected tab |
221 // always shows the close button. | 229 // always shows the close button. |
222 - (BOOL)shouldShowCloseButton { | 230 - (BOOL)shouldShowCloseButton { |
223 if ([self pinned]) | 231 if ([self mini]) |
224 return NO; | 232 return NO; |
225 return ([self selected] || [self iconCapacity] >= 3); | 233 return ([self selected] || [self iconCapacity] >= 3); |
226 } | 234 } |
227 | 235 |
228 - (void)updateVisibility { | 236 - (void)updateVisibility { |
229 // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden] | 237 // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden] |
230 // won't work. Instead, the state of the icon is tracked separately in | 238 // won't work. Instead, the state of the icon is tracked separately in |
231 // isIconShowing_. | 239 // isIconShowing_. |
232 BOOL oldShowIcon = isIconShowing_ ? YES : NO; | 240 BOOL oldShowIcon = isIconShowing_ ? YES : NO; |
233 BOOL newShowIcon = [self shouldShowIcon] ? YES : NO; | 241 BOOL newShowIcon = [self shouldShowIcon] ? YES : NO; |
234 | 242 |
235 [iconView_ setHidden:newShowIcon ? NO : YES]; | 243 [iconView_ setHidden:newShowIcon ? NO : YES]; |
236 isIconShowing_ = newShowIcon; | 244 isIconShowing_ = newShowIcon; |
237 | 245 |
238 // If the tab is pinned, hide the title. | 246 // If the tab is a mini-tab, hide the title. |
239 [titleView_ setHidden:[self pinned]]; | 247 [titleView_ setHidden:[self mini]]; |
| 248 |
| 249 // If it's a phantom mini-tab, draw it alpha-style. Windows does this. |
| 250 CGFloat alphaValue = [self phantom] ? kPhantomTabAlpha |
| 251 : 1.0; |
| 252 [[self view] setAlphaValue:alphaValue]; |
240 | 253 |
241 BOOL oldShowCloseButton = [closeButton_ isHidden] ? NO : YES; | 254 BOOL oldShowCloseButton = [closeButton_ isHidden] ? NO : YES; |
242 BOOL newShowCloseButton = [self shouldShowCloseButton] ? YES : NO; | 255 BOOL newShowCloseButton = [self shouldShowCloseButton] ? YES : NO; |
243 | 256 |
244 [closeButton_ setHidden:newShowCloseButton ? NO : YES]; | 257 [closeButton_ setHidden:newShowCloseButton ? NO : YES]; |
245 | 258 |
246 // Adjust the title view based on changes to the icon's and close button's | 259 // Adjust the title view based on changes to the icon's and close button's |
247 // visibility. | 260 // visibility. |
248 NSRect titleFrame = [titleView_ frame]; | 261 NSRect titleFrame = [titleView_ frame]; |
249 | 262 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 // Called by the tabs to determine whether we are in rapid (tab) closure mode. | 316 // Called by the tabs to determine whether we are in rapid (tab) closure mode. |
304 - (BOOL)inRapidClosureMode { | 317 - (BOOL)inRapidClosureMode { |
305 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { | 318 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { |
306 return [[self target] performSelector:@selector(inRapidClosureMode)] ? | 319 return [[self target] performSelector:@selector(inRapidClosureMode)] ? |
307 YES : NO; | 320 YES : NO; |
308 } | 321 } |
309 return NO; | 322 return NO; |
310 } | 323 } |
311 | 324 |
312 @end | 325 @end |
OLD | NEW |