diff options
author | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-08 13:46:34 +0000 |
---|---|---|
committer | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-08 13:46:34 +0000 |
commit | 51a5ea2a6ef9d361b62ef1e6f3590131ac395cea (patch) | |
tree | 85e8c73758d3ff70f990265b824708ca6b427483 /chrome/browser/cocoa | |
parent | 653bd5f03ef74274adbec816df10cdfd046b6eea (diff) | |
download | chromium_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.h | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 46 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.h | 4 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_controller.mm | 109 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_model_observer_bridge.h | 70 | ||||
-rw-r--r-- | chrome/browser/cocoa/tab_strip_model_observer_bridge.mm | 87 |
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]; +} |