| Index: chrome/browser/ui/cocoa/tab_controller.mm
|
| ===================================================================
|
| --- chrome/browser/ui/cocoa/tab_controller.mm (revision 71805)
|
| +++ chrome/browser/ui/cocoa/tab_controller.mm (working copy)
|
| @@ -1,306 +0,0 @@
|
| -// Copyright (c) 2010 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.
|
| -
|
| -#include "app/l10n_util_mac.h"
|
| -#include "base/mac/mac_util.h"
|
| -#import "chrome/browser/themes/browser_theme_provider.h"
|
| -#import "chrome/browser/ui/cocoa/menu_controller.h"
|
| -#import "chrome/browser/ui/cocoa/tab_controller.h"
|
| -#import "chrome/browser/ui/cocoa/tab_controller_target.h"
|
| -#import "chrome/browser/ui/cocoa/tab_view.h"
|
| -#import "chrome/browser/ui/cocoa/themed_window.h"
|
| -#import "chrome/common/extensions/extension.h"
|
| -#include "grit/generated_resources.h"
|
| -
|
| -@implementation TabController
|
| -
|
| -@synthesize action = action_;
|
| -@synthesize app = app_;
|
| -@synthesize loadingState = loadingState_;
|
| -@synthesize mini = mini_;
|
| -@synthesize pinned = pinned_;
|
| -@synthesize target = target_;
|
| -@synthesize iconView = iconView_;
|
| -@synthesize titleView = titleView_;
|
| -@synthesize closeButton = closeButton_;
|
| -
|
| -namespace TabControllerInternal {
|
| -
|
| -// A C++ delegate that handles enabling/disabling menu items and handling when
|
| -// a menu command is chosen. Also fixes up the menu item label for "pin/unpin
|
| -// tab".
|
| -class MenuDelegate : public ui::SimpleMenuModel::Delegate {
|
| - public:
|
| - explicit MenuDelegate(id<TabControllerTarget> target, TabController* owner)
|
| - : target_(target),
|
| - owner_(owner) {}
|
| -
|
| - // Overridden from ui::SimpleMenuModel::Delegate
|
| - virtual bool IsCommandIdChecked(int command_id) const { return false; }
|
| - virtual bool IsCommandIdEnabled(int command_id) const {
|
| - TabStripModel::ContextMenuCommand command =
|
| - static_cast<TabStripModel::ContextMenuCommand>(command_id);
|
| - return [target_ isCommandEnabled:command forController:owner_];
|
| - }
|
| - virtual bool GetAcceleratorForCommandId(
|
| - int command_id,
|
| - ui::Accelerator* accelerator) { return false; }
|
| - virtual void ExecuteCommand(int command_id) {
|
| - TabStripModel::ContextMenuCommand command =
|
| - static_cast<TabStripModel::ContextMenuCommand>(command_id);
|
| - [target_ commandDispatch:command forController:owner_];
|
| - }
|
| -
|
| - private:
|
| - id<TabControllerTarget> target_; // weak
|
| - TabController* owner_; // weak, owns me
|
| -};
|
| -
|
| -} // TabControllerInternal namespace
|
| -
|
| -// The min widths match the windows values and are sums of left + right
|
| -// padding, of which we have no comparable constants (we draw using paths, not
|
| -// images). The selected tab width includes the close button width.
|
| -+ (CGFloat)minTabWidth { return 31; }
|
| -+ (CGFloat)minSelectedTabWidth { return 46; }
|
| -+ (CGFloat)maxTabWidth { return 220; }
|
| -+ (CGFloat)miniTabWidth { return 53; }
|
| -+ (CGFloat)appTabWidth { return 66; }
|
| -
|
| -- (TabView*)tabView {
|
| - return static_cast<TabView*>([self view]);
|
| -}
|
| -
|
| -- (id)init {
|
| - self = [super initWithNibName:@"TabView" bundle:base::mac::MainAppBundle()];
|
| - if (self != nil) {
|
| - isIconShowing_ = YES;
|
| - NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter];
|
| - [defaultCenter addObserver:self
|
| - selector:@selector(viewResized:)
|
| - name:NSViewFrameDidChangeNotification
|
| - object:[self view]];
|
| - [defaultCenter addObserver:self
|
| - selector:@selector(themeChangedNotification:)
|
| - name:kBrowserThemeDidChangeNotification
|
| - object:nil];
|
| - }
|
| - return self;
|
| -}
|
| -
|
| -- (void)dealloc {
|
| - [[NSNotificationCenter defaultCenter] removeObserver:self];
|
| - [[self tabView] setController:nil];
|
| - [super dealloc];
|
| -}
|
| -
|
| -// The internals of |-setSelected:| but doesn't check if we're already set
|
| -// to |selected|. Pass the selection change to the subviews that need it and
|
| -// mark ourselves as needing a redraw.
|
| -- (void)internalSetSelected:(BOOL)selected {
|
| - selected_ = selected;
|
| - TabView* tabView = static_cast<TabView*>([self view]);
|
| - DCHECK([tabView isKindOfClass:[TabView class]]);
|
| - [tabView setState:selected];
|
| - [tabView cancelAlert];
|
| - [self updateVisibility];
|
| - [self updateTitleColor];
|
| -}
|
| -
|
| -// Called when the tab's nib is done loading and all outlets are hooked up.
|
| -- (void)awakeFromNib {
|
| - // Remember the icon's frame, so that if the icon is ever removed, a new
|
| - // one can later replace it in the proper location.
|
| - originalIconFrame_ = [iconView_ frame];
|
| -
|
| - // When the icon is removed, the title expands to the left to fill the space
|
| - // left by the icon. When the close button is removed, the title expands to
|
| - // the right to fill its space. These are the amounts to expand and contract
|
| - // titleView_ under those conditions. We don't have to explicilty save the
|
| - // offset between the title and the close button since we can just get that
|
| - // value for the close button's frame.
|
| - NSRect titleFrame = [titleView_ frame];
|
| - iconTitleXOffset_ = NSMinX(titleFrame) - NSMinX(originalIconFrame_);
|
| -
|
| - [self internalSetSelected:selected_];
|
| -}
|
| -
|
| -// Called when Cocoa wants to display the context menu. Lazily instantiate
|
| -// the menu based off of the cross-platform model. Re-create the menu and
|
| -// model every time to get the correct labels and enabling.
|
| -- (NSMenu*)menu {
|
| - contextMenuDelegate_.reset(
|
| - new TabControllerInternal::MenuDelegate(target_, self));
|
| - contextMenuModel_.reset(new TabMenuModel(contextMenuDelegate_.get(),
|
| - [self pinned]));
|
| - contextMenuController_.reset(
|
| - [[MenuController alloc] initWithModel:contextMenuModel_.get()
|
| - useWithPopUpButtonCell:NO]);
|
| - return [contextMenuController_ menu];
|
| -}
|
| -
|
| -- (IBAction)closeTab:(id)sender {
|
| - if ([[self target] respondsToSelector:@selector(closeTab:)]) {
|
| - [[self target] performSelector:@selector(closeTab:)
|
| - withObject:[self view]];
|
| - }
|
| -}
|
| -
|
| -- (void)setTitle:(NSString*)title {
|
| - [[self view] setToolTip:title];
|
| - if ([self mini] && ![self selected]) {
|
| - TabView* tabView = static_cast<TabView*>([self view]);
|
| - DCHECK([tabView isKindOfClass:[TabView class]]);
|
| - [tabView startAlert];
|
| - }
|
| - [super setTitle:title];
|
| -}
|
| -
|
| -- (void)setSelected:(BOOL)selected {
|
| - if (selected_ != selected)
|
| - [self internalSetSelected:selected];
|
| -}
|
| -
|
| -- (BOOL)selected {
|
| - return selected_;
|
| -}
|
| -
|
| -- (void)setIconView:(NSView*)iconView {
|
| - [iconView_ removeFromSuperview];
|
| - iconView_ = iconView;
|
| - if ([self app]) {
|
| - NSRect appIconFrame = [iconView frame];
|
| - appIconFrame.origin = originalIconFrame_.origin;
|
| - // Center the icon.
|
| - appIconFrame.origin.x = ([TabController appTabWidth] -
|
| - NSWidth(appIconFrame)) / 2.0;
|
| - [iconView setFrame:appIconFrame];
|
| - } else {
|
| - [iconView_ setFrame:originalIconFrame_];
|
| - }
|
| - // Ensure that the icon is suppressed if no icon is set or if the tab is too
|
| - // narrow to display one.
|
| - [self updateVisibility];
|
| -
|
| - if (iconView_)
|
| - [[self view] addSubview:iconView_];
|
| -}
|
| -
|
| -- (NSString*)toolTip {
|
| - return [[self view] toolTip];
|
| -}
|
| -
|
| -// Return a rough approximation of the number of icons we could fit in the
|
| -// tab. We never actually do this, but it's a helpful guide for determining
|
| -// how much space we have available.
|
| -- (int)iconCapacity {
|
| - CGFloat width = NSMaxX([closeButton_ frame]) - NSMinX(originalIconFrame_);
|
| - CGFloat iconWidth = NSWidth(originalIconFrame_);
|
| -
|
| - return width / iconWidth;
|
| -}
|
| -
|
| -// Returns YES if we should show the icon. When tabs get too small, we clip
|
| -// the favicon before the close button for selected tabs, and prefer the
|
| -// favicon for unselected tabs. The icon can also be suppressed more directly
|
| -// by clearing iconView_.
|
| -- (BOOL)shouldShowIcon {
|
| - if (!iconView_)
|
| - return NO;
|
| -
|
| - if ([self mini])
|
| - return YES;
|
| -
|
| - int iconCapacity = [self iconCapacity];
|
| - if ([self selected])
|
| - return iconCapacity >= 2;
|
| - return iconCapacity >= 1;
|
| -}
|
| -
|
| -// Returns YES if we should be showing the close button. The selected tab
|
| -// always shows the close button.
|
| -- (BOOL)shouldShowCloseButton {
|
| - if ([self mini])
|
| - return NO;
|
| - return ([self selected] || [self iconCapacity] >= 3);
|
| -}
|
| -
|
| -- (void)updateVisibility {
|
| - // iconView_ may have been replaced or it may be nil, so [iconView_ isHidden]
|
| - // won't work. Instead, the state of the icon is tracked separately in
|
| - // isIconShowing_.
|
| - BOOL newShowIcon = [self shouldShowIcon];
|
| -
|
| - [iconView_ setHidden:!newShowIcon];
|
| - isIconShowing_ = newShowIcon;
|
| -
|
| - // If the tab is a mini-tab, hide the title.
|
| - [titleView_ setHidden:[self mini]];
|
| -
|
| - BOOL newShowCloseButton = [self shouldShowCloseButton];
|
| -
|
| - [closeButton_ setHidden:!newShowCloseButton];
|
| -
|
| - // Adjust the title view based on changes to the icon's and close button's
|
| - // visibility.
|
| - NSRect oldTitleFrame = [titleView_ frame];
|
| - NSRect newTitleFrame;
|
| - newTitleFrame.size.height = oldTitleFrame.size.height;
|
| - newTitleFrame.origin.y = oldTitleFrame.origin.y;
|
| -
|
| - if (newShowIcon) {
|
| - newTitleFrame.origin.x = originalIconFrame_.origin.x + iconTitleXOffset_;
|
| - } else {
|
| - newTitleFrame.origin.x = originalIconFrame_.origin.x;
|
| - }
|
| -
|
| - if (newShowCloseButton) {
|
| - newTitleFrame.size.width = NSMinX([closeButton_ frame]) -
|
| - newTitleFrame.origin.x;
|
| - } else {
|
| - newTitleFrame.size.width = NSMaxX([closeButton_ frame]) -
|
| - newTitleFrame.origin.x;
|
| - }
|
| -
|
| - [titleView_ setFrame:newTitleFrame];
|
| -}
|
| -
|
| -- (void)updateTitleColor {
|
| - NSColor* titleColor = nil;
|
| - ThemeProvider* theme = [[[self view] window] themeProvider];
|
| - if (theme && ![self selected]) {
|
| - titleColor =
|
| - theme->GetNSColor(BrowserThemeProvider::COLOR_BACKGROUND_TAB_TEXT,
|
| - true);
|
| - }
|
| - // Default to the selected text color unless told otherwise.
|
| - if (theme && !titleColor) {
|
| - titleColor = theme->GetNSColor(BrowserThemeProvider::COLOR_TAB_TEXT,
|
| - true);
|
| - }
|
| - [titleView_ setTextColor:titleColor ? titleColor : [NSColor textColor]];
|
| -}
|
| -
|
| -// Called when our view is resized. If it gets too small, start by hiding
|
| -// the close button and only show it if tab is selected. Eventually, hide the
|
| -// icon as well. We know that this is for our view because we only registered
|
| -// for notifications from our specific view.
|
| -- (void)viewResized:(NSNotification*)info {
|
| - [self updateVisibility];
|
| -}
|
| -
|
| -- (void)themeChangedNotification:(NSNotification*)notification {
|
| - [self updateTitleColor];
|
| -}
|
| -
|
| -// Called by the tabs to determine whether we are in rapid (tab) closure mode.
|
| -- (BOOL)inRapidClosureMode {
|
| - if ([[self target] respondsToSelector:@selector(inRapidClosureMode)]) {
|
| - return [[self target] performSelector:@selector(inRapidClosureMode)] ?
|
| - YES : NO;
|
| - }
|
| - return NO;
|
| -}
|
| -
|
| -@end
|
|
|