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 #import "chrome/browser/cocoa/tab_contents_controller.h" | 5 #import "chrome/browser/cocoa/tab_contents_controller.h" |
6 | 6 |
7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
8 #include "chrome/app/chrome_dll_resource.h" | |
9 #include "chrome/browser/bookmarks/bookmark_model.h" | 8 #include "chrome/browser/bookmarks/bookmark_model.h" |
10 #import "chrome/browser/cocoa/location_bar_view_mac.h" | |
11 #include "chrome/browser/command_updater.h" | |
12 #include "chrome/browser/tab_contents/tab_contents.h" | 9 #include "chrome/browser/tab_contents/tab_contents.h" |
13 #include "chrome/browser/toolbar_model.h" | |
14 | |
15 // Names of images in the bundle for the star icon (normal and 'starred'). | |
16 static NSString* const kStarImageName = @"star"; | |
17 static NSString* const kStarredImageName = @"starred"; | |
18 | |
19 @interface TabContentsController(CommandUpdates) | |
20 - (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled; | |
21 @end | |
22 | 10 |
23 @interface TabContentsController(Private) | 11 @interface TabContentsController(Private) |
24 - (void)updateToolbarCommandStatus; | |
25 - (void)applyContentsBoxOffset:(BOOL)apply; | 12 - (void)applyContentsBoxOffset:(BOOL)apply; |
26 @end | 13 @end |
27 | 14 |
28 // A C++ bridge class that handles listening for updates to commands and | |
29 // passing them back to the controller. | |
30 class TabContentsCommandObserver : public CommandUpdater::CommandObserver { | |
31 public: | |
32 TabContentsCommandObserver(TabContentsController* controller, | |
33 CommandUpdater* commands); | |
34 ~TabContentsCommandObserver(); | |
35 | |
36 // Overridden from CommandUpdater::CommandObserver | |
37 void EnabledStateChangedForCommand(int command, bool enabled); | |
38 | |
39 private: | |
40 TabContentsController* controller_; // weak, owns me | |
41 CommandUpdater* commands_; // weak | |
42 }; | |
43 | |
44 @implementation TabContentsController | 15 @implementation TabContentsController |
45 | 16 |
46 - (id)initWithNibName:(NSString*)name | 17 - (id)initWithNibName:(NSString*)name |
47 bundle:(NSBundle*)bundle | 18 bundle:(NSBundle*)bundle |
48 contents:(TabContents*)contents | 19 contents:(TabContents*)contents |
49 commands:(CommandUpdater*)commands | |
50 toolbarModel:(ToolbarModel*)toolbarModel | |
51 bookmarkModel:(BookmarkModel*)bookmarkModel { | 20 bookmarkModel:(BookmarkModel*)bookmarkModel { |
52 if ((self = [super initWithNibName:name bundle:bundle])) { | 21 if ((self = [super initWithNibName:name bundle:bundle])) { |
53 commands_ = commands; | |
54 if (commands_) | |
55 observer_ = new TabContentsCommandObserver(self, commands); | |
56 contents_ = contents; | 22 contents_ = contents; |
57 toolbarModel_ = toolbarModel; | |
58 bookmarkModel_ = bookmarkModel; | 23 bookmarkModel_ = bookmarkModel; |
59 } | 24 } |
60 return self; | 25 return self; |
61 } | 26 } |
62 | 27 |
63 - (void)dealloc { | 28 - (void)dealloc { |
64 // make sure our contents have been removed from the window | 29 // make sure our contents have been removed from the window |
65 [[self view] removeFromSuperview]; | 30 [[self view] removeFromSuperview]; |
66 delete observer_; | |
67 delete locationBarView_; | |
68 [super dealloc]; | 31 [super dealloc]; |
69 } | 32 } |
70 | 33 |
71 - (void)awakeFromNib { | 34 - (void)awakeFromNib { |
72 [contentsBox_ setContentView:contents_->GetNativeView()]; | 35 [contentsBox_ setContentView:contents_->GetNativeView()]; |
73 [self applyContentsBoxOffset:YES]; | 36 [self applyContentsBoxOffset:YES]; |
74 | |
75 // Provide a starting point since we won't get notifications if the state | |
76 // doesn't change between tabs. | |
77 [self updateToolbarCommandStatus]; | |
78 | |
79 locationBarView_ = new LocationBarViewMac(locationBar_); | |
80 locationBarView_->Init(); | |
81 | |
82 [locationBar_ setStringValue:@"http://dev.chromium.org"]; | |
83 } | |
84 | |
85 - (LocationBar*)locationBar { | |
86 return locationBarView_; | |
87 } | 37 } |
88 | 38 |
89 // Returns YES if the tab represented by this controller is the front-most. | 39 // Returns YES if the tab represented by this controller is the front-most. |
90 - (BOOL)isCurrentTab { | 40 - (BOOL)isCurrentTab { |
91 // We're the current tab if we're in the view hierarchy, otherwise some other | 41 // We're the current tab if we're in the view hierarchy, otherwise some other |
92 // tab is. | 42 // tab is. |
93 return [[self view] superview] ? YES : NO; | 43 return [[self view] superview] ? YES : NO; |
94 } | 44 } |
95 | 45 |
96 // Called when the state for a command changes to |enabled|. Update the | |
97 // corresponding UI element. | |
98 - (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled { | |
99 // We don't need to update anything if we're not the frontmost tab. | |
100 // TODO(pinkerton): i'm worried that observer ordering could cause the | |
101 // notification to be sent before we've been put into the view, but we | |
102 // appear to be called in the right order so far. | |
103 if (![self isCurrentTab]) | |
104 return; | |
105 | |
106 NSButton* button = nil; | |
107 switch (command) { | |
108 case IDC_BACK: | |
109 button = backButton_; | |
110 break; | |
111 case IDC_FORWARD: | |
112 button = forwardButton_; | |
113 break; | |
114 case IDC_HOME: | |
115 // TODO(pinkerton): add home button | |
116 break; | |
117 case IDC_STAR: | |
118 button = starButton_; | |
119 break; | |
120 } | |
121 [button setEnabled:enabled]; | |
122 } | |
123 | |
124 - (IBAction)fullScreen:(id)sender { | 46 - (IBAction)fullScreen:(id)sender { |
125 if ([[self view] isInFullScreenMode]) { | 47 if ([[self view] isInFullScreenMode]) { |
126 [[self view] exitFullScreenModeWithOptions:nil]; | 48 [[self view] exitFullScreenModeWithOptions:nil]; |
127 } else { | 49 } else { |
128 [[self view] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; | 50 [[self view] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; |
129 } | 51 } |
130 } | 52 } |
131 | 53 |
132 // Set the enabled state of the buttons on the toolbar to match the state in | |
133 // the controller. We can't only rely on notifications to do this because the | |
134 // command model only assumes a single toolbar and won't send notifications if | |
135 // the state doesn't change. | |
136 - (void)updateToolbarCommandStatus { | |
137 [backButton_ setEnabled:commands_->IsCommandEnabled(IDC_BACK) ? YES : NO]; | |
138 [forwardButton_ | |
139 setEnabled:commands_->IsCommandEnabled(IDC_FORWARD) ? YES : NO]; | |
140 [reloadButton_ | |
141 setEnabled:commands_->IsCommandEnabled(IDC_RELOAD) ? YES : NO]; | |
142 [starButton_ setEnabled:commands_->IsCommandEnabled(IDC_STAR) ? YES : NO]; | |
143 } | |
144 | |
145 - (void)willBecomeSelectedTab { | 54 - (void)willBecomeSelectedTab { |
146 [self updateToolbarCommandStatus]; | |
147 } | 55 } |
148 | 56 |
149 - (void)tabDidChange:(TabContents*)updatedContents { | 57 - (void)tabDidChange:(TabContents*)updatedContents { |
150 contents_ = updatedContents; | 58 contents_ = updatedContents; |
151 [contentsBox_ setContentView:contents_->GetNativeView()]; | 59 [contentsBox_ setContentView:contents_->GetNativeView()]; |
152 } | 60 } |
153 | 61 |
154 - (void)focusLocationBar { | |
155 if (locationBarView_) { | |
156 locationBarView_->FocusLocation(); | |
157 } | |
158 } | |
159 | |
160 - (void)updateToolbarWithContents:(TabContents*)tab { | |
161 // TODO(pinkerton): there's a lot of ui code in autocomplete_edit.cc | |
162 // that we'll want to duplicate. For now, just handle setting the text. | |
163 | |
164 // TODO(pinkerton): update the security lock icon and background color | |
165 | |
166 NSString* urlString = base::SysWideToNSString(toolbarModel_->GetText()); | |
167 [locationBar_ setStringValue:urlString]; | |
168 } | |
169 | |
170 - (void)setStarredState:(BOOL)isStarred { | |
171 NSString* starImageName = kStarImageName; | |
172 if (isStarred) | |
173 starImageName = kStarredImageName; | |
174 [starButton_ setImage:[NSImage imageNamed:starImageName]]; | |
175 } | |
176 | |
177 // Return the rect, in WebKit coordinates (flipped), of the window's grow box | 62 // Return the rect, in WebKit coordinates (flipped), of the window's grow box |
178 // in the coordinate system of the content area of this tab. | 63 // in the coordinate system of the content area of this tab. |
179 - (NSRect)growBoxRect { | 64 - (NSRect)growBoxRect { |
180 NSRect localGrowBox = NSMakeRect(0, 0, 0, 0); | 65 NSRect localGrowBox = NSMakeRect(0, 0, 0, 0); |
181 NSView* contentView = contents_->GetNativeView(); | 66 NSView* contentView = contents_->GetNativeView(); |
182 if (contentView) { | 67 if (contentView) { |
183 // For the rect, we start with the grow box view which is a sibling of | 68 // For the rect, we start with the grow box view which is a sibling of |
184 // the content view's containing box. It's in the coordinate system of | 69 // the content view's containing box. It's in the coordinate system of |
185 // the controller view. | 70 // the controller view. |
186 localGrowBox = [growBox_ frame]; | 71 localGrowBox = [growBox_ frame]; |
187 // The scrollbar assumes that the resizer goes all the way down to the | 72 // The scrollbar assumes that the resizer goes all the way down to the |
188 // bottom corner, so we ignore any y offset to the rect itself and use the | 73 // bottom corner, so we ignore any y offset to the rect itself and use the |
189 // entire bottom corner. | 74 // entire bottom corner. |
190 localGrowBox.origin.y = 0; | 75 localGrowBox.origin.y = 0; |
191 // Convert to the content view's coordinates. | 76 // Convert to the content view's coordinates. |
192 localGrowBox = [contentView convertRect:localGrowBox | 77 localGrowBox = [contentView convertRect:localGrowBox |
193 fromView:[self view]]; | 78 fromView:[self view]]; |
194 // Flip the rect in view coordinates | 79 // Flip the rect in view coordinates |
195 localGrowBox.origin.y = | 80 localGrowBox.origin.y = |
196 [contentView frame].size.height - localGrowBox.origin.y - | 81 [contentView frame].size.height - localGrowBox.origin.y - |
197 localGrowBox.size.height; | 82 localGrowBox.size.height; |
198 } | 83 } |
199 return localGrowBox; | 84 return localGrowBox; |
200 } | 85 } |
201 | 86 |
202 - (void)setIsLoading:(BOOL)isLoading { | |
203 NSString* imageName = @"go"; | |
204 if (isLoading) | |
205 imageName = @"stop"; | |
206 [goButton_ setImage:[NSImage imageNamed:imageName]]; | |
207 } | |
208 | |
209 - (void)toggleBookmarkBar:(BOOL)enable { | 87 - (void)toggleBookmarkBar:(BOOL)enable { |
210 contentsBoxHasOffset_ = enable; | 88 contentsBoxHasOffset_ = enable; |
211 [self applyContentsBoxOffset:enable]; | 89 [self applyContentsBoxOffset:enable]; |
212 | 90 |
213 if (enable) { | 91 if (enable) { |
214 // TODO(jrg): display something useful in the bookmark bar | 92 // TODO(jrg): display something useful in the bookmark bar |
215 // TODO(jrg): use a BookmarksView, not a ToolbarView | 93 // TODO(jrg): use a BookmarksView, not a ToolbarView |
216 // TODO(jrg): don't draw a border around it | 94 // TODO(jrg): don't draw a border around it |
217 // TODO(jrg): ... | 95 // TODO(jrg): ... |
218 } | 96 } |
(...skipping 22 matching lines...) Expand all Loading... |
241 frame.size.height += offset; | 119 frame.size.height += offset; |
242 | 120 |
243 // TODO(jrg): animate | 121 // TODO(jrg): animate |
244 [contentsBox_ setFrame:frame]; | 122 [contentsBox_ setFrame:frame]; |
245 | 123 |
246 [bookmarkView_ setNeedsDisplay:YES]; | 124 [bookmarkView_ setNeedsDisplay:YES]; |
247 [contentsBox_ setNeedsDisplay:YES]; | 125 [contentsBox_ setNeedsDisplay:YES]; |
248 } | 126 } |
249 | 127 |
250 @end | 128 @end |
251 | |
252 //-------------------------------------------------------------------------- | |
253 | |
254 TabContentsCommandObserver::TabContentsCommandObserver( | |
255 TabContentsController* controller, CommandUpdater* commands) | |
256 : controller_(controller), commands_(commands) { | |
257 DCHECK(controller_ && commands); | |
258 // Register for notifications about state changes for the toolbar buttons | |
259 commands_->AddCommandObserver(IDC_BACK, this); | |
260 commands_->AddCommandObserver(IDC_FORWARD, this); | |
261 commands_->AddCommandObserver(IDC_RELOAD, this); | |
262 commands_->AddCommandObserver(IDC_HOME, this); | |
263 commands_->AddCommandObserver(IDC_STAR, this); | |
264 } | |
265 | |
266 TabContentsCommandObserver::~TabContentsCommandObserver() { | |
267 // Unregister the notifications | |
268 commands_->RemoveCommandObserver(this); | |
269 } | |
270 | |
271 void TabContentsCommandObserver::EnabledStateChangedForCommand(int command, | |
272 bool enabled) { | |
273 [controller_ enabledStateChangedForCommand:command | |
274 enabled:enabled ? YES : NO]; | |
275 } | |
OLD | NEW |