| 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 "base/mac_util.h" | 5 #include "base/mac_util.h" |
| 6 #import "chrome/browser/cocoa/tab_controller.h" | 6 #import "chrome/browser/cocoa/tab_controller.h" |
| 7 #import "chrome/browser/cocoa/tab_controller_target.h" | 7 #import "chrome/browser/cocoa/tab_controller_target.h" |
| 8 #import "chrome/browser/cocoa/tab_view.h" | 8 #import "chrome/browser/cocoa/tab_view.h" |
| 9 #import "third_party/GTM/AppKit/GTMTheme.h" | 9 #import "third_party/GTM/AppKit/GTMTheme.h" |
| 10 | 10 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 + (float)maxTabWidth { return 220; } | 26 + (float)maxTabWidth { return 220; } |
| 27 | 27 |
| 28 - (TabView*)tabView { | 28 - (TabView*)tabView { |
| 29 return static_cast<TabView*>([self view]); | 29 return static_cast<TabView*>([self view]); |
| 30 } | 30 } |
| 31 | 31 |
| 32 - (id)init { | 32 - (id)init { |
| 33 self = [super initWithNibName:@"TabView" bundle:mac_util::MainAppBundle()]; | 33 self = [super initWithNibName:@"TabView" bundle:mac_util::MainAppBundle()]; |
| 34 if (self != nil) { | 34 if (self != nil) { |
| 35 isIconShowing_ = YES; | 35 isIconShowing_ = YES; |
| 36 [[NSNotificationCenter defaultCenter] | 36 NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; |
| 37 addObserver:self | 37 [defaultCenter addObserver:self |
| 38 selector:@selector(viewResized:) | 38 selector:@selector(viewResized:) |
| 39 name:NSViewFrameDidChangeNotification | 39 name:NSViewFrameDidChangeNotification |
| 40 object:[self view]]; | 40 object:[self view]]; |
| 41 [defaultCenter addObserver:self |
| 42 selector:@selector(themeChangedNotification:) |
| 43 name:kGTMThemeDidChangeNotification |
| 44 object:nil]; |
| 41 } | 45 } |
| 42 return self; | 46 return self; |
| 43 } | 47 } |
| 44 | 48 |
| 45 - (void)dealloc { | 49 - (void)dealloc { |
| 46 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 50 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 47 [super dealloc]; | 51 [super dealloc]; |
| 48 } | 52 } |
| 49 | 53 |
| 50 // The internals of |-setSelected:| but doesn't check if we're already set | 54 // The internals of |-setSelected:| but doesn't check if we're already set |
| 51 // to |selected|. Pass the selection change to the subviews that need it and | 55 // to |selected|. Pass the selection change to the subviews that need it and |
| 52 // mark ourselves as needing a redraw. | 56 // mark ourselves as needing a redraw. |
| 53 - (void)internalSetSelected:(BOOL)selected { | 57 - (void)internalSetSelected:(BOOL)selected { |
| 54 selected_ = selected; | 58 selected_ = selected; |
| 55 [(TabView *)[self view] setState:selected]; | 59 TabView* tabView = static_cast<TabView*>([self view]); |
| 60 [tabView setState:selected]; |
| 56 [self updateVisibility]; | 61 [self updateVisibility]; |
| 57 [self applyTheme]; | 62 [self updateTitleColor]; |
| 58 } | 63 } |
| 59 | 64 |
| 60 // Called when the tab's nib is done loading and all outlets are hooked up. | 65 // Called when the tab's nib is done loading and all outlets are hooked up. |
| 61 - (void)awakeFromNib { | 66 - (void)awakeFromNib { |
| 62 // Remember the icon's frame, so that if the icon is ever removed, a new | 67 // Remember the icon's frame, so that if the icon is ever removed, a new |
| 63 // one can later replace it in the proper location. | 68 // one can later replace it in the proper location. |
| 64 originalIconFrame_ = [iconView_ frame]; | 69 originalIconFrame_ = [iconView_ frame]; |
| 65 | 70 |
| 66 // When the icon is removed, the title expands to the left to fill the space | 71 // When the icon is removed, the title expands to the left to fill the space |
| 67 // left by the icon. When the close button is removed, the title expands to | 72 // left by the icon. When the close button is removed, the title expands to |
| 68 // the right to fill its space. These are the amounts to expand and contract | 73 // the right to fill its space. These are the amounts to expand and contract |
| 69 // titleView_ under those conditions. | 74 // titleView_ under those conditions. |
| 70 NSRect titleFrame = [titleView_ frame]; | 75 NSRect titleFrame = [titleView_ frame]; |
| 71 iconTitleXOffset_ = NSMinX(titleFrame) - NSMinX(originalIconFrame_); | 76 iconTitleXOffset_ = NSMinX(titleFrame) - NSMinX(originalIconFrame_); |
| 72 titleCloseWidthOffset_ = NSMaxX([closeButton_ frame]) - NSMaxX(titleFrame); | 77 titleCloseWidthOffset_ = NSMaxX([closeButton_ frame]) - NSMaxX(titleFrame); |
| 73 | 78 |
| 74 // Ensure we don't show favicon if the tab is already too small to begin with. | |
| 75 [self updateVisibility]; | |
| 76 | |
| 77 [self internalSetSelected:selected_]; | 79 [self internalSetSelected:selected_]; |
| 78 } | 80 } |
| 79 | 81 |
| 80 - (IBAction)closeTab:(id)sender { | 82 - (IBAction)closeTab:(id)sender { |
| 81 if ([[self target] respondsToSelector:@selector(closeTab:)]) { | 83 if ([[self target] respondsToSelector:@selector(closeTab:)]) { |
| 82 [[self target] performSelector:@selector(closeTab:) | 84 [[self target] performSelector:@selector(closeTab:) |
| 83 withObject:[self view]]; | 85 withObject:[self view]]; |
| 84 } | 86 } |
| 85 } | 87 } |
| 86 | 88 |
| 87 // Dispatches the command in the tag to the registered target object. | 89 // Dispatches the command in the tag to the registered target object. |
| 88 - (IBAction)commandDispatch:(id)sender { | 90 - (IBAction)commandDispatch:(id)sender { |
| 89 TabStripModel::ContextMenuCommand command = | 91 TabStripModel::ContextMenuCommand command = |
| 90 static_cast<TabStripModel::ContextMenuCommand>([sender tag]); | 92 static_cast<TabStripModel::ContextMenuCommand>([sender tag]); |
| 91 [[self target] commandDispatch:command forController:self]; | 93 [[self target] commandDispatch:command forController:self]; |
| 92 } | 94 } |
| 93 | 95 |
| 94 // Called for each menu item on its target, which would be this controller. | 96 // Called for each menu item on its target, which would be this controller. |
| 95 // Returns YES if the menu item should be enabled. We ask the tab's | 97 // Returns YES if the menu item should be enabled. We ask the tab's |
| 96 // target for the proper answer. | 98 // target for the proper answer. |
| 97 - (BOOL)validateMenuItem:(NSMenuItem*)item { | 99 - (BOOL)validateMenuItem:(NSMenuItem*)item { |
| 98 TabStripModel::ContextMenuCommand command = | 100 TabStripModel::ContextMenuCommand command = |
| 99 static_cast<TabStripModel::ContextMenuCommand>([item tag]); | 101 static_cast<TabStripModel::ContextMenuCommand>([item tag]); |
| 100 return [[self target] isCommandEnabled:command forController:self]; | 102 return [[self target] isCommandEnabled:command forController:self]; |
| 101 } | 103 } |
| 102 | 104 |
| 103 - (void)setTitle:(NSString *)title { | 105 - (void)setTitle:(NSString*)title { |
| 104 [[self view] setToolTip:title]; | 106 [[self view] setToolTip:title]; |
| 105 [super setTitle:title]; | 107 [super setTitle:title]; |
| 106 } | 108 } |
| 107 | 109 |
| 108 - (void)setSelected:(BOOL)selected { | 110 - (void)setSelected:(BOOL)selected { |
| 109 if (selected_ != selected) | 111 if (selected_ != selected) |
| 110 [self internalSetSelected:selected]; | 112 [self internalSetSelected:selected]; |
| 111 } | 113 } |
| 112 | 114 |
| 113 - (BOOL)selected { | 115 - (BOOL)selected { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 124 [self updateVisibility]; | 126 [self updateVisibility]; |
| 125 | 127 |
| 126 if (iconView_) | 128 if (iconView_) |
| 127 [[self view] addSubview:iconView_]; | 129 [[self view] addSubview:iconView_]; |
| 128 } | 130 } |
| 129 | 131 |
| 130 - (NSView*)iconView { | 132 - (NSView*)iconView { |
| 131 return iconView_; | 133 return iconView_; |
| 132 } | 134 } |
| 133 | 135 |
| 134 - (NSString *)toolTip { | 136 - (NSString*)toolTip { |
| 135 return [[self view] toolTip]; | 137 return [[self view] toolTip]; |
| 136 } | 138 } |
| 137 | 139 |
| 138 // Return a rough approximation of the number of icons we could fit in the | 140 // Return a rough approximation of the number of icons we could fit in the |
| 139 // tab. We never actually do this, but it's a helpful guide for determining | 141 // tab. We never actually do this, but it's a helpful guide for determining |
| 140 // how much space we have available. | 142 // how much space we have available. |
| 141 - (int)iconCapacity { | 143 - (int)iconCapacity { |
| 142 float width = NSMaxX([closeButton_ frame]) - NSMinX(originalIconFrame_); | 144 float width = NSMaxX([closeButton_ frame]) - NSMinX(originalIconFrame_); |
| 143 float iconWidth = NSWidth(originalIconFrame_); | 145 float iconWidth = NSWidth(originalIconFrame_); |
| 144 | 146 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 // absence of the close button. | 207 // absence of the close button. |
| 206 if (newShowCloseButton) | 208 if (newShowCloseButton) |
| 207 titleFrame.size.width -= titleCloseWidthOffset_; | 209 titleFrame.size.width -= titleCloseWidthOffset_; |
| 208 else | 210 else |
| 209 titleFrame.size.width += titleCloseWidthOffset_; | 211 titleFrame.size.width += titleCloseWidthOffset_; |
| 210 } | 212 } |
| 211 | 213 |
| 212 [titleView_ setFrame:titleFrame]; | 214 [titleView_ setFrame:titleFrame]; |
| 213 } | 215 } |
| 214 | 216 |
| 217 - (void)updateTitleColor { |
| 218 NSColor* titleColor = nil; |
| 219 GTMTheme* theme = [[self view] gtm_theme]; |
| 220 if (![self selected]) { |
| 221 titleColor = [theme textColorForStyle:GTMThemeStyleTabBarDeselected |
| 222 state:GTMThemeStateActiveWindow]; |
| 223 } |
| 224 // Default to the selected text color unless told otherwise. |
| 225 if (!titleColor) { |
| 226 titleColor = [theme textColorForStyle:GTMThemeStyleTabBarSelected |
| 227 state:GTMThemeStateActiveWindow]; |
| 228 } |
| 229 [titleView_ setTextColor:titleColor ? titleColor : [NSColor textColor]]; |
| 230 } |
| 231 |
| 215 // Called when our view is resized. If it gets too small, start by hiding | 232 // Called when our view is resized. If it gets too small, start by hiding |
| 216 // the close button and only show it if tab is selected. Eventually, hide the | 233 // the close button and only show it if tab is selected. Eventually, hide the |
| 217 // icon as well. We know that this is for our view because we only registered | 234 // icon as well. We know that this is for our view because we only registered |
| 218 // for notifications from our specific view. | 235 // for notifications from our specific view. |
| 219 - (void)viewResized:(NSNotification*)info { | 236 - (void)viewResized:(NSNotification*)info { |
| 220 [self updateVisibility]; | 237 [self updateVisibility]; |
| 221 } | 238 } |
| 222 | 239 |
| 223 - (void)applyTheme { | 240 - (void)themeChangedNotification:(NSNotification*)notification { |
| 224 GTMTheme* theme = [[self view] gtm_theme]; | 241 GTMTheme* theme = [notification object]; |
| 225 NSColor* color = nil; | 242 NSView* view = [self view]; |
| 226 if (!selected_) { | 243 if ([theme isEqual:[view gtm_theme]]) { |
| 227 color = [theme textColorForStyle:GTMThemeStyleTabBarDeselected | 244 [self updateTitleColor]; |
| 228 state:GTMThemeStateActiveWindow]; | |
| 229 } | 245 } |
| 230 // Default to the selected text color unless told otherwise. | |
| 231 if (!color) { | |
| 232 color = [theme textColorForStyle:GTMThemeStyleToolBar | |
| 233 state:GTMThemeStateActiveWindow]; | |
| 234 } | |
| 235 | |
| 236 [titleView_ setTextColor:color ? color : [NSColor textColor]]; | |
| 237 [[self view] setNeedsDisplay:YES]; | |
| 238 } | 246 } |
| 239 | 247 |
| 240 // Called by the tabs to determine whether we are in rapid (tab) closure mode. | 248 // Called by the tabs to determine whether we are in rapid (tab) closure mode. |
| 241 - (BOOL)inRapidClosureMode { | 249 - (BOOL)inRapidClosureMode { |
| 242 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { | 250 if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) { |
| 243 return [[self target] performSelector:@selector(inRapidClosureMode)] ? | 251 return [[self target] performSelector:@selector(inRapidClosureMode)] ? |
| 244 YES : NO; | 252 YES : NO; |
| 245 } | 253 } |
| 246 return NO; | 254 return NO; |
| 247 } | 255 } |
| 248 | 256 |
| 249 @end | 257 @end |
| OLD | NEW |