| 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 |