summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h3
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm54
-rw-r--r--chrome/browser/cocoa/command_observer_bridge.h41
-rw-r--r--chrome/browser/cocoa/command_observer_bridge.mm26
-rw-r--r--chrome/browser/cocoa/tab_contents_controller.h36
-rw-r--r--chrome/browser/cocoa/tab_contents_controller.mm147
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h27
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm63
-rw-r--r--chrome/browser/cocoa/tab_window_controller.h18
-rw-r--r--chrome/browser/cocoa/tab_window_controller.mm26
-rw-r--r--chrome/browser/cocoa/toolbar_controller.h60
-rw-r--r--chrome/browser/cocoa/toolbar_controller.mm123
12 files changed, 347 insertions, 277 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index f89d979..04deaf58 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -11,6 +11,7 @@
#import <Cocoa/Cocoa.h>
#import "chrome/browser/cocoa/tab_window_controller.h"
+#import "chrome/browser/cocoa/toolbar_view.h"
class Browser;
class BrowserWindow;
@@ -21,11 +22,13 @@ class TabContents;
@class TabStripController;
class TabStripModelObserverBridge;
@class TabStripView;
+@class ToolbarController;
@interface BrowserWindowController :
TabWindowController<NSUserInterfaceValidations> {
@private
TabStripController* tabStripController_;
+ ToolbarController* toolbarController_;
Browser* browser_;
TabStripModelObserverBridge* tabObserver_;
BrowserWindowCocoa* windowShim_;
diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm
index 024b5f5..ac78712 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -14,7 +14,11 @@
#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_strip_controller.h"
#import "chrome/browser/cocoa/tab_view.h"
+#import "chrome/browser/cocoa/toolbar_controller.h"
+@interface BrowserWindowController(Private)
+- (void)positionToolbar;
+@end
@implementation BrowserWindowController
@@ -43,7 +47,17 @@
// registering for the appropriate tab notifications from the back-end and
// managing the creation of new tabs.
tabStripController_ = [[TabStripController alloc]
- initWithView:[self tabStripView] browser:browser_];
+ initWithView:[self tabStripView]
+ switchView:[self tabContentArea]
+ browser:browser_];
+
+ // Create a controller for the toolbar, giving it the toolbar model object
+ // and the toolbar view from the nib. The controller will handle
+ // registering for the appropriate command state changes from the back-end.
+ toolbarController_ = [[ToolbarController alloc]
+ initWithModel:browser->toolbar_model()
+ commands:browser->command_updater()];
+ [self positionToolbar];
}
return self;
}
@@ -51,6 +65,7 @@
- (void)dealloc {
browser_->CloseAllTabs();
[tabStripController_ release];
+ [toolbarController_ release];
delete windowShim_;
delete tabObserver_;
delete browser_;
@@ -62,6 +77,28 @@
return windowShim_;
}
+// Position |toolbarView_| below the tab strip, but not as a sibling. The
+// toolbar is part of the window's contentView, mainly because we want the
+// opacity during drags to be the same as the web content.
+- (void)positionToolbar {
+ NSView* contentView = [self tabContentArea];
+ NSRect contentFrame = [contentView frame];
+ NSView* toolbarView = [toolbarController_ view];
+ NSRect toolbarFrame = [toolbarView frame];
+
+ // Shrink the content area by the height of the toolbar.
+ contentFrame.size.height -= toolbarFrame.size.height;
+ [contentView setFrame:contentFrame];
+
+ // Move the toolbar above the content area, within the window's content view
+ // (as opposed to the tab strip, which is a sibling).
+ toolbarFrame.origin.y = NSMaxY(contentFrame);
+ toolbarFrame.origin.x = 0;
+ toolbarFrame.size.width = contentFrame.size.width;
+ [toolbarView setFrame:toolbarFrame];
+ [[[self window] contentView] addSubview:toolbarView];
+}
+
- (void)destroyBrowser {
// We need the window to go away now.
[self autorelease];
@@ -172,29 +209,27 @@
}
- (LocationBar*)locationBar {
- return [tabStripController_ locationBar];
+ return [toolbarController_ locationBar];
}
- (void)updateToolbarWithContents:(TabContents*)tab
shouldRestoreState:(BOOL)shouldRestore {
- [tabStripController_ updateToolbarWithContents:tab
- shouldRestoreState:shouldRestore];
+ [toolbarController_ updateToolbarWithContents:shouldRestore ? tab : NULL];
}
- (void)setStarredState:(BOOL)isStarred {
- [tabStripController_ setStarredState:isStarred];
+ [toolbarController_ setStarredState:isStarred];
}
// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of the currently selected tab.
// |windowGrowBox| needs to be in the window's coordinate system.
- (NSRect)selectedTabGrowBoxRect {
- return [tabStripController_
- selectedTabGrowBoxRect];
+ return [tabStripController_ selectedTabGrowBoxRect];
}
- (void)setIsLoading:(BOOL)isLoading {
- [tabStripController_ setIsLoading:isLoading];
+ [toolbarController_ setIsLoading:isLoading];
}
// Called to start/stop the loading animations.
@@ -211,7 +246,7 @@
// Make the location bar the first responder, if possible.
- (void)focusLocationBar {
- [tabStripController_ focusLocationBar];
+ [toolbarController_ focusLocationBar];
}
- (void)arrangeTabs {
@@ -313,4 +348,5 @@
UpdateUIForContents(new_contents);
#endif
}
+
@end
diff --git a/chrome/browser/cocoa/command_observer_bridge.h b/chrome/browser/cocoa/command_observer_bridge.h
new file mode 100644
index 0000000..042c0d1
--- /dev/null
+++ b/chrome/browser/cocoa/command_observer_bridge.h
@@ -0,0 +1,41 @@
+// 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.
+
+#import <Cocoa/Cocoa.h>
+
+#include "chrome/browser/command_updater.h"
+
+@protocol CommandObserverProtocol;
+
+// A C++ bridge class that handles listening for updates to commands and
+// passing them back to an object that supports the protocol delcared below.
+// The observer will create one of these bridges, call ObserveCommand() on the
+// command ids it cares about, and then wait for update notifications,
+// delivered via -enabledStateChangedForCommand:enabled:. Destroying this
+// bridge will handle automatically unregistering for updates, so there's no
+// need to do that manually.
+
+class CommandObserverBridge : public CommandUpdater::CommandObserver {
+ public:
+ CommandObserverBridge(id<CommandObserverProtocol> observer,
+ CommandUpdater* commands);
+ virtual ~CommandObserverBridge();
+
+ // Register for updates about |command|.
+ void ObserveCommand(int command);
+
+ protected:
+ // Overridden from CommandUpdater::CommandObserver
+ virtual void EnabledStateChangedForCommand(int command, bool enabled);
+
+ private:
+ id<CommandObserverProtocol> observer_; // weak, owns me
+ CommandUpdater* commands_; // weak
+};
+
+// Implemented by the observing Objective-C object, called when there is a
+// state change for the given command.
+@protocol CommandObserverProtocol
+- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled;
+@end
diff --git a/chrome/browser/cocoa/command_observer_bridge.mm b/chrome/browser/cocoa/command_observer_bridge.mm
new file mode 100644
index 0000000..47ea888
--- /dev/null
+++ b/chrome/browser/cocoa/command_observer_bridge.mm
@@ -0,0 +1,26 @@
+// 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.
+
+#import "chrome/browser/cocoa/command_observer_bridge.h"
+
+CommandObserverBridge::CommandObserverBridge(
+ id<CommandObserverProtocol> observer, CommandUpdater* commands)
+ : observer_(observer), commands_(commands) {
+ DCHECK(observer_ && commands_);
+}
+
+CommandObserverBridge::~CommandObserverBridge() {
+ // Unregister the notifications
+ commands_->RemoveCommandObserver(this);
+}
+
+void CommandObserverBridge::ObserveCommand(int command) {
+ commands_->AddCommandObserver(command, this);
+}
+
+void CommandObserverBridge::EnabledStateChangedForCommand(int command,
+ bool enabled) {
+ [observer_ enabledStateChangedForCommand:command
+ enabled:enabled ? YES : NO];
+}
diff --git a/chrome/browser/cocoa/tab_contents_controller.h b/chrome/browser/cocoa/tab_contents_controller.h
index bf97dc3..ac8bd30 100644
--- a/chrome/browser/cocoa/tab_contents_controller.h
+++ b/chrome/browser/cocoa/tab_contents_controller.h
@@ -9,16 +9,12 @@
@class BookmarkView;
@class GrowBoxView;
-@class ToolbarView;
class BookmarkModel;
-class CommandUpdater;
-class LocationBar;
-class LocationBarViewMac;
class TabContents;
class TabContentsCommandObserver;
class TabStripModel;
-class ToolbarModel;
+@class ToolbarView;
// A class that controls the contents of a tab, including the toolbar and
// web area.
@@ -36,25 +32,14 @@ class ToolbarModel;
@interface TabContentsController : NSViewController {
@private
- CommandUpdater* commands_; // weak, may be nil
TabContentsCommandObserver* observer_; // nil if |commands_| is nil
- LocationBarViewMac* locationBarView_;
TabContents* contents_; // weak
- ToolbarModel* toolbarModel_; // weak, one per window
- IBOutlet ToolbarView* toolbarView_;
-
BookmarkModel* bookmarkModel_; // weak; one per window
// TODO(jrg): write a BookmarkView
IBOutlet ToolbarView* /* BookmarkView* */ bookmarkView_;
- IBOutlet NSButton* backButton_;
- IBOutlet NSButton* forwardButton_;
- IBOutlet NSButton* reloadButton_;
- IBOutlet NSButton* starButton_;
- IBOutlet NSButton* goButton_;
- IBOutlet NSTextField* locationBar_;
IBOutlet NSBox* contentsBox_;
IBOutlet GrowBoxView* growBox_;
@@ -69,16 +54,11 @@ class ToolbarModel;
- (id)initWithNibName:(NSString*)name
bundle:(NSBundle*)bundle
contents:(TabContents*)contents
- commands:(CommandUpdater*)commands
- toolbarModel:(ToolbarModel*)toolbarModel
bookmarkModel:(BookmarkModel*)bookmarkModel;
// Take this view (toolbar and web contents) full screen
- (IBAction)fullScreen:(id)sender;
-// Get the C++ bridge object representing the location bar for this tab.
-- (LocationBar*)locationBar;
-
// Called when the tab contents is about to be put into the view hierarchy as
// the selected tab. Handles things such as ensuring the toolbar is correctly
// enabled.
@@ -89,24 +69,10 @@ class ToolbarModel;
// an entirely new tab contents object.
- (void)tabDidChange:(TabContents*)updatedContents;
-// Called when any url bar state changes. If |tabForRestoring| is non-NULL,
-// it points to a TabContents whose state we should restore.
-- (void)updateToolbarWithContents:(TabContents*)tabForRestoring;
-
-// Sets whether or not the current page in the frontmost tab is bookmarked.
-- (void)setStarredState:(BOOL)isStarred;
-
// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of this tab.
- (NSRect)growBoxRect;
-// Called to update the loading state. Handles updating the go/stop button
-// state.
-- (void)setIsLoading:(BOOL)isLoading;
-
-// Make the location bar the first responder, if possible.
-- (void)focusLocationBar;
-
// Change the visibility state of the bookmark bar.
- (void)toggleBookmarkBar:(BOOL)enable;
diff --git a/chrome/browser/cocoa/tab_contents_controller.mm b/chrome/browser/cocoa/tab_contents_controller.mm
index 1ceb2a3..ce00782 100644
--- a/chrome/browser/cocoa/tab_contents_controller.mm
+++ b/chrome/browser/cocoa/tab_contents_controller.mm
@@ -5,56 +5,21 @@
#import "chrome/browser/cocoa/tab_contents_controller.h"
#include "base/sys_string_conversions.h"
-#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
-#import "chrome/browser/cocoa/location_bar_view_mac.h"
-#include "chrome/browser/command_updater.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/toolbar_model.h"
-
-// Names of images in the bundle for the star icon (normal and 'starred').
-static NSString* const kStarImageName = @"star";
-static NSString* const kStarredImageName = @"starred";
-
-@interface TabContentsController(CommandUpdates)
-- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled;
-@end
@interface TabContentsController(Private)
-- (void)updateToolbarCommandStatus;
- (void)applyContentsBoxOffset:(BOOL)apply;
@end
-// A C++ bridge class that handles listening for updates to commands and
-// passing them back to the controller.
-class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
- public:
- TabContentsCommandObserver(TabContentsController* controller,
- CommandUpdater* commands);
- ~TabContentsCommandObserver();
-
- // Overridden from CommandUpdater::CommandObserver
- void EnabledStateChangedForCommand(int command, bool enabled);
-
- private:
- TabContentsController* controller_; // weak, owns me
- CommandUpdater* commands_; // weak
-};
-
@implementation TabContentsController
- (id)initWithNibName:(NSString*)name
bundle:(NSBundle*)bundle
contents:(TabContents*)contents
- commands:(CommandUpdater*)commands
- toolbarModel:(ToolbarModel*)toolbarModel
bookmarkModel:(BookmarkModel*)bookmarkModel {
if ((self = [super initWithNibName:name bundle:bundle])) {
- commands_ = commands;
- if (commands_)
- observer_ = new TabContentsCommandObserver(self, commands);
contents_ = contents;
- toolbarModel_ = toolbarModel;
bookmarkModel_ = bookmarkModel;
}
return self;
@@ -63,27 +28,12 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
- (void)dealloc {
// make sure our contents have been removed from the window
[[self view] removeFromSuperview];
- delete observer_;
- delete locationBarView_;
[super dealloc];
}
- (void)awakeFromNib {
[contentsBox_ setContentView:contents_->GetNativeView()];
[self applyContentsBoxOffset:YES];
-
- // Provide a starting point since we won't get notifications if the state
- // doesn't change between tabs.
- [self updateToolbarCommandStatus];
-
- locationBarView_ = new LocationBarViewMac(locationBar_);
- locationBarView_->Init();
-
- [locationBar_ setStringValue:@"http://dev.chromium.org"];
-}
-
-- (LocationBar*)locationBar {
- return locationBarView_;
}
// Returns YES if the tab represented by this controller is the front-most.
@@ -93,34 +43,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
return [[self view] superview] ? YES : NO;
}
-// Called when the state for a command changes to |enabled|. Update the
-// corresponding UI element.
-- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled {
- // We don't need to update anything if we're not the frontmost tab.
- // TODO(pinkerton): i'm worried that observer ordering could cause the
- // notification to be sent before we've been put into the view, but we
- // appear to be called in the right order so far.
- if (![self isCurrentTab])
- return;
-
- NSButton* button = nil;
- switch (command) {
- case IDC_BACK:
- button = backButton_;
- break;
- case IDC_FORWARD:
- button = forwardButton_;
- break;
- case IDC_HOME:
- // TODO(pinkerton): add home button
- break;
- case IDC_STAR:
- button = starButton_;
- break;
- }
- [button setEnabled:enabled];
-}
-
- (IBAction)fullScreen:(id)sender {
if ([[self view] isInFullScreenMode]) {
[[self view] exitFullScreenModeWithOptions:nil];
@@ -129,21 +51,7 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
}
}
-// Set the enabled state of the buttons on the toolbar to match the state in
-// the controller. We can't only rely on notifications to do this because the
-// command model only assumes a single toolbar and won't send notifications if
-// the state doesn't change.
-- (void)updateToolbarCommandStatus {
- [backButton_ setEnabled:commands_->IsCommandEnabled(IDC_BACK) ? YES : NO];
- [forwardButton_
- setEnabled:commands_->IsCommandEnabled(IDC_FORWARD) ? YES : NO];
- [reloadButton_
- setEnabled:commands_->IsCommandEnabled(IDC_RELOAD) ? YES : NO];
- [starButton_ setEnabled:commands_->IsCommandEnabled(IDC_STAR) ? YES : NO];
-}
-
- (void)willBecomeSelectedTab {
- [self updateToolbarCommandStatus];
}
- (void)tabDidChange:(TabContents*)updatedContents {
@@ -151,29 +59,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
[contentsBox_ setContentView:contents_->GetNativeView()];
}
-- (void)focusLocationBar {
- if (locationBarView_) {
- locationBarView_->FocusLocation();
- }
-}
-
-- (void)updateToolbarWithContents:(TabContents*)tab {
- // TODO(pinkerton): there's a lot of ui code in autocomplete_edit.cc
- // that we'll want to duplicate. For now, just handle setting the text.
-
- // TODO(pinkerton): update the security lock icon and background color
-
- NSString* urlString = base::SysWideToNSString(toolbarModel_->GetText());
- [locationBar_ setStringValue:urlString];
-}
-
-- (void)setStarredState:(BOOL)isStarred {
- NSString* starImageName = kStarImageName;
- if (isStarred)
- starImageName = kStarredImageName;
- [starButton_ setImage:[NSImage imageNamed:starImageName]];
-}
-
// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of this tab.
- (NSRect)growBoxRect {
@@ -199,13 +84,6 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
return localGrowBox;
}
-- (void)setIsLoading:(BOOL)isLoading {
- NSString* imageName = @"go";
- if (isLoading)
- imageName = @"stop";
- [goButton_ setImage:[NSImage imageNamed:imageName]];
-}
-
- (void)toggleBookmarkBar:(BOOL)enable {
contentsBoxHasOffset_ = enable;
[self applyContentsBoxOffset:enable];
@@ -248,28 +126,3 @@ class TabContentsCommandObserver : public CommandUpdater::CommandObserver {
}
@end
-
-//--------------------------------------------------------------------------
-
-TabContentsCommandObserver::TabContentsCommandObserver(
- TabContentsController* controller, CommandUpdater* commands)
- : controller_(controller), commands_(commands) {
- DCHECK(controller_ && commands);
- // Register for notifications about state changes for the toolbar buttons
- commands_->AddCommandObserver(IDC_BACK, this);
- commands_->AddCommandObserver(IDC_FORWARD, this);
- commands_->AddCommandObserver(IDC_RELOAD, this);
- commands_->AddCommandObserver(IDC_HOME, this);
- commands_->AddCommandObserver(IDC_STAR, this);
-}
-
-TabContentsCommandObserver::~TabContentsCommandObserver() {
- // Unregister the notifications
- commands_->RemoveCommandObserver(this);
-}
-
-void TabContentsCommandObserver::EnabledStateChangedForCommand(int command,
- bool enabled) {
- [controller_ enabledStateChangedForCommand:command
- enabled:enabled ? YES : NO];
-}
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
index 7159d8d..ab6b902 100644
--- a/chrome/browser/cocoa/tab_strip_controller.h
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -36,10 +36,10 @@ class ToolbarModel;
@private
TabContents* currentTab_; // weak, tab for which we're showing state
TabStripView* tabView_; // weak
+ NSView* switchView_; // weak
NSButton* newTabButton_; // weak, obtained from the nib.
TabStripModelObserverBridge* bridge_;
TabStripModel* tabModel_; // weak
- ToolbarModel* toolbarModel_; // weak, one per browser
BookmarkModel* bookmarkModel_; // weak, one per profile (= one per Browser*)
CommandUpdater* commands_; // weak, may be nil
// access to the TabContentsControllers (which own the parent view
@@ -56,33 +56,18 @@ class ToolbarModel;
}
// Initialize the controller with a view and browser that contains
-// everything else we'll need.
+// everything else we'll need. |switchView| is the view whose contents get
+// "switched" every time the user switches tabs. The children of this view
+// will be released, so if you want them to stay around, make sure
+// you have retained them.
- (id)initWithView:(TabStripView*)view
+ switchView:(NSView*)switchView
browser:(Browser*)browser;
-// Get the C++ bridge object representing the location bar for the current tab.
-- (LocationBar*)locationBar;
-
-// Updates the toolbar (and transitively the location bar) with the states of
-// the specified |tab|. If |shouldRestore| is true, we're switching
-// (back?) to this tab and should restore any previous location bar state
-// (such as user editing) as well.
-- (void)updateToolbarWithContents:(TabContents*)tab
- shouldRestoreState:(BOOL)shouldRestore;
-
-// Sets whether or not the current page in the frontmost tab is bookmarked.
-- (void)setStarredState:(BOOL)isStarred;
-
// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of the currently selected tab.
- (NSRect)selectedTabGrowBoxRect;
-// Called to tell the selected tab to update its loading state.
-- (void)setIsLoading:(BOOL)isLoading;
-
-// Make the location bar the first responder, if possible.
-- (void)focusLocationBar;
-
// Return a boolean (ObjC BOOL, not C++ bool) to say if the bookmark
// bar is visible.
- (BOOL)isBookmarkBarVisible;
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index 6e3e70b..e4d669a 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -20,12 +20,13 @@
@implementation TabStripController
- (id)initWithView:(TabStripView*)view
+ switchView:(NSView*)switchView
browser:(Browser*)browser {
- DCHECK(view && browser);
+ DCHECK(view && switchView && browser);
if ((self = [super init])) {
tabView_ = view;
+ switchView_ = switchView;
tabModel_ = browser->tabstrip_model();
- toolbarModel_ = browser->toolbar_model();
bookmarkModel_ = browser->profile()->GetBookmarkModel();
commands_ = browser->command_updater();
bridge_ = new TabStripModelObserverBridge(tabModel_, self);
@@ -62,22 +63,20 @@
TabContentsController* controller = [tabContentsArray_ objectAtIndex:index];
// Resize the new view to fit the window
- NSView* contentView = [[tabView_ window] contentView];
NSView* newView = [controller view];
- NSRect frame = [contentView bounds];
- frame.size.height -= 14.0;
+ NSRect frame = [switchView_ bounds];
[newView setFrame:frame];
// Remove the old view from the view hierarchy. We know there's only one
- // child of the contentView because we're the one who put it there. There
+ // child of |switchView_| because we're the one who put it there. There
// may not be any children in the case of a tab that's been closed, in
// which case there's no swapping going on.
- NSArray* subviews = [contentView subviews];
+ NSArray* subviews = [switchView_ subviews];
if ([subviews count]) {
NSView* oldView = [subviews objectAtIndex:0];
- [contentView replaceSubview:oldView with:newView];
+ [switchView_ replaceSubview:oldView with:newView];
} else {
- [contentView addSubview:newView];
+ [switchView_ addSubview:newView];
}
}
@@ -224,8 +223,6 @@
[[[TabContentsController alloc] initWithNibName:@"TabContents"
bundle:nil
contents:contents
- commands:commands_
- toolbarModel:toolbarModel_
bookmarkModel:bookmarkModel_]
autorelease];
if ([self isBookmarkBarVisible])
@@ -315,32 +312,6 @@
[updatedController tabDidChange:contents];
}
-- (LocationBar*)locationBar {
- TabContentsController* selectedController =
- [tabContentsArray_ objectAtIndex:tabModel_->selected_index()];
- return [selectedController locationBar];
-}
-
-- (void)updateToolbarWithContents:(TabContents*)tab
- shouldRestoreState:(BOOL)shouldRestore {
- // TODO(pinkerton): OS_WIN maintains this, but I'm not sure why. It's
- // available by querying the model, which we have available to us.
- currentTab_ = tab;
-
- // tell the appropriate controller to update its state. |shouldRestore| being
- // YES means we're going back to this tab and should put back any state
- // associated with it.
- TabContentsController* controller =
- [tabContentsArray_ objectAtIndex:tabModel_->GetIndexOfTabContents(tab)];
- [controller updateToolbarWithContents:shouldRestore ? tab : nil];
-}
-
-- (void)setStarredState:(BOOL)isStarred {
- TabContentsController* selectedController =
- [tabContentsArray_ objectAtIndex:tabModel_->selected_index()];
- [selectedController setStarredState:isStarred];
-}
-
// Return the rect, in WebKit coordinates (flipped), of the window's grow box
// in the coordinate system of the content area of the currently selected tab.
- (NSRect)selectedTabGrowBoxRect {
@@ -358,23 +329,6 @@
return [selectedController growBoxRect];
}
-// Called to tell the selected tab to update its loading state.
-- (void)setIsLoading:(BOOL)isLoading {
- // TODO(pinkerton): update the favicon on the selected tab view to/from
- // a spinner?
-
- TabContentsController* selectedController =
- [tabContentsArray_ objectAtIndex:tabModel_->selected_index()];
- [selectedController setIsLoading:isLoading];
-}
-
-// Make the location bar the first responder, if possible.
-- (void)focusLocationBar {
- TabContentsController* selectedController =
- [tabContentsArray_ objectAtIndex:tabModel_->selected_index()];
- [selectedController focusLocationBar];
-}
-
- (BOOL)isBookmarkBarVisible {
return [bookmarkBarStateController_ visible];
}
@@ -386,7 +340,6 @@
for (TabContentsController *controller in tabContentsArray_) {
[controller toggleBookmarkBar:visible];
}
-
}
@end
diff --git a/chrome/browser/cocoa/tab_window_controller.h b/chrome/browser/cocoa/tab_window_controller.h
index f0fcb524..43df6f2 100644
--- a/chrome/browser/cocoa/tab_window_controller.h
+++ b/chrome/browser/cocoa/tab_window_controller.h
@@ -11,6 +11,12 @@
// know anything about the actual tab implementation or model, as that is fairly
// application-specific. It only provides an API to be overridden by subclasses
// to fill in the details.
+//
+// This assumes that there will be a view in the nib, connected to
+// |tabContentArea_|, that indicates the content that it switched when switching
+// between tabs. It needs to be a regular NSView, not something like an NSBox
+// because the TabStripController makes certain assumptions about how it can
+// swap out subviews.
#import <Cocoa/Cocoa.h>
@@ -19,9 +25,7 @@
@interface TabWindowController : NSWindowController {
@private
- IBOutlet NSBox* contentBox_; // Only valid at window creation time, used
- // to position the tab strip. nil afterwards.
- // TODO(pinkerton): get rid of this.
+ IBOutlet NSView* tabContentArea_;
IBOutlet TabStripView* tabStripView_;
NSWindow* overlayWindow_; // Used during dragging for window opacity tricks
NSView* cachedContentView_; // Used during dragging for identifying which
@@ -29,6 +33,7 @@
// (weak)
}
@property(readonly, nonatomic) TabStripView* tabStripView;
+@property(readonly, nonatomic) NSView* tabContentArea;
// Used during tab dragging to turn on/off the overlay window when a tab
// is torn off.
@@ -62,4 +67,11 @@
@end
+@interface TabWindowController(ProtectedMethods)
+// A list of all the views that need to move to the overlay window. Subclasses
+// can override this to add more things besides the tab strip. Be sure to
+// call the superclass' version if overridden.
+- (NSArray*)viewsToMoveToOverlay;
+@end
+
#endif // CHROME_BROWSER_TAB_WINDOW_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/tab_window_controller.mm b/chrome/browser/cocoa/tab_window_controller.mm
index 691095f..456c973 100644
--- a/chrome/browser/cocoa/tab_window_controller.mm
+++ b/chrome/browser/cocoa/tab_window_controller.mm
@@ -13,19 +13,16 @@
@implementation TabWindowController
@synthesize tabStripView = tabStripView_;
+@synthesize tabContentArea = tabContentArea_;
- (void)windowDidLoad {
// Place the tab bar above the content box and add it to the view hierarchy
// as a sibling of the content view so it can overlap with the window frame.
- NSRect tabFrame = [contentBox_ frame];
+ NSRect tabFrame = [tabContentArea_ frame];
tabFrame.origin = NSMakePoint(0, NSMaxY(tabFrame));
tabFrame.size.height = NSHeight([tabStripView_ frame]);
[tabStripView_ setFrame:tabFrame];
[[[[self window] contentView] superview] addSubview:tabStripView_];
-
- // tab switching will destroy the content area, so nil this out to ensure
- // that nobody tries to use it.
- contentBox_ = nil;
}
- (void)removeOverlay {
@@ -45,6 +42,21 @@
[self setUseOverlay:YES];
}
+- (NSArray*)viewsToMoveToOverlay {
+ return [NSArray arrayWithObject:[self tabStripView]];
+}
+
+// if |useOverlay| is true, we're moving views into the overlay's content
+// area. If false, we're moving out of the overlay back into the window's
+// content.
+- (void)moveViewsBetweenWindowAndOverlay:(BOOL)useOverlay {
+ NSView* moveTo = useOverlay ?
+ [overlayWindow_ contentView] : [cachedContentView_ superview];
+ NSArray* viewsToMove = [self viewsToMoveToOverlay];
+ for (NSView* view in viewsToMove)
+ [moveTo addSubview:view];
+}
+
// If |useOverlay| is YES, creates a new overlay window and puts the tab strip
// and the content area inside of it. This allows it to have a different opacity
// from the title bar. If NO, returns everything to the previous state and
@@ -66,7 +78,7 @@
NSView *contentView = [overlayWindow_ contentView];
[contentView addSubview:[self tabStripView]];
cachedContentView_ = [[self window] contentView];
- [contentView addSubview:cachedContentView_];
+ [self moveViewsBetweenWindowAndOverlay:useOverlay];
[overlayWindow_ setHasShadow:YES];
[[self window] addChildWindow:overlayWindow_ ordered:NSWindowAbove];
[overlayWindow_ orderFront:nil];
@@ -75,7 +87,7 @@
DCHECK(cachedContentView_);
[[self window] setHasShadow:YES];
[[self window] setContentView:cachedContentView_];
- [[cachedContentView_ superview] addSubview:[self tabStripView]];
+ [self moveViewsBetweenWindowAndOverlay:useOverlay];
[[self window] makeFirstResponder:cachedContentView_];
[[self window] display];
[[self window] removeChildWindow:overlayWindow_];
diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h
new file mode 100644
index 0000000..d2cc2c4
--- /dev/null
+++ b/chrome/browser/cocoa/toolbar_controller.h
@@ -0,0 +1,60 @@
+// 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.
+
+#ifndef CHROME_BROWSER_COCOA_TOOLBAR_CONTROLLER_H_
+#define CHROME_BROWSER_COCOA_TOOLBAR_CONTROLLER_H_
+
+#import <Cocoa/Cocoa.h>
+
+#import "chrome/browser/cocoa/command_observer_bridge.h"
+
+class CommandUpdater;
+class LocationBar;
+class LocationBarViewMac;
+class TabContents;
+class ToolbarModel;
+class ToolbarView;
+
+// A controller for the toolbar in the browser window. Manages updating the
+// state for location bar and back/fwd/reload/go buttons.
+
+@interface ToolbarController : NSViewController<CommandObserverProtocol> {
+ @private
+ ToolbarModel* toolbarModel_; // weak, one per window
+ CommandUpdater* commands_; // weak, one per window
+ CommandObserverBridge* commandObserver_;
+ LocationBarViewMac* locationBarView_;
+
+ IBOutlet NSButton* backButton_;
+ IBOutlet NSButton* forwardButton_;
+ IBOutlet NSButton* reloadButton_;
+ IBOutlet NSButton* starButton_;
+ IBOutlet NSButton* goButton_;
+ IBOutlet NSTextField* locationBar_;
+}
+
+// Initialize the toolbar and register for command updates.
+- (id)initWithModel:(ToolbarModel*)model
+ commands:(CommandUpdater*)commands;
+
+// Get the C++ bridge object representing the location bar for this tab.
+- (LocationBar*)locationBar;
+
+// Make the location bar the first responder, if possible.
+- (void)focusLocationBar;
+
+// Called when any url bar state changes. If |tabForRestoring| is non-NULL,
+// it points to a TabContents whose state we should restore.
+- (void)updateToolbarWithContents:(TabContents*)tabForRestoring;
+
+// Sets whether or not the current page in the frontmost tab is bookmarked.
+- (void)setStarredState:(BOOL)isStarred;
+
+// Called to update the loading state. Handles updating the go/stop button
+// state.
+- (void)setIsLoading:(BOOL)isLoading;
+
+@end
+
+#endif // CHROME_BROWSER_COCOA_TOOLBAR_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm
new file mode 100644
index 0000000..e77c30c
--- /dev/null
+++ b/chrome/browser/cocoa/toolbar_controller.mm
@@ -0,0 +1,123 @@
+// 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.
+
+#import "chrome/browser/cocoa/toolbar_controller.h"
+
+#include "base/sys_string_conversions.h"
+#include "chrome/app/chrome_dll_resource.h"
+#import "chrome/browser/cocoa/location_bar_view_mac.h"
+#include "chrome/browser/toolbar_model.h"
+
+// Names of images in the bundle for the star icon (normal and 'starred').
+static NSString* const kStarImageName = @"star";
+static NSString* const kStarredImageName = @"starred";
+
+@interface ToolbarController(Private)
+- (void)initCommandStatus:(CommandUpdater*)commands;
+@end
+
+@implementation ToolbarController
+
+- (id)initWithModel:(ToolbarModel*)model
+ commands:(CommandUpdater*)commands {
+ DCHECK(model && commands);
+ if ((self = [super initWithNibName:@"Toolbar" bundle:nil])) {
+ toolbarModel_ = model;
+ commands_ = commands;
+
+ // Register for notifications about state changes for the toolbar buttons
+ commandObserver_ = new CommandObserverBridge(self, commands);
+ commandObserver_->ObserveCommand(IDC_BACK);
+ commandObserver_->ObserveCommand(IDC_FORWARD);
+ commandObserver_->ObserveCommand(IDC_RELOAD);
+ commandObserver_->ObserveCommand(IDC_HOME);
+ commandObserver_->ObserveCommand(IDC_STAR);
+ }
+ return self;
+}
+
+// Called after the view is done loading and the outlets have been hooked up.
+// Now we can hook up bridges that rely on UI objects such as the location
+// bar and button state.
+- (void)awakeFromNib {
+ [self initCommandStatus:commands_];
+ locationBarView_ = new LocationBarViewMac(locationBar_);
+ locationBarView_->Init();
+ [locationBar_ setStringValue:@"http://dev.chromium.org"];
+}
+
+- (void)dealloc {
+ delete locationBarView_;
+ delete commandObserver_;
+ [super dealloc];
+}
+
+- (LocationBar*)locationBar {
+ return locationBarView_;
+}
+
+- (void)focusLocationBar {
+ if (locationBarView_) {
+ locationBarView_->FocusLocation();
+ }
+}
+
+// Called when the state for a command changes to |enabled|. Update the
+// corresponding UI element.
+- (void)enabledStateChangedForCommand:(NSInteger)command enabled:(BOOL)enabled {
+ NSButton* button = nil;
+ switch (command) {
+ case IDC_BACK:
+ button = backButton_;
+ break;
+ case IDC_FORWARD:
+ button = forwardButton_;
+ break;
+ case IDC_HOME:
+ // TODO(pinkerton): add home button
+ break;
+ case IDC_STAR:
+ button = starButton_;
+ break;
+ }
+ [button setEnabled:enabled];
+}
+
+// Init the enabled state of the buttons on the toolbar to match the state in
+// the controller.
+- (void)initCommandStatus:(CommandUpdater*)commands {
+ [backButton_ setEnabled:commands->IsCommandEnabled(IDC_BACK) ? YES : NO];
+ [forwardButton_
+ setEnabled:commands->IsCommandEnabled(IDC_FORWARD) ? YES : NO];
+ [reloadButton_
+ setEnabled:commands->IsCommandEnabled(IDC_RELOAD) ? YES : NO];
+ // TODO(pinkerton): Add home button.
+ [starButton_ setEnabled:commands->IsCommandEnabled(IDC_STAR) ? YES : NO];
+}
+
+- (void)updateToolbarWithContents:(TabContents*)tab {
+ // TODO(pinkerton): there's a lot of ui code in autocomplete_edit.cc
+ // that we'll want to duplicate. For now, just handle setting the text.
+
+ // TODO(pinkerton): update the security lock icon and background color
+
+ NSString* urlString = base::SysWideToNSString(toolbarModel_->GetText());
+ [locationBar_ setStringValue:urlString];
+}
+
+- (void)setStarredState:(BOOL)isStarred {
+ NSString* starImageName = kStarImageName;
+ if (isStarred)
+ starImageName = kStarredImageName;
+ [starButton_ setImage:[NSImage imageNamed:starImageName]];
+}
+
+- (void)setIsLoading:(BOOL)isLoading {
+ NSString* imageName = @"go";
+ if (isLoading)
+ imageName = @"stop";
+ [goButton_ setImage:[NSImage imageNamed:imageName]];
+}
+
+@end