summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 13:46:34 +0000
committerpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-08 13:46:34 +0000
commit51a5ea2a6ef9d361b62ef1e6f3590131ac395cea (patch)
tree85e8c73758d3ff70f990265b824708ca6b427483 /chrome/browser/cocoa
parent653bd5f03ef74274adbec816df10cdfd046b6eea (diff)
downloadchromium_src-51a5ea2a6ef9d361b62ef1e6f3590131ac395cea.zip
chromium_src-51a5ea2a6ef9d361b62ef1e6f3590131ac395cea.tar.gz
chromium_src-51a5ea2a6ef9d361b62ef1e6f3590131ac395cea.tar.bz2
Refactor tab model observer for cocoa into a separate class so it can be re-used. Mark tab as visible when switching to it so tabs loaded in the background work.
Review URL: http://codereview.chromium.org/63087 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13346 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/browser_window_controller.h2
-rw-r--r--chrome/browser/cocoa/browser_window_controller.mm46
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.h4
-rw-r--r--chrome/browser/cocoa/tab_strip_controller.mm109
-rw-r--r--chrome/browser/cocoa/tab_strip_model_observer_bridge.h70
-rw-r--r--chrome/browser/cocoa/tab_strip_model_observer_bridge.mm87
6 files changed, 212 insertions, 106 deletions
diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h
index 9e552e6..f89d979 100644
--- a/chrome/browser/cocoa/browser_window_controller.h
+++ b/chrome/browser/cocoa/browser_window_controller.h
@@ -19,6 +19,7 @@ class LocationBar;
class TabContents;
@class TabContentsController;
@class TabStripController;
+class TabStripModelObserverBridge;
@class TabStripView;
@interface BrowserWindowController :
@@ -26,6 +27,7 @@ class TabContents;
@private
TabStripController* tabStripController_;
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 bd71540..024b5f5 100644
--- a/chrome/browser/cocoa/browser_window_controller.mm
+++ b/chrome/browser/cocoa/browser_window_controller.mm
@@ -5,13 +5,17 @@
#include "chrome/app/chrome_dll_resource.h" // IDC_*
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_list.h"
+#include "chrome/browser/tab_contents/web_contents.h"
+#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#import "chrome/browser/cocoa/browser_window_cocoa.h"
#import "chrome/browser/cocoa/browser_window_controller.h"
+#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/cocoa/tab_strip_view.h"
#import "chrome/browser/cocoa/tab_strip_controller.h"
#import "chrome/browser/cocoa/tab_view.h"
+
@implementation BrowserWindowController
// Load the browser window nib and do any Cocoa-specific initialization.
@@ -21,6 +25,8 @@
if ((self = [super initWithWindowNibName:@"BrowserWindow"])) {
browser_ = browser;
DCHECK(browser_);
+ tabObserver_ = new TabStripModelObserverBridge(browser->tabstrip_model(),
+ self);
windowShim_ = new BrowserWindowCocoa(browser, self, [self window]);
// The window is now fully realized and |-windowDidLoad:| has been
@@ -45,8 +51,9 @@
- (void)dealloc {
browser_->CloseAllTabs();
[tabStripController_ release];
- delete browser_;
delete windowShim_;
+ delete tabObserver_;
+ delete browser_;
[super dealloc];
}
@@ -269,4 +276,41 @@
return browser_->tabstrip_model()->count();
}
+- (void)selectTabWithContents:(TabContents*)newContents
+ previousContents:(TabContents*)oldContents
+ atIndex:(NSInteger)index
+ userGesture:(bool)wasUserGesture {
+ DCHECK(oldContents != newContents);
+
+ // We do not store the focus when closing the tab to work-around bug 4633.
+ // Some reports seem to show that the focus manager and/or focused view can
+ // be garbage at that point, it is not clear why.
+ if (oldContents && !oldContents->is_being_destroyed() &&
+ oldContents->AsWebContents())
+ oldContents->AsWebContents()->view()->StoreFocus();
+
+ // Update various elements that are interested in knowing the current
+ // TabContents.
+#if 0
+// TODO(pinkerton):Update as more things become window-specific
+ infobar_container_->ChangeTabContents(new_contents);
+ contents_container_->SetTabContents(new_contents);
+#endif
+ newContents->DidBecomeSelected();
+
+ if (BrowserList::GetLastActive() == browser_ &&
+ !browser_->tabstrip_model()->closing_all() &&
+ newContents->AsWebContents()) {
+ newContents->AsWebContents()->view()->RestoreFocus();
+ }
+
+#if 0
+// TODO(pinkerton):Update as more things become window-specific
+ // Update all the UI bits.
+ UpdateTitleBar();
+ toolbar_->SetProfile(new_contents->profile());
+ UpdateToolbar(new_contents, true);
+ UpdateUIForContents(new_contents);
+#endif
+}
@end
diff --git a/chrome/browser/cocoa/tab_strip_controller.h b/chrome/browser/cocoa/tab_strip_controller.h
index 89504fd..7159d8d 100644
--- a/chrome/browser/cocoa/tab_strip_controller.h
+++ b/chrome/browser/cocoa/tab_strip_controller.h
@@ -16,7 +16,7 @@ class BookmarkModel;
class Browser;
class CommandUpdater;
class LocationBar;
-class TabStripBridge;
+class TabStripModelObserverBridge;
class TabStripModel;
class TabContents;
class ToolbarModel;
@@ -37,7 +37,7 @@ class ToolbarModel;
TabContents* currentTab_; // weak, tab for which we're showing state
TabStripView* tabView_; // weak
NSButton* newTabButton_; // weak, obtained from the nib.
- TabStripBridge* bridge_;
+ TabStripModelObserverBridge* bridge_;
TabStripModel* tabModel_; // weak
ToolbarModel* toolbarModel_; // weak, one per browser
BookmarkModel* bookmarkModel_; // weak, one per profile (= one per Browser*)
diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm
index d29702b..6e3e70b 100644
--- a/chrome/browser/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/cocoa/tab_strip_controller.mm
@@ -12,55 +12,11 @@
#import "chrome/browser/cocoa/tab_cell.h"
#import "chrome/browser/cocoa/tab_contents_controller.h"
#import "chrome/browser/cocoa/tab_controller.h"
+#import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/cocoa/tab_view.h"
#import "chrome/browser/tab_contents/tab_contents.h"
#import "chrome/browser/tabs/tab_strip_model.h"
-// The private methods the brige object needs from the controller.
-@interface TabStripController(BridgeMethods)
-- (void)insertTabWithContents:(TabContents*)contents
- atIndex:(NSInteger)index
- inForeground:(bool)inForeground;
-- (void)selectTabWithContents:(TabContents*)newContents
- previousContents:(TabContents*)oldContents
- atIndex:(NSInteger)index
- userGesture:(bool)wasUserGesture;
-- (void)tabDetachedWithContents:(TabContents*)contents
- atIndex:(NSInteger)index;
-- (void)tabChangedWithContents:(TabContents*)contents
- atIndex:(NSInteger)index
- loadingOnly:(BOOL)loading;
-@end
-
-// A C++ bridge class to handle receiving notifications from the C++ tab
-// strip model. Doesn't do much on its own, just sends everything straight
-// to the Cocoa controller.
-class TabStripBridge : public TabStripModelObserver {
- public:
- TabStripBridge(TabStripModel* model, TabStripController* controller);
- ~TabStripBridge();
-
- // Overridden from TabStripModelObserver
- virtual void TabInsertedAt(TabContents* contents,
- int index,
- bool foreground);
- virtual void TabDetachedAt(TabContents* contents, int index);
- virtual void TabSelectedAt(TabContents* old_contents,
- TabContents* new_contents,
- int index,
- bool user_gesture);
- virtual void TabMoved(TabContents* contents,
- int from_index,
- int to_index);
- virtual void TabChangedAt(TabContents* contents, int index,
- bool loading_only);
- virtual void TabStripEmpty();
-
- private:
- TabStripController* controller_; // weak, owns me
- TabStripModel* model_; // weak, owned by Browser
-};
-
@implementation TabStripController
- (id)initWithView:(TabStripView*)view
@@ -72,7 +28,7 @@ class TabStripBridge : public TabStripModelObserver {
toolbarModel_ = browser->toolbar_model();
bookmarkModel_ = browser->profile()->GetBookmarkModel();
commands_ = browser->command_updater();
- bridge_ = new TabStripBridge(tabModel_, self);
+ bridge_ = new TabStripModelObserverBridge(tabModel_, self);
tabContentsArray_ = [[NSMutableArray alloc] init];
tabArray_ = [[NSMutableArray alloc] init];
bookmarkBarStateController_ = [[BookmarkBarStateController alloc]
@@ -346,11 +302,13 @@ class TabStripBridge : public TabStripModelObserver {
}
// Called when a notification is received from the model that the given tab
-// has been updated.
+// has been updated. |loading| will be YES when we only want to update the
+// throbber state, not anything else about the (partially) loading tab.
- (void)tabChangedWithContents:(TabContents*)contents
atIndex:(NSInteger)index
loadingOnly:(BOOL)loading {
- [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents];
+ if (!loading)
+ [self setTabTitle:[tabArray_ objectAtIndex:index] withContents:contents];
TabContentsController* updatedController =
[tabContentsArray_ objectAtIndex:index];
@@ -431,59 +389,4 @@ class TabStripBridge : public TabStripModelObserver {
}
-
@end
-
-//--------------------------------------------------------------------------
-
-TabStripBridge::TabStripBridge(TabStripModel* model,
- TabStripController* controller)
- : controller_(controller), model_(model) {
- // Register to be a listener on the model so we can get updates and tell
- // the TabStripController about them.
- model_->AddObserver(this);
-}
-
-TabStripBridge::~TabStripBridge() {
- // Remove ourselves from receiving notifications.
- model_->RemoveObserver(this);
-}
-
-void TabStripBridge::TabInsertedAt(TabContents* contents,
- int index,
- bool foreground) {
- [controller_ insertTabWithContents:contents
- atIndex:index
- inForeground:foreground];
-}
-
-void TabStripBridge::TabDetachedAt(TabContents* contents, int index) {
- [controller_ tabDetachedWithContents:contents atIndex:index];
-}
-
-void TabStripBridge::TabSelectedAt(TabContents* old_contents,
- TabContents* new_contents,
- int index,
- bool user_gesture) {
- [controller_ selectTabWithContents:new_contents
- previousContents:old_contents
- atIndex:index
- userGesture:user_gesture];
-}
-
-void TabStripBridge::TabMoved(TabContents* contents,
- int from_index,
- int to_index) {
- NOTIMPLEMENTED();
-}
-
-void TabStripBridge::TabChangedAt(TabContents* contents, int index,
- bool loading_only) {
- [controller_ tabChangedWithContents:contents
- atIndex:index
- loadingOnly:loading_only ? YES : NO];
-}
-
-void TabStripBridge::TabStripEmpty() {
- NOTIMPLEMENTED();
-}
diff --git a/chrome/browser/cocoa/tab_strip_model_observer_bridge.h b/chrome/browser/cocoa/tab_strip_model_observer_bridge.h
new file mode 100644
index 0000000..e31dd59
--- /dev/null
+++ b/chrome/browser/cocoa/tab_strip_model_observer_bridge.h
@@ -0,0 +1,70 @@
+// 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_TAB_STRIP_MODEL_OBSERVER_BRIDGE_H_
+#define CHROME_BROWSER_COCOA_TAB_STRIP_MODEL_OBSERVER_BRIDGE_H_
+
+#import <Foundation/Foundation.h>
+
+#include "chrome/browser/tabs/tab_strip_model.h"
+
+class TabContents;
+
+// A C++ bridge class to handle receiving notifications from the C++ tab strip
+// model. When the caller allocates a bridge, it automatically registers for
+// notifications from |model| and passes messages to |controller| via the
+// informal protocol below. The owner of this object is responsible for deleting
+// it (and thus unhooking notifications) before |controller| is destroyed.
+class TabStripModelObserverBridge : public TabStripModelObserver {
+ public:
+ TabStripModelObserverBridge(TabStripModel* model, id controller);
+ virtual ~TabStripModelObserverBridge();
+
+ // Overridden from TabStripModelObserver
+ virtual void TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground);
+ virtual void TabClosingAt(TabContents* contents, int index);
+ virtual void TabDetachedAt(TabContents* contents, int index);
+ virtual void TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture);
+ virtual void TabMoved(TabContents* contents,
+ int from_index,
+ int to_index);
+ virtual void TabChangedAt(TabContents* contents, int index,
+ bool loading_only);
+ virtual void TabStripEmpty();
+
+ private:
+ id controller_; // weak, owns me
+ TabStripModel* model_; // weak, owned by Browser
+};
+
+// A collection of methods which can be selectively implemented by any
+// Cocoa object to receive updates about changes to a tab strip model. It is
+// ok to not implement them, the calling code checks before calling.
+@interface NSObject(TabStripModelBridge)
+- (void)insertTabWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index
+ inForeground:(bool)inForeground;
+- (void)tabClosingWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index;
+- (void)tabDetachedWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index;
+- (void)selectTabWithContents:(TabContents*)newContents
+ previousContents:(TabContents*)oldContents
+ atIndex:(NSInteger)index
+ userGesture:(bool)wasUserGesture;
+- (void)tabMovedWithContents:(TabContents*)contents
+ fromIndex:(NSInteger)from
+ toIndex:(NSInteger)to;
+- (void)tabChangedWithContents:(TabContents*)contents
+ atIndex:(NSInteger)index
+ loadingOnly:(BOOL)loading;
+- (void)tabStripEmpty;
+@end
+
+#endif // CHROME_BROWSER_COCOA_TAB_STRIP_MODEL_OBSERVER_BRIDGE_H_
diff --git a/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm b/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm
new file mode 100644
index 0000000..1eee36c
--- /dev/null
+++ b/chrome/browser/cocoa/tab_strip_model_observer_bridge.mm
@@ -0,0 +1,87 @@
+// 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 "chrome/browser/cocoa/tab_strip_model_observer_bridge.h"
+
+TabStripModelObserverBridge::TabStripModelObserverBridge(TabStripModel* model,
+ id controller)
+ : controller_(controller), model_(model) {
+ DCHECK(model && controller);
+ // Register to be a listener on the model so we can get updates and tell
+ // |controller_| about them in the future.
+ model_->AddObserver(this);
+}
+
+TabStripModelObserverBridge::~TabStripModelObserverBridge() {
+ // Remove ourselves from receiving notifications.
+ model_->RemoveObserver(this);
+}
+
+void TabStripModelObserverBridge::TabInsertedAt(TabContents* contents,
+ int index,
+ bool foreground) {
+ if ([controller_ respondsToSelector:
+ @selector(insertTabWithContents:atIndex:inForeground:)]) {
+ [controller_ insertTabWithContents:contents
+ atIndex:index
+ inForeground:foreground];
+ }
+}
+
+void TabStripModelObserverBridge::TabClosingAt(TabContents* contents,
+ int index) {
+ if ([controller_ respondsToSelector:
+ @selector(tabClosingWithContents:atIndex:)]) {
+ [controller_ tabClosingWithContents:contents atIndex:index];
+ }
+}
+
+void TabStripModelObserverBridge::TabDetachedAt(TabContents* contents,
+ int index) {
+ if ([controller_ respondsToSelector:
+ @selector(tabDetachedWithContents:atIndex:)]) {
+ [controller_ tabDetachedWithContents:contents atIndex:index];
+ }
+}
+
+void TabStripModelObserverBridge::TabSelectedAt(TabContents* old_contents,
+ TabContents* new_contents,
+ int index,
+ bool user_gesture) {
+ if ([controller_ respondsToSelector:
+ @selector(selectTabWithContents:previousContents:atIndex:
+ userGesture:)]) {
+ [controller_ selectTabWithContents:new_contents
+ previousContents:old_contents
+ atIndex:index
+ userGesture:user_gesture];
+ }
+}
+
+void TabStripModelObserverBridge::TabMoved(TabContents* contents,
+ int from_index,
+ int to_index) {
+ if ([controller_ respondsToSelector:
+ @selector(tabMovedWithContents:fromIndex:toIndex:)]) {
+ [controller_ tabMovedWithContents:contents
+ fromIndex:from_index
+ toIndex:to_index];
+ }
+}
+
+void TabStripModelObserverBridge::TabChangedAt(TabContents* contents,
+ int index,
+ bool loading_only) {
+ if ([controller_ respondsToSelector:
+ @selector(tabChangedWithContents:atIndex:loadingOnly:)]) {
+ [controller_ tabChangedWithContents:contents
+ atIndex:index
+ loadingOnly:loading_only ? YES : NO];
+ }
+}
+
+void TabStripModelObserverBridge::TabStripEmpty() {
+ if ([controller_ respondsToSelector:@selector(tabStripEmpty)])
+ [controller_ tabStripEmpty];
+}