blob: cff9f818b9810cfdeb7a93309b331843e26a9ef6 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
// Copyright (c) 2009 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 "base/mac_util.h"
#include "chrome/browser/cocoa/nsimage_cache.h"
#import "chrome/browser/cocoa/tab_controller.h"
#import "chrome/browser/cocoa/tab_controller_target.h"
#import "chrome/browser/cocoa/tab_view.h"
@interface TabController(Private)
- (void)updateVisibility;
@end
@implementation TabController
@synthesize loadingState = loadingState_;
@synthesize target = target_;
@synthesize action = action_;
// 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 box width.
+ (float)minTabWidth { return 31; }
+ (float)minSelectedTabWidth { return 47; }
+ (float)maxTabWidth { return 220.0; }
- (TabView*)tabView {
return static_cast<TabView*>([self view]);
}
- (id)init {
self = [super initWithNibName:@"TabView" bundle:mac_util::MainAppBundle()];
if (self != nil) {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(viewResized:)
name:NSViewFrameDidChangeNotification
object:[self view]];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[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 *)[self view] setState:selected];
[self updateVisibility];
[[self view] setNeedsDisplay:YES];
}
// Called when the tab's nib is done loading and all outlets are hooked up.
- (void)awakeFromNib {
// Ensure we don't show favicon if the tab is already too small to begin with.
[self updateVisibility];
[(id)iconView_ setImage:nsimage_cache::ImageNamed(@"nav.pdf")];
[[self view] addSubview:backgroundButton_
positioned:NSWindowBelow
relativeTo:nil];
[self internalSetSelected:selected_];
}
- (IBAction)closeTab:(id)sender {
if ([[self target] respondsToSelector:@selector(closeTab:)]) {
[[self target] performSelector:@selector(closeTab:)
withObject:[self view]];
}
}
// Dispatches the command in the tag to the registered target object.
- (IBAction)commandDispatch:(id)sender {
TabStripModel::ContextMenuCommand command =
static_cast<TabStripModel::ContextMenuCommand>([sender tag]);
[[self target] commandDispatch:command forController:self];
}
// Called for each menu item on its target, which would be this controller.
// Returns YES if the menu item should be enabled. We ask the tab's
// target for the proper answer.
- (BOOL)validateMenuItem:(NSMenuItem*)item {
TabStripModel::ContextMenuCommand command =
static_cast<TabStripModel::ContextMenuCommand>([item tag]);
return [[self target] isCommandEnabled:command forController:self];
}
- (void)setTitle:(NSString *)title {
[backgroundButton_ setToolTip:title];
[super setTitle:title];
}
- (void)setSelected:(BOOL)selected {
if (selected_ != selected)
[self internalSetSelected:selected];
}
- (BOOL)selected {
return selected_;
}
- (void)setIconView:(NSView*)iconView {
NSRect currentFrame = [iconView_ frame];
[iconView_ removeFromSuperview];
iconView_ = iconView;
[iconView_ setFrame:currentFrame];
// Ensure we don't show favicon if the tab is already too small to begin with.
[self updateVisibility];
[[self view] addSubview:iconView_];
}
- (NSView*)iconView {
return iconView_;
}
- (NSString *)toolTip {
return [backgroundButton_ 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 {
float width = NSWidth([[self view] frame]);
float leftPadding = NSMinX([iconView_ frame]);
float rightPadding = width - NSMaxX([closeButton_ frame]);
float iconWidth = NSWidth([iconView_ frame]);
width -= leftPadding + rightPadding;
return width / iconWidth;
}
// Returns YES if we should show the icon. When tabs get too small, we clip
// the favicon before the close box for selected tabs, and prefer the favicon
// for unselected tabs.
// TODO(pinkerton): don't show the icon if there's no image data (eg, NTP).
- (BOOL)shouldShowIcon {
int iconCapacity = [self iconCapacity];
if ([self selected])
return iconCapacity >= 2;
return iconCapacity >= 1;
}
// Returns YES if we should be showing the close box. The selected tab always
// shows the close box.
- (BOOL)shouldShowCloseBox {
return [self selected] || [self iconCapacity] >= 3;
}
// Call to update the visibility of certain subviews, such as the icon or
// close box, based on criteria like if the tab is selected and the current
// tab width.
- (void)updateVisibility {
[iconView_ setHidden:[self shouldShowIcon] ? NO : YES];
[closeButton_ setHidden:[self shouldShowCloseBox] ? NO : YES];
}
// Called when our view is resized. If it gets too small, start by hiding
// the close box 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];
}
@end
|