diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-16 22:13:22 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-16 22:13:22 +0000 |
commit | ec348507c86c875b051f561bdb5cde1162534d97 (patch) | |
tree | 8a6381fac4ad3f4610307b6c48ce99cdd81bb953 /chrome/browser/views/tabs | |
parent | 2152600d98b5c802fec1caba84ae9d0cb16af235 (diff) | |
download | chromium_src-ec348507c86c875b051f561bdb5cde1162534d97.zip chromium_src-ec348507c86c875b051f561bdb5cde1162534d97.tar.gz chromium_src-ec348507c86c875b051f561bdb5cde1162534d97.tar.bz2 |
More TabStrip refactoring.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/2124003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47387 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/views/tabs')
-rw-r--r-- | chrome/browser/views/tabs/base_tab_renderer.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab_renderer.h | 14 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab_strip.cc | 167 | ||||
-rw-r--r-- | chrome/browser/views/tabs/base_tab_strip.h | 152 | ||||
-rw-r--r-- | chrome/browser/views/tabs/browser_tab_strip_controller.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_controller.cc | 99 | ||||
-rw-r--r-- | chrome/browser/views/tabs/dragged_tab_controller.h | 42 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.cc | 74 | ||||
-rw-r--r-- | chrome/browser/views/tabs/side_tab_strip.h | 23 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab.cc | 4 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab.h | 14 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 422 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.h | 82 |
13 files changed, 563 insertions, 538 deletions
diff --git a/chrome/browser/views/tabs/base_tab_renderer.cc b/chrome/browser/views/tabs/base_tab_renderer.cc index e9f138d..e2c2251 100644 --- a/chrome/browser/views/tabs/base_tab_renderer.cc +++ b/chrome/browser/views/tabs/base_tab_renderer.cc @@ -5,7 +5,9 @@ #include "chrome/browser/views/tabs/base_tab_renderer.h" BaseTabRenderer::BaseTabRenderer(TabController* controller) - : controller_(controller) { + : controller_(controller), + closing_(false), + dragging_(false) { } void BaseTabRenderer::SetData(const TabRendererData& data) { diff --git a/chrome/browser/views/tabs/base_tab_renderer.h b/chrome/browser/views/tabs/base_tab_renderer.h index 8c80a53..12491c4 100644 --- a/chrome/browser/views/tabs/base_tab_renderer.h +++ b/chrome/browser/views/tabs/base_tab_renderer.h @@ -58,6 +58,14 @@ class BaseTabRenderer : public views::View { // invoked. virtual void UpdateLoadingAnimation(TabRendererData::NetworkState state); + // Used to set/check whether this Tab is being animated closed. + void set_closing(bool closing) { closing_ = closing; } + bool closing() const { return closing_; } + + // See description above field. + void set_dragging(bool dragging) { dragging_ = dragging; } + bool dragging() const { return dragging_; } + protected: // Invoked from SetData after |data_| has been updated to the new data. virtual void DataChanged(const TabRendererData& old) {} @@ -74,6 +82,12 @@ class BaseTabRenderer : public views::View { TabRendererData data_; + // True if the tab is being animated closed. + bool closing_; + + // True if the tab is being dragged. + bool dragging_; + DISALLOW_COPY_AND_ASSIGN(BaseTabRenderer); }; diff --git a/chrome/browser/views/tabs/base_tab_strip.cc b/chrome/browser/views/tabs/base_tab_strip.cc index a39633b..6afa538 100644 --- a/chrome/browser/views/tabs/base_tab_strip.cc +++ b/chrome/browser/views/tabs/base_tab_strip.cc @@ -4,10 +4,16 @@ #include "chrome/browser/views/tabs/base_tab_strip.h" +#include "base/logging.h" +#include "chrome/browser/views/tabs/dragged_tab_controller.h" #include "chrome/browser/views/tabs/tab_strip_controller.h" +#include "views/widget/root_view.h" +#include "views/window/window.h" -BaseTabStrip::BaseTabStrip(TabStripController* controller) - : controller_(controller) { +BaseTabStrip::BaseTabStrip(TabStripController* controller, Type type) + : controller_(controller), + type_(type), + attaching_dragged_tab_(false) { } BaseTabStrip::~BaseTabStrip() { @@ -21,6 +27,56 @@ BaseTabRenderer* BaseTabStrip::GetSelectedBaseTab() const { return GetBaseTabAtModelIndex(controller_->GetSelectedIndex()); } +void BaseTabStrip::AddTabAt(int model_index, + bool foreground, + const TabRendererData& data) { + BaseTabRenderer* tab = CreateTab(); + tab->SetData(data); + + TabData d = { tab, gfx::Rect() }; + tab_data_.insert(tab_data_.begin() + ModelIndexToTabIndex(model_index), d); + + AddChildView(tab); + + // Don't animate the first tab, it looks weird, and don't animate anything + // if the containing window isn't visible yet. + if (tab_count() > 1 && GetWindow() && GetWindow()->IsVisible()) + StartInsertTabAnimation(model_index, foreground); + else + Layout(); +} + +void BaseTabStrip::MoveTab(int from_model_index, int to_model_index) { + int from_tab_data_index = ModelIndexToTabIndex(from_model_index); + + BaseTabRenderer* tab = tab_data_[from_tab_data_index].tab; + tab_data_.erase(tab_data_.begin() + from_tab_data_index); + + TabData data = {tab, gfx::Rect()}; + + int to_tab_data_index = ModelIndexToTabIndex(to_model_index); + + tab_data_.insert(tab_data_.begin() + to_tab_data_index, data); + + StartMoveTabAnimation(); +} + +BaseTabRenderer* BaseTabStrip::GetBaseTabAtModelIndex(int model_index) const { + return base_tab_at_tab_index(ModelIndexToTabIndex(model_index)); +} + +int BaseTabStrip::GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const { + for (int i = 0, model_index = 0; i < tab_count(); ++i) { + BaseTabRenderer* current_tab = base_tab_at_tab_index(i); + if (!current_tab->closing()) { + if (current_tab == tab) + return model_index; + model_index++; + } + } + return -1; +} + int BaseTabStrip::GetModelCount() const { return controller_->GetCount(); } @@ -29,6 +85,22 @@ bool BaseTabStrip::IsValidModelIndex(int model_index) const { return controller_->IsValidIndex(model_index); } +int BaseTabStrip::ModelIndexToTabIndex(int model_index) const { + int current_model_index = 0; + for (int i = 0; i < tab_count(); ++i) { + if (!base_tab_at_tab_index(i)->closing()) { + if (current_model_index == model_index) + return i; + current_model_index++; + } + } + return static_cast<int>(tab_data_.size()); +} + +bool BaseTabStrip::IsDragSessionActive() const { + return drag_controller_.get() != NULL; +} + void BaseTabStrip::SelectTab(BaseTabRenderer* tab) { int model_index = GetModelIndexOfBaseTab(tab); if (IsValidModelIndex(model_index)) @@ -52,7 +124,98 @@ bool BaseTabStrip::IsTabSelected(const BaseTabRenderer* tab) const { } bool BaseTabStrip::IsTabPinned(const BaseTabRenderer* tab) const { + if (tab->closing()) + return false; + int model_index = GetModelIndexOfBaseTab(tab); return IsValidModelIndex(model_index) && controller_->IsTabPinned(model_index); } + +void BaseTabStrip::MaybeStartDrag(BaseTabRenderer* tab, + const views::MouseEvent& event) { + // Don't accidentally start any drag operations during animations if the + // mouse is down... during an animation tabs are being resized automatically, + // so the View system can misinterpret this easily if the mouse is down that + // the user is dragging. + if (IsAnimating() || tab->closing() || + controller_->HasAvailableDragActions() == 0) { + return; + } + int model_index = GetModelIndexOfBaseTab(tab); + if (!IsValidModelIndex(model_index)) { + CHECK(false); + return; + } + drag_controller_.reset(new DraggedTabController(tab, this)); + drag_controller_->CaptureDragInfo(tab, event.location()); +} + +void BaseTabStrip::ContinueDrag(const views::MouseEvent& event) { + // We can get called even if |MaybeStartDrag| wasn't called in the event of + // a TabStrip animation when the mouse button is down. In this case we should + // _not_ continue the drag because it can lead to weird bugs. + if (drag_controller_.get()) { + bool started_drag = drag_controller_->started_drag(); + drag_controller_->Drag(); + if (drag_controller_->started_drag() && !started_drag) { + // The drag just started. Redirect mouse events to us to that the tab that + // originated the drag can be safely deleted. + GetRootView()->SetMouseHandler(this); + } + } +} + +bool BaseTabStrip::EndDrag(bool canceled) { + if (!drag_controller_.get()) + return false; + bool started_drag = drag_controller_->started_drag(); + drag_controller_->EndDrag(canceled); + return started_drag; +} + +void BaseTabStrip::Layout() { + StopAnimating(false); + + GenerateIdealBounds(); + + for (int i = 0; i < tab_count(); ++i) + tab_data_[i].tab->SetBounds(tab_data_[i].ideal_bounds); + + SchedulePaint(); +} + +bool BaseTabStrip::OnMouseDragged(const views::MouseEvent& event) { + if (drag_controller_.get()) + drag_controller_->Drag(); + return true; +} + +void BaseTabStrip::OnMouseReleased(const views::MouseEvent& event, + bool canceled) { + EndDrag(canceled); +} + +void BaseTabStrip::RemoveAndDeleteTab(BaseTabRenderer* tab) { + int tab_data_index = TabIndexOfTab(tab); + + DCHECK(tab_data_index != -1); + + // Remove the Tab from the TabStrip's list... + tab_data_.erase(tab_data_.begin() + tab_data_index); + + delete tab; +} + +int BaseTabStrip::TabIndexOfTab(BaseTabRenderer* tab) const { + for (int i = 0; i < tab_count(); ++i) { + if (base_tab_at_tab_index(i) == tab) + return i; + } + return -1; +} + +void BaseTabStrip::DestroyDragController() { + if (IsDragSessionActive()) + drag_controller_.reset(NULL); +} diff --git a/chrome/browser/views/tabs/base_tab_strip.h b/chrome/browser/views/tabs/base_tab_strip.h index 96a527c..b299e72 100644 --- a/chrome/browser/views/tabs/base_tab_strip.h +++ b/chrome/browser/views/tabs/base_tab_strip.h @@ -5,10 +5,14 @@ #ifndef CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_ #define CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_ +#include <vector> + #include "base/scoped_ptr.h" #include "chrome/browser/views/tabs/base_tab_renderer.h" #include "views/view.h" +class BaseTabRenderer; +class DraggedTabController; class TabStrip; class TabStripController; class ThemeProvider; @@ -17,9 +21,16 @@ class ThemeProvider; class BaseTabStrip : public views::View, public TabController { public: - explicit BaseTabStrip(TabStripController* controller); + enum Type { + HORIZONTAL_TAB_STRIP, + VERTICAL_TAB_STRIP + }; + + BaseTabStrip(TabStripController* controller, Type type); virtual ~BaseTabStrip(); + Type type() const { return type_; } + // Returns the preferred height of this TabStrip. This is based on the // typical height of its constituent tabs. virtual int GetPreferredHeight() = 0; @@ -36,9 +47,6 @@ class BaseTabStrip : public views::View, virtual void SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) = 0; - // Returns true if a drag session is currently active. - virtual bool IsDragSessionActive() const = 0; - // Updates the loading animations displayed by tabs in the tabstrip to the // next frame. void UpdateLoadingAnimations(); @@ -56,30 +64,22 @@ class BaseTabStrip : public views::View, // Stops all tab higlighting. virtual void StopAllHighlighting() = 0; - // Returns the tab at the specified model index. - virtual BaseTabRenderer* GetBaseTabAtModelIndex(int model_index) const = 0; - - // Returns the tab at the specified tab index. - virtual BaseTabRenderer* GetBaseTabAtTabIndex(int tab_index) const = 0; - - // Returns the index of the specified tab in the model coordiate system, or - // -1 if tab is closing or not valid. - virtual int GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const = 0; - - // Returns the number of tabs. - virtual int GetTabCount() const = 0; - // Returns the selected tab. virtual BaseTabRenderer* GetSelectedBaseTab() const; + // Retrieves the ideal bounds for the Tab at the specified index. + const gfx::Rect& ideal_bounds(int tab_data_index) { + return tab_data_[tab_data_index].ideal_bounds; + } + // Creates and returns a tab that can be used for dragging. Ownership passes // to the caller. virtual BaseTabRenderer* CreateTabForDragging() = 0; // Adds a tab at the specified index. - virtual void AddTabAt(int model_index, - bool foreground, - const TabRendererData& data) = 0; + void AddTabAt(int model_index, + bool foreground, + const TabRendererData& data); // Removes a tab at the specified index. If |initiated_close| is true, the // close was initiated by the tab strip (such as clicking the close button). @@ -90,7 +90,7 @@ class BaseTabStrip : public views::View, virtual void SelectTabAt(int old_model_index, int new_model_index) = 0; // Moves a tab. - virtual void MoveTab(int from_model_index, int to_model_index) = 0; + virtual void MoveTab(int from_model_index, int to_model_index); // Invoked when the title of a tab changes and the tab isn't loading. virtual void TabTitleChangedNotLoading(int model_index) = 0; @@ -98,10 +98,40 @@ class BaseTabStrip : public views::View, // Sets the tab data at the specified model index. virtual void SetTabData(int model_index, const TabRendererData& data) = 0; - // Cover methods for TabStripController method. + // Returns the tab at the specified model index. + virtual BaseTabRenderer* GetBaseTabAtModelIndex(int model_index) const; + + // Returns the tab at the specified tab index. + BaseTabRenderer* base_tab_at_tab_index(int tab_index) const { + return tab_data_[tab_index].tab; + } + + // Returns the index of the specified tab in the model coordiate system, or + // -1 if tab is closing or not valid. + virtual int GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const; + + // Gets the number of Tabs in the tab strip. + // WARNING: this is the number of tabs displayed by the tabstrip, which if + // an animation is ongoing is not necessarily the same as the number of tabs + // in the model. + int tab_count() const { return static_cast<int>(tab_data_.size()); } + + // Cover method for TabStripController::GetCount. int GetModelCount() const; + + // Cover method for TabStripController::IsValidIndex. bool IsValidModelIndex(int model_index) const; + // Returns the index into |tab_data_| corresponding to the index from the + // TabStripModel, or |tab_data_.size()| if there is no tab representing + // |model_index|. + int ModelIndexToTabIndex(int model_index) const; + + TabStripController* controller() const { return controller_.get(); } + + // Returns true if a drag session is currently active. + bool IsDragSessionActive() const; + // TabController overrides: virtual void SelectTab(BaseTabRenderer* tab); virtual void CloseTab(BaseTabRenderer* tab); @@ -109,14 +139,84 @@ class BaseTabStrip : public views::View, virtual bool IsTabSelected(const BaseTabRenderer* tab) const; virtual bool IsTabPinned(const BaseTabRenderer* tab) const; virtual void MaybeStartDrag(BaseTabRenderer* tab, - const views::MouseEvent& event) = 0; - virtual void ContinueDrag(const views::MouseEvent& event) = 0; - virtual bool EndDrag(bool canceled) = 0; + const views::MouseEvent& event); + virtual void ContinueDrag(const views::MouseEvent& event); + virtual bool EndDrag(bool canceled); - TabStripController* controller() const { return controller_.get(); } + // View overrides: + virtual void Layout(); + + protected: + // The Tabs we contain, and their last generated "good" bounds. + struct TabData { + BaseTabRenderer* tab; + gfx::Rect ideal_bounds; + }; + + // View overrides. + virtual bool OnMouseDragged(const views::MouseEvent& event); + virtual void OnMouseReleased(const views::MouseEvent& event, + bool canceled); + + // Creates and returns a new tab. The caller owners the returned tab. + virtual BaseTabRenderer* CreateTab() = 0; + + // Invoked from |AddTabAt| after the newly created tab has been inserted. + // Subclasses should either start an animation, or layout. + virtual void StartInsertTabAnimation(int model_index, bool foreground) = 0; + + // Invoked from |MoveTab| after |tab_data_| has been updated to animate the + // move. + virtual void StartMoveTabAnimation() = 0; + + // Cleans up the Tab from the TabStrip. This is called from the tab animation + // code and is not a general-purpose method. + void RemoveAndDeleteTab(BaseTabRenderer* tab); + + // Resets the bounds of all non-closing tabs. + virtual void GenerateIdealBounds() = 0; + + void set_ideal_bounds(int index, const gfx::Rect& bounds) { + tab_data_[index].ideal_bounds = bounds; + } + + // Returns the index into |tab_data_| corresponding to the specified tab, or + // -1 if the tab isn't in |tab_data_|. + int TabIndexOfTab(BaseTabRenderer* tab) const; + + // Stops any ongoing animations. If |layout| is true and an animation is + // ongoing this does a layout. + virtual void StopAnimating(bool layout) = 0; + + // Destroys the active drag controller. + void DestroyDragController(); + + // Used by DraggedTabController when the user starts or stops dragging a tab. + virtual void StartedDraggingTab(BaseTabRenderer* tab) = 0; + virtual void StoppedDraggingTab(BaseTabRenderer* tab) = 0; + + // See description above field for details. + bool attaching_dragged_tab() const { return attaching_dragged_tab_; } private: + friend class DraggedTabController; + + // See description above field for details. + void set_attaching_dragged_tab(bool value) { attaching_dragged_tab_ = value; } + scoped_ptr<TabStripController> controller_; + + const Type type_; + + std::vector<TabData> tab_data_; + + // The controller for a drag initiated from a Tab. Valid for the lifetime of + // the drag session. + scoped_ptr<DraggedTabController> drag_controller_; + + // If true, the insert is a result of a drag attaching the tab back to the + // model. + bool attaching_dragged_tab_; }; #endif // CHROME_BROWSER_VIEWS_TABS_BASE_TAB_STRIP_H_ diff --git a/chrome/browser/views/tabs/browser_tab_strip_controller.cc b/chrome/browser/views/tabs/browser_tab_strip_controller.cc index cd7cee7..4ebed88 100644 --- a/chrome/browser/views/tabs/browser_tab_strip_controller.cc +++ b/chrome/browser/views/tabs/browser_tab_strip_controller.cc @@ -211,9 +211,9 @@ void BrowserTabStripController::UpdateLoadingAnimations() { // Don't use the model count here as it's possible for this to be invoked // before we've applied an update from the model (Browser::TabInsertedAt may // be processed before us and invokes this). - for (int tab_index = 0, tab_count = tabstrip_->GetTabCount(); + for (int tab_index = 0, tab_count = tabstrip_->tab_count(); tab_index < tab_count; ++tab_index) { - BaseTabRenderer* tab = tabstrip_->GetBaseTabAtTabIndex(tab_index); + BaseTabRenderer* tab = tabstrip_->base_tab_at_tab_index(tab_index); int model_index = tabstrip_->GetModelIndexOfBaseTab(tab); if (model_->ContainsIndex(model_index)) { TabContents* contents = model_->GetTabContentsAt(model_index); diff --git a/chrome/browser/views/tabs/dragged_tab_controller.cc b/chrome/browser/views/tabs/dragged_tab_controller.cc index 3a4ee25..f3f2fff 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.cc +++ b/chrome/browser/views/tabs/dragged_tab_controller.cc @@ -20,10 +20,11 @@ #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/views/frame/browser_view.h" +#include "chrome/browser/views/tabs/base_tab_renderer.h" +#include "chrome/browser/views/tabs/base_tab_strip.h" #include "chrome/browser/views/tabs/browser_tab_strip_controller.h" #include "chrome/browser/views/tabs/dragged_tab_view.h" #include "chrome/browser/views/tabs/native_view_photobooth.h" -#include "chrome/browser/views/tabs/tab.h" #include "chrome/browser/views/tabs/tab_strip.h" #include "chrome/common/notification_service.h" #include "gfx/canvas.h" @@ -178,7 +179,7 @@ class DockView : public views::View { DISALLOW_COPY_AND_ASSIGN(DockView); }; -gfx::Point ConvertScreenPointToTabStripPoint(TabStrip* tabstrip, +gfx::Point ConvertScreenPointToTabStripPoint(BaseTabStrip* tabstrip, const gfx::Point& screen_point) { gfx::Point tabstrip_topleft; views::View::ConvertPointToScreen(tabstrip, &tabstrip_topleft); @@ -311,12 +312,12 @@ class DraggedTabController::DockDisplayer : public AnimationDelegate { /////////////////////////////////////////////////////////////////////////////// // DraggedTabController, public: -DraggedTabController::DraggedTabController(Tab* source_tab, - TabStrip* source_tabstrip) +DraggedTabController::DraggedTabController(BaseTabRenderer* source_tab, + BaseTabStrip* source_tabstrip) : dragged_contents_(NULL), original_delegate_(NULL), source_tabstrip_(source_tabstrip), - source_model_index_(source_tabstrip->GetModelIndexOfTab(source_tab)), + source_model_index_(source_tabstrip->GetModelIndexOfBaseTab(source_tab)), attached_tabstrip_(NULL), attached_tab_(NULL), offset_to_width_ratio_(0), @@ -343,7 +344,7 @@ DraggedTabController::~DraggedTabController() { SetDraggedContents(NULL); // This removes our observer. } -void DraggedTabController::CaptureDragInfo(Tab* tab, +void DraggedTabController::CaptureDragInfo(views::View* tab, const gfx::Point& mouse_offset) { if (tab->width() > 0) { offset_to_width_ratio_ = static_cast<float>(mouse_offset.x()) / @@ -505,7 +506,7 @@ void DraggedTabController::InitWindowCreatePoint() { // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise, // the window_create_point_ is not in the correct coordinate system. Please // refer to http://crbug.com/6223 comment #15 for detailed information. - Tab* first_tab = source_tabstrip_->GetTabAtTabDataIndex(0); + views::View* first_tab = source_tabstrip_->base_tab_at_tab_index(0); views::View::ConvertPointToWidget(first_tab, &first_source_tab_point_); UpdateWindowCreatePoint(); } @@ -619,12 +620,12 @@ void DraggedTabController::ContinueDragging() { #if defined(OS_CHROMEOS) // We don't allow detaching in chrome os. - TabStrip* target_tabstrip = source_tabstrip_; + BaseTabStrip* target_tabstrip = source_tabstrip_; #else // Determine whether or not we have dragged over a compatible TabStrip in // another browser window. If we have, we should attach to it and start // dragging within it. - TabStrip* target_tabstrip = GetTabStripForPoint(screen_point); + BaseTabStrip* target_tabstrip = GetTabStripForPoint(screen_point); #endif if (target_tabstrip != attached_tabstrip_) { // Make sure we're fully detached from whatever TabStrip we're attached to @@ -653,15 +654,33 @@ void DraggedTabController::MoveAttachedTab(const gfx::Point& screen_point) { DCHECK(!view_.get()); gfx::Point dragged_view_point = GetAttachedTabDragPoint(screen_point); - TabStripModel* attached_model = GetModel(attached_tabstrip_); int from_index = attached_model->GetIndexOfTabContents(dragged_contents_); + if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { + MoveAttachedTabHorizontalTabStrip(screen_point, attached_model, + dragged_view_point, from_index); + } else { + MoveAttachedTabVerticalTabStrip(screen_point, attached_model, + dragged_view_point, from_index); + } + attached_tab_->SchedulePaint(); + attached_tab_->SetX(dragged_view_point.x()); + attached_tab_->SetY(dragged_view_point.y()); + attached_tab_->SchedulePaint(); +} + +void DraggedTabController::MoveAttachedTabHorizontalTabStrip( + const gfx::Point& screen_point, + TabStripModel* model, + const gfx::Point& dragged_view_point, + int from_index) { + TabStrip* tab_strip = static_cast<TabStrip*>(attached_tabstrip_); // Determine the horizontal move threshold. This is dependent on the width // of tabs. The smaller the tabs compared to the standard size, the smaller // the threshold. double unselected, selected; - attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected); + tab_strip->GetCurrentTabWidths(&unselected, &selected); double ratio = unselected / Tab::GetStandardSize().width(); int threshold = static_cast<int>(ratio * kHorizontalMoveThreshold); @@ -670,20 +689,23 @@ void DraggedTabController::MoveAttachedTab(const gfx::Point& screen_point) { // jitter). if (abs(screen_point.x() - last_move_screen_x_) > threshold) { gfx::Point dragged_view_screen_point(dragged_view_point); - views::View::ConvertPointToScreen(attached_tabstrip_, - &dragged_view_screen_point); + views::View::ConvertPointToScreen(tab_strip, &dragged_view_screen_point); gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_screen_point); int to_index = GetInsertionIndexForDraggedBounds(bounds, true); to_index = NormalizeIndexToAttachedTabStrip(to_index); if (from_index != to_index) { last_move_screen_x_ = screen_point.x(); - attached_model->MoveTabContentsAt(from_index, to_index, true); + model->MoveTabContentsAt(from_index, to_index, true); } } - attached_tab_->SchedulePaint(); - attached_tab_->SetX(dragged_view_point.x()); - attached_tab_->SetY(dragged_view_point.y()); - attached_tab_->SchedulePaint(); +} + +void DraggedTabController::MoveAttachedTabVerticalTabStrip( + const gfx::Point& screen_point, + TabStripModel* model, + const gfx::Point& dragged_view_point, + int from_index) { + // TODO(sky): implement me. } void DraggedTabController::MoveDetachedTab(const gfx::Point& screen_point) { @@ -718,7 +740,7 @@ DockInfo DraggedTabController::GetDockInfoAtPoint( return info; } -TabStrip* DraggedTabController::GetTabStripForPoint( +BaseTabStrip* DraggedTabController::GetTabStripForPoint( const gfx::Point& screen_point) { gfx::NativeView dragged_view = NULL; if (view_.get()) { @@ -738,14 +760,15 @@ TabStrip* DraggedTabController::GetTabStripForPoint( !browser->browser()->SupportsWindowFeature(Browser::FEATURE_TABSTRIP)) return NULL; - TabStrip* other_tabstrip = browser->tabstrip()->AsTabStrip(); + BaseTabStrip* other_tabstrip = browser->tabstrip(); if (!other_tabstrip->controller()->IsCompatibleWith(source_tabstrip_)) return NULL; return GetTabStripIfItContains(other_tabstrip, screen_point); } -TabStrip* DraggedTabController::GetTabStripIfItContains( - TabStrip* tabstrip, const gfx::Point& screen_point) const { +BaseTabStrip* DraggedTabController::GetTabStripIfItContains( + BaseTabStrip* tabstrip, const gfx::Point& screen_point) const { + // TODO(sky): this likely needs to be adjusted for vertical tabs. static const int kVerticalDetachMagnetism = 15; // Make sure the specified screen point is actually within the bounds of the // specified tabstrip... @@ -764,7 +787,7 @@ TabStrip* DraggedTabController::GetTabStripIfItContains( return NULL; } -void DraggedTabController::Attach(TabStrip* attached_tabstrip, +void DraggedTabController::Attach(BaseTabStrip* attached_tabstrip, const gfx::Point& screen_point) { DCHECK(!attached_tabstrip_); // We should already have detached by the time // we get here. @@ -778,7 +801,7 @@ void DraggedTabController::Attach(TabStrip* attached_tabstrip, // And we don't need the dragged view. view_.reset(); - Tab* tab = GetTabMatchingDraggedContents(attached_tabstrip_); + BaseTabRenderer* tab = GetTabMatchingDraggedContents(attached_tabstrip_); if (!tab) { // There is no Tab in |attached_tabstrip| that corresponds to the dragged @@ -878,8 +901,8 @@ int DraggedTabController::GetInsertionIndexForDraggedBounds( attached_tabstrip_->MirroredLeftPointForRect(adjusted_bounds)); int index = -1; - for (int i = 0; i < attached_tabstrip_->GetTabCount(); ++i) { - gfx::Rect ideal_bounds = attached_tabstrip_->GetIdealBounds(i); + for (int i = 0; i < attached_tabstrip_->tab_count(); ++i) { + const gfx::Rect& ideal_bounds = attached_tabstrip_->ideal_bounds(i); gfx::Rect left_half = ideal_bounds; left_half.set_width(left_half.width() / 2); gfx::Rect right_half = ideal_bounds; @@ -919,13 +942,18 @@ gfx::Rect DraggedTabController::GetDraggedViewTabStripBounds( return gfx::Rect(client_point.x(), client_point.y(), attached_tab_->width(), attached_tab_->height()); } - // attached_tab_ is NULL when inserting into a new tabstrip. - double sel_width, unselected_width; - attached_tabstrip_->GetCurrentTabWidths(&sel_width, &unselected_width); + if (attached_tabstrip_->type() == BaseTabStrip::HORIZONTAL_TAB_STRIP) { + // attached_tab_ is NULL when inserting into a new tabstrip. + double sel_width, unselected_width; + static_cast<TabStrip*>(attached_tabstrip_)->GetCurrentTabWidths( + &sel_width, &unselected_width); + return gfx::Rect(client_point.x(), client_point.y(), + static_cast<int>(sel_width), + Tab::GetStandardSize().height()); + } // TODO(sky): this needs to adjust based on orientation of the tab strip. return gfx::Rect(client_point.x(), client_point.y(), - static_cast<int>(sel_width), - Tab::GetStandardSize().height()); + 0, Tab::GetStandardSize().height()); } gfx::Point DraggedTabController::GetAttachedTabDragPoint( @@ -950,11 +978,12 @@ gfx::Point DraggedTabController::GetAttachedTabDragPoint( return gfx::Point(x, y); } -Tab* DraggedTabController::GetTabMatchingDraggedContents( - TabStrip* tabstrip) const { - int model_index = GetModel(tabstrip)->GetIndexOfTabContents(dragged_contents_); +BaseTabRenderer* DraggedTabController::GetTabMatchingDraggedContents( + BaseTabStrip* tabstrip) const { + int model_index = + GetModel(tabstrip)->GetIndexOfTabContents(dragged_contents_); return model_index == TabStripModel::kNoTab ? - NULL : tabstrip->GetTabAtModelIndex(model_index); + NULL : tabstrip->GetBaseTabAtModelIndex(model_index); } void DraggedTabController::EndDragImpl(EndDragType type) { diff --git a/chrome/browser/views/tabs/dragged_tab_controller.h b/chrome/browser/views/tabs/dragged_tab_controller.h index f4aca80..8e3355f 100644 --- a/chrome/browser/views/tabs/dragged_tab_controller.h +++ b/chrome/browser/views/tabs/dragged_tab_controller.h @@ -15,11 +15,10 @@ namespace views { class View; } +class BaseTabRenderer; class BaseTabStrip; class DraggedTabView; class NativeViewPhotobooth; -class Tab; -class TabStrip; class TabStripModel; struct TabRendererData; @@ -39,13 +38,14 @@ class DraggedTabController : public TabContentsDelegate, public NotificationObserver, public MessageLoopForUI::Observer { public: - DraggedTabController(Tab* source_tab, TabStrip* source_tabstrip); + DraggedTabController(BaseTabRenderer* source_tab, + BaseTabStrip* source_tabstrip); virtual ~DraggedTabController(); // Capture information needed to be used during a drag session for this - // controller's associated source Tab and TabStrip. |mouse_offset| is the - // distance of the mouse pointer from the Tab's origin. - void CaptureDragInfo(Tab* tab, const gfx::Point& mouse_offset); + // controller's associated source tab and BaseTabStrip. |mouse_offset| is the + // distance of the mouse pointer from the tab's origin. + void CaptureDragInfo(views::View* tab, const gfx::Point& mouse_offset); // Responds to drag events subsequent to StartDrag. If the mouse moves a // sufficient distance before the mouse is released, a drag session is @@ -153,22 +153,36 @@ class DraggedTabController : public TabContentsDelegate, // Handles dragging a tab while the tab is attached. void MoveAttachedTab(const gfx::Point& screen_point); + // Adjusts the model as necessary for a move when the attached tab strip is + // horizontal. + void MoveAttachedTabHorizontalTabStrip(const gfx::Point& screen_point, + TabStripModel* model, + const gfx::Point& dragged_view_point, + int from_index); + + // Adjusts the model as necessary for a move when the attached tab strip is + // vertical. + void MoveAttachedTabVerticalTabStrip(const gfx::Point& screen_point, + TabStripModel* model, + const gfx::Point& dragged_view_point, + int from_index); + // Handles dragging while the tab is detached. void MoveDetachedTab(const gfx::Point& screen_point); // Returns the compatible TabStrip that is under the specified point (screen // coordinates), or NULL if there is none. - TabStrip* GetTabStripForPoint(const gfx::Point& screen_point); + BaseTabStrip* GetTabStripForPoint(const gfx::Point& screen_point); DockInfo GetDockInfoAtPoint(const gfx::Point& screen_point); // Returns the specified |tabstrip| if it contains the specified point // (screen coordinates), NULL if it does not. - TabStrip* GetTabStripIfItContains(TabStrip* tabstrip, - const gfx::Point& screen_point) const; + BaseTabStrip* GetTabStripIfItContains(BaseTabStrip* tabstrip, + const gfx::Point& screen_point) const; // Attach the dragged Tab to the specified TabStrip. - void Attach(TabStrip* attached_tabstrip, const gfx::Point& screen_point); + void Attach(BaseTabStrip* attached_tabstrip, const gfx::Point& screen_point); // Detach the dragged Tab from the current TabStrip. void Detach(); @@ -190,7 +204,7 @@ class DraggedTabController : public TabContentsDelegate, // Finds the Tab within the specified TabStrip that corresponds to the // dragged TabContents. - Tab* GetTabMatchingDraggedContents(TabStrip* tabstrip) const; + BaseTabRenderer* GetTabMatchingDraggedContents(BaseTabStrip* tabstrip) const; // Does the work for EndDrag. If we actually started a drag and |how_end| is // not TAB_DESTROYED then one of EndDrag or RevertDrag is invoked. @@ -241,7 +255,7 @@ class DraggedTabController : public TabContentsDelegate, TabContentsDelegate* original_delegate_; // The TabStrip |source_tab_| originated from. - TabStrip* source_tabstrip_; + BaseTabStrip* source_tabstrip_; // This is the index of the |source_tab_| in |source_tabstrip_| when the drag // began. This is used to restore the previous state if the drag is aborted. @@ -249,10 +263,10 @@ class DraggedTabController : public TabContentsDelegate, // The TabStrip the dragged Tab is currently attached to, or NULL if the // dragged Tab is detached. - TabStrip* attached_tabstrip_; + BaseTabStrip* attached_tabstrip_; // If attached this is the tab we're dragging. - Tab* attached_tab_; + BaseTabRenderer* attached_tab_; // The visual representation of the dragged Tab. scoped_ptr<DraggedTabView> view_; diff --git a/chrome/browser/views/tabs/side_tab_strip.cc b/chrome/browser/views/tabs/side_tab_strip.cc index afcd9c4..2a973d5 100644 --- a/chrome/browser/views/tabs/side_tab_strip.cc +++ b/chrome/browser/views/tabs/side_tab_strip.cc @@ -17,11 +17,12 @@ const int kTabStripInset = 3; // SideTabStrip, public: SideTabStrip::SideTabStrip(TabStripController* controller) - : BaseTabStrip(controller) { + : BaseTabStrip(controller, BaseTabStrip::VERTICAL_TAB_STRIP) { SetID(VIEW_ID_TAB_STRIP); } SideTabStrip::~SideTabStrip() { + DestroyDragController(); } //////////////////////////////////////////////////////////////////////////////// @@ -42,10 +43,6 @@ void SideTabStrip::SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) { } -bool SideTabStrip::IsDragSessionActive() const { - return false; -} - bool SideTabStrip::IsAnimating() const { return false; } @@ -64,30 +61,10 @@ BaseTabRenderer* SideTabStrip::GetBaseTabAtModelIndex(int model_index) const { return static_cast<BaseTabRenderer*>(GetChildViewAt(model_index)); } -BaseTabRenderer* SideTabStrip::GetBaseTabAtTabIndex(int tab_index) const { - return static_cast<BaseTabRenderer*>(GetChildViewAt(tab_index)); -} - -int SideTabStrip::GetTabCount() const { - return GetChildViewCount(); -} - BaseTabRenderer* SideTabStrip::CreateTabForDragging() { return new SideTab(NULL); } -int SideTabStrip::GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const { - return GetChildIndex(tab); -} - -void SideTabStrip::AddTabAt(int model_index, - bool foreground, - const TabRendererData& data) { - SideTab* tab = new SideTab(this); - AddChildView(tab); - Layout(); -} - void SideTabStrip::RemoveTabAt(int index, bool initiated_close) { View* v = GetChildViewAt(index); RemoveChildView(v); @@ -99,41 +76,46 @@ void SideTabStrip::SelectTabAt(int old_model_index, int new_model_index) { GetChildViewAt(new_model_index)->SchedulePaint(); } -void SideTabStrip::MoveTab(int from_model_index, int to_model_index) { -} - void SideTabStrip::TabTitleChangedNotLoading(int model_index) { } void SideTabStrip::SetTabData(int model_index, const TabRendererData& data) { + BaseTabRenderer* tab = GetBaseTabAtModelIndex(model_index); + tab->SetData(data); + tab->SchedulePaint(); } -void SideTabStrip::MaybeStartDrag(BaseTabRenderer* tab, - const views::MouseEvent& event) { -} - -void SideTabStrip::ContinueDrag(const views::MouseEvent& event) { +gfx::Size SideTabStrip::GetPreferredSize() { + return gfx::Size(kTabStripWidth, 0); } -bool SideTabStrip::EndDrag(bool canceled) { - return false; +BaseTabRenderer* SideTabStrip::CreateTab() { + return new SideTab(this); } -//////////////////////////////////////////////////////////////////////////////// -// SideTabStrip, views::View overrides: - -void SideTabStrip::Layout() { +void SideTabStrip::GenerateIdealBounds() { gfx::Rect layout_rect = GetLocalBounds(false); layout_rect.Inset(kTabStripInset, kTabStripInset); + int y = layout_rect.y(); - for (int c = GetChildViewCount(), i = 0; i < c; ++i) { - views::View* child = GetChildViewAt(i); - child->SetBounds(layout_rect.x(), y, layout_rect.width(), - child->GetPreferredSize().height()); - y = child->bounds().bottom() + kVerticalTabSpacing; + for (int i = 0; i < tab_count(); ++i) { + BaseTabRenderer* tab = base_tab_at_tab_index(i); + if (!tab->closing()) { + gfx::Rect bounds = gfx::Rect(layout_rect.x(), y, layout_rect.width(), + tab->GetPreferredSize().height()); + set_ideal_bounds(i, bounds); + y = bounds.bottom() + kVerticalTabSpacing; + } } } -gfx::Size SideTabStrip::GetPreferredSize() { - return gfx::Size(kTabStripWidth, 0); +void SideTabStrip::StartInsertTabAnimation(int model_index, bool foreground) { + Layout(); +} + +void SideTabStrip::StartMoveTabAnimation() { + Layout(); +} + +void SideTabStrip::StopAnimating(bool layout) { } diff --git a/chrome/browser/views/tabs/side_tab_strip.h b/chrome/browser/views/tabs/side_tab_strip.h index d1a6043..67f9e82 100644 --- a/chrome/browser/views/tabs/side_tab_strip.h +++ b/chrome/browser/views/tabs/side_tab_strip.h @@ -20,34 +20,31 @@ class SideTabStrip : public BaseTabStrip { virtual bool IsPositionInWindowCaption(const gfx::Point& point); virtual void SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds); - virtual bool IsDragSessionActive() const; virtual bool IsAnimating() const; virtual TabStrip* AsTabStrip(); virtual void StartHighlight(int model_index); virtual void StopAllHighlighting(); virtual BaseTabRenderer* GetBaseTabAtModelIndex(int model_index) const; - virtual BaseTabRenderer* GetBaseTabAtTabIndex(int tab_index) const; - virtual int GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const; - virtual int GetTabCount() const; virtual BaseTabRenderer* CreateTabForDragging(); - virtual void AddTabAt(int model_index, - bool foreground, - const TabRendererData& data); virtual void RemoveTabAt(int model_index, bool initiated_close); virtual void SelectTabAt(int old_model_index, int new_model_index); - virtual void MoveTab(int from_model_index, int to_model_index); virtual void TabTitleChangedNotLoading(int model_index); virtual void SetTabData(int model_index, const TabRendererData& data); - virtual void MaybeStartDrag(BaseTabRenderer* tab, - const views::MouseEvent& event); - virtual void ContinueDrag(const views::MouseEvent& event); - virtual bool EndDrag(bool canceled); // views::View overrides: - virtual void Layout(); virtual gfx::Size GetPreferredSize(); + protected: + // BaseTabStrip overrides: + virtual BaseTabRenderer* CreateTab(); + virtual void GenerateIdealBounds(); + virtual void StartInsertTabAnimation(int model_index, bool foreground); + virtual void StartMoveTabAnimation(); + virtual void StopAnimating(bool layout); + virtual void StartedDraggingTab(BaseTabRenderer* tab) {} + virtual void StoppedDraggingTab(BaseTabRenderer* tab) {} + private: DISALLOW_COPY_AND_ASSIGN(SideTabStrip); }; diff --git a/chrome/browser/views/tabs/tab.cc b/chrome/browser/views/tabs/tab.cc index 8a7b731..9920f69 100644 --- a/chrome/browser/views/tabs/tab.cc +++ b/chrome/browser/views/tabs/tab.cc @@ -30,9 +30,7 @@ static const SkScalar kTabBottomCurveWidth = 3; // Tab, public: Tab::Tab(TabController* controller) - : TabRenderer(controller), - closing_(false), - dragging_(false) { + : TabRenderer(controller) { close_button()->SetTooltipText(l10n_util::GetString(IDS_TOOLTIP_CLOSE_TAB)); close_button()->SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_CLOSE)); close_button()->SetAnimationDuration(0); diff --git a/chrome/browser/views/tabs/tab.h b/chrome/browser/views/tabs/tab.h index e5ab9b9..f798618 100644 --- a/chrome/browser/views/tabs/tab.h +++ b/chrome/browser/views/tabs/tab.h @@ -28,14 +28,6 @@ class Tab : public TabRenderer, explicit Tab(TabController* controller); virtual ~Tab(); - // Used to set/check whether this Tab is being animated closed. - void set_closing(bool closing) { closing_ = closing; } - bool closing() const { return closing_; } - - // See description above field. - void set_dragging(bool dragging) { dragging_ = dragging; } - bool dragging() const { return dragging_; } - // TabRenderer overrides: virtual bool IsSelected() const; @@ -64,12 +56,6 @@ class Tab : public TabRenderer, // representation. Used by GetViewForPoint for hit-testing. void MakePathForTab(gfx::Path* path) const; - // True if the tab is being animated closed. - bool closing_; - - // True if the tab is being dragged. - bool dragging_; - DISALLOW_COPY_AND_ASSIGN(Tab); }; diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index 49db8cc..c6e45fa 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -15,7 +15,6 @@ #include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/defaults.h" #include "chrome/browser/view_ids.h" -#include "chrome/browser/views/tabs/dragged_tab_controller.h" #include "chrome/browser/views/tabs/tab.h" #include "chrome/browser/views/tabs/tab_strip_controller.h" #include "chrome/common/pref_names.h" @@ -26,7 +25,6 @@ #include "grit/theme_resources.h" #include "views/controls/image_view.h" #include "views/widget/default_theme_provider.h" -#include "views/widget/root_view.h" #include "views/window/non_client_view.h" #include "views/window/window.h" @@ -112,7 +110,7 @@ class NewTabAlphaDelegate class ResetDraggingStateDelegate : public views::BoundsAnimator::OwnedAnimationDelegate { public: - explicit ResetDraggingStateDelegate(Tab* tab) : tab_(tab) { + explicit ResetDraggingStateDelegate(BaseTabRenderer* tab) : tab_(tab) { } virtual void AnimationEnded(const Animation* animation) { @@ -124,7 +122,7 @@ class ResetDraggingStateDelegate } private: - Tab* tab_; + BaseTabRenderer* tab_; DISALLOW_COPY_AND_ASSIGN(ResetDraggingStateDelegate); }; @@ -206,7 +204,7 @@ class TabStrip::RemoveTabDelegate NOTREACHED(); return; } - tabstrip_->RemoveTab(tab_); + tabstrip_->RemoveAndDeleteTab(tab_); HighlightCloseButton(); } @@ -258,7 +256,7 @@ const int TabStrip::mini_to_non_mini_gap_ = 3; const int TabStrip::extra_gap_for_nano_ = 10; TabStrip::TabStrip(TabStripController* controller) - : BaseTabStrip(controller), + : BaseTabStrip(controller, BaseTabStrip::HORIZONTAL_TAB_STRIP), resize_layout_factory_(this), added_as_message_loop_observer_(false), needs_resize_layout_(false), @@ -269,8 +267,7 @@ TabStrip::TabStrip(TabStripController* controller) ALLOW_THIS_IN_INITIALIZER_LIST(bounds_animator_(this)), animation_type_(ANIMATION_DEFAULT), new_tab_button_enabled_(true), - cancelling_animation_(false), - attaching_dragged_tab_(false) { + cancelling_animation_(false) { Init(); } @@ -279,8 +276,7 @@ TabStrip::~TabStrip() { // delete the tabs. StopAnimating(false); - // TODO(beng): remove this if it doesn't work to fix the TabSelectedAt bug. - drag_controller_.reset(NULL); + DestroyDragController(); // Make sure we unhook ourselves as a message loop observer so that we don't // crash in the case where the user closes the window after closing a tab @@ -292,17 +288,6 @@ TabStrip::~TabStrip() { RemoveAllChildViews(true); } -void TabStrip::DestroyDragController() { - if (IsDragSessionActive()) - drag_controller_.reset(NULL); -} - -gfx::Rect TabStrip::GetIdealBounds(int tab_data_index) { - DCHECK_GE(tab_data_index, 0); - DCHECK_LT(tab_data_index, GetTabCount()); - return tab_data_[tab_data_index].ideal_bounds; -} - void TabStrip::InitTabStripButtons() { newtab_button_ = new NewTabButton(this); if (browser_defaults::kSizeTabButtonToTopOfTabStrip) { @@ -326,8 +311,7 @@ int TabStrip::GetPreferredHeight() { } void TabStrip::SetBackgroundOffset(const gfx::Point& offset) { - int tab_count = GetTabCount(); - for (int i = 0; i < tab_count; ++i) + for (int i = 0; i < tab_count(); ++i) GetTabAtTabDataIndex(i)->SetBackgroundOffset(offset); } @@ -358,10 +342,6 @@ bool TabStrip::IsPositionInWindowCaption(const gfx::Point& point) { void TabStrip::SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds) { } -bool TabStrip::IsDragSessionActive() const { - return drag_controller_.get() != NULL; -} - bool TabStrip::IsAnimating() const { return bounds_animator_.IsAnimating() || new_tab_timer_.IsRunning(); } @@ -370,33 +350,6 @@ TabStrip* TabStrip::AsTabStrip() { return this; } -void TabStrip::AddTabAt(int model_index, - bool foreground, - const TabRendererData& data) { - Tab* tab = CreateTab(); - tab->SetAnimationContainer(animation_container_.get()); - tab->SetData(data); - - TabData d = { tab, gfx::Rect() }; - tab_data_.insert(tab_data_.begin() + - ModelIndexToTabDataIndex(model_index), d); - - AddChildView(tab); - - // Don't animate the first tab, it looks weird, and don't animate anything - // if the containing window isn't visible yet. - if (GetTabCount() > 1 && GetWindow() && GetWindow()->IsVisible()) { - if (!IsDragSessionActive() && !attaching_dragged_tab_ && - ShouldStartIntertTabAnimationAtEnd(model_index, foreground)) { - StartInsertTabAnimationAtEnd(); - } else { - StartInsertTabAnimation(model_index); - } - } else { - Layout(); - } -} - void TabStrip::RemoveTabAt(int model_index, bool initiated_close) { if (initiated_close) { int model_count = GetModelCount(); @@ -418,7 +371,6 @@ void TabStrip::RemoveTabAt(int model_index, bool initiated_close) { AddMessageLoopObserver(); } } - StartRemoveTabAnimation(model_index); } @@ -433,15 +385,11 @@ void TabStrip::SelectTabAt(int old_model_index, int new_model_index) { } if (old_model_index >= 0) { - GetTabAtTabDataIndex(ModelIndexToTabDataIndex(old_model_index))-> + GetTabAtTabDataIndex(ModelIndexToTabIndex(old_model_index))-> StopMiniTabTitleAnimation(); } } -void TabStrip::MoveTab(int from_model_index, int to_model_index) { - StartMoveTabAnimation(from_model_index, to_model_index); -} - void TabStrip::TabTitleChangedNotLoading(int model_index) { Tab* tab = GetTabAtModelIndex(model_index); if (tab->data().mini && !tab->IsSelected()) @@ -467,22 +415,10 @@ void TabStrip::StartHighlight(int model_index) { } void TabStrip::StopAllHighlighting() { - for (int i = 0; i < GetTabCount(); ++i) + for (int i = 0; i < tab_count(); ++i) GetTabAtTabDataIndex(i)->StopPulse(); } -BaseTabRenderer* TabStrip::GetBaseTabAtModelIndex(int model_index) const { - return GetTabAtModelIndex(model_index); -} - -BaseTabRenderer* TabStrip::GetBaseTabAtTabIndex(int tab_index) const { - return GetTabAtTabDataIndex(tab_index); -} - -int TabStrip::GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const { - return GetModelIndexOfTab(static_cast<const Tab*>(tab)); -} - BaseTabRenderer* TabStrip::CreateTabForDragging() { Tab* tab = new Tab(NULL); // Make sure the dragged tab shares our theme provider. We need to explicitly @@ -496,8 +432,6 @@ BaseTabRenderer* TabStrip::CreateTabForDragging() { void TabStrip::PaintChildren(gfx::Canvas* canvas) { // Tabs are painted in reverse order, so they stack to the left. - int tab_count = GetTabCount(); - // Phantom tabs appear behind all other tabs and are rendered first. To make // them slightly transparent we render them to a different layer. if (HasPhantomTabs()) { @@ -506,7 +440,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) { canvas->saveLayerAlpha(&bounds, kPhantomTabAlpha, SkCanvas::kARGB_ClipLayer_SaveFlag); canvas->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); - for (int i = tab_count - 1; i >= 0; --i) { + for (int i = tab_count() - 1; i >= 0; --i) { Tab* tab = GetTabAtTabDataIndex(i); if (tab->data().phantom) tab->ProcessPaint(canvas); @@ -516,7 +450,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) { canvas->saveLayerAlpha(&bounds, kPhantomTabIconAlpha, SkCanvas::kARGB_ClipLayer_SaveFlag); canvas->drawARGB(0, 255, 255, 255, SkXfermode::kClear_Mode); - for (int i = tab_count - 1; i >= 0; --i) { + for (int i = tab_count() - 1; i >= 0; --i) { Tab* tab = GetTabAtTabDataIndex(i); if (tab->data().phantom) { canvas->save(); @@ -536,7 +470,7 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) { int model_count = GetModelCount(); - for (int i = tab_count - 1; i >= 0; --i) { + for (int i = tab_count() - 1; i >= 0; --i) { Tab* tab = GetTabAtTabDataIndex(i); // We must ask the _Tab's_ model, not ourselves, because in some situations // the model will be different to this object, e.g. when a Tab is being @@ -598,12 +532,12 @@ void TabStrip::PaintChildren(gfx::Canvas* canvas) { // Overridden to support automation. See automation_proxy_uitest.cc. views::View* TabStrip::GetViewByID(int view_id) const { - if (GetTabCount() > 0) { + if (tab_count() > 0) { if (view_id == VIEW_ID_TAB_LAST) { - return GetTabAtTabDataIndex(GetTabCount() - 1); + return GetTabAtTabDataIndex(tab_count() - 1); } else if ((view_id >= VIEW_ID_TAB_0) && (view_id < VIEW_ID_TAB_LAST)) { int index = view_id - VIEW_ID_TAB_0; - if (index >= 0 && index < GetTabCount()) { + if (index >= 0 && index < tab_count()) { return GetTabAtTabDataIndex(index); } else { return NULL; @@ -615,14 +549,7 @@ views::View* TabStrip::GetViewByID(int view_id) const { } void TabStrip::Layout() { - // Called from: - // - window resize - StopAnimating(false); - - GenerateIdealBounds(); - - for (int i = 0, tab_count = GetTabCount(); i < tab_count; ++i) - tab_data_[i].tab->SetBounds(tab_data_[i].ideal_bounds); + BaseTabStrip::Layout(); if (new_tab_button_enabled_) { newtab_button_->SetBounds(newtab_button_bounds_); @@ -630,8 +557,6 @@ void TabStrip::Layout() { } else { newtab_button_->SetVisible(false); } - - SchedulePaint(); } gfx::Size TabStrip::GetPreferredSize() { @@ -692,9 +617,8 @@ views::View* TabStrip::GetViewForPoint(const gfx::Point& point) { // walk the display list hit-testing Tabs. Since the selected tab always // renders on top of adjacent tabs, it needs to be hit-tested before any // left-adjacent Tab, so we look ahead for it as we walk. - int tab_count = GetTabCount(); - for (int i = 0; i < tab_count; ++i) { - Tab* next_tab = i < (tab_count - 1) ? GetTabAtTabDataIndex(i + 1) : NULL; + for (int i = 0; i < tab_count(); ++i) { + Tab* next_tab = i < (tab_count() - 1) ? GetTabAtTabDataIndex(i + 1) : NULL; if (next_tab && next_tab->IsSelected() && IsPointInTab(next_tab, point)) return next_tab; Tab* tab = GetTabAtTabDataIndex(i); @@ -720,89 +644,77 @@ void TabStrip::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { } Tab* TabStrip::CreateTab() { - return new Tab(this); + Tab* tab = new Tab(this); + tab->SetAnimationContainer(animation_container_.get()); + return tab; } -void TabStrip::ViewHierarchyChanged(bool is_add, - views::View* parent, - views::View* child) { - if (is_add && child == this) - InitTabStripButtons(); +void TabStrip::StartInsertTabAnimation(int model_index, bool foreground) { + if (!IsDragSessionActive() && !attaching_dragged_tab() && + ShouldStartIntertTabAnimationAtEnd(model_index, foreground)) { + StartInsertTabAnimationAtEnd(); + } else { + StartInsertTabAnimationImpl(model_index); + } } -bool TabStrip::OnMouseDragged(const views::MouseEvent& event) { - if (drag_controller_.get()) - drag_controller_->Drag(); - return true; -} +void TabStrip::StartMoveTabAnimation() { + ResetAnimationState(true); -void TabStrip::OnMouseReleased(const views::MouseEvent& event, - bool canceled) { - EndDrag(canceled); + GenerateIdealBounds(); + AnimateToIdealBounds(); } -/////////////////////////////////////////////////////////////////////////////// -// TabStrip, Tab::Delegate implementation: +void TabStrip::StartedDraggingTab(BaseTabRenderer* tab) { + tab->set_dragging(true); -bool TabStrip::IsTabSelected(const BaseTabRenderer* btr) const { - const Tab* tab = static_cast<const Tab*>(btr); - if (tab->closing() || tab->render_unselected()) - return false; + // Stop any animations on the tab. + bounds_animator_.StopAnimatingView(tab); - return BaseTabStrip::IsTabSelected(btr); + // Move the tab to its ideal bounds. + GenerateIdealBounds(); + int tab_data_index = TabIndexOfTab(tab); + DCHECK(tab_data_index != -1); + tab->SetBounds(ideal_bounds(tab_data_index)); + SchedulePaint(); } -bool TabStrip::IsTabPinned(const BaseTabRenderer* btr) const { - const Tab* tab = static_cast<const Tab*>(btr); - if (tab->closing()) - return false; +void TabStrip::StoppedDraggingTab(BaseTabRenderer* tab) { + int tab_data_index = TabIndexOfTab(tab); + if (tab_data_index == -1) { + // The tab was removed before the drag completed. Don't do anything. + return; + } - return BaseTabStrip::IsTabPinned(tab); + // Animate the view back to its correct position. + ResetAnimationState(true); + GenerateIdealBounds(); + AnimateToIdealBounds(); + bounds_animator_.AnimateViewTo(tab, ideal_bounds(TabIndexOfTab(tab))); + + // Install a delegate to reset the dragging state when done. We have to leave + // dragging true for the tab otherwise it'll draw beneath the new tab button. + bounds_animator_.SetAnimationDelegate(tab, + new ResetDraggingStateDelegate(tab), + true); } -void TabStrip::MaybeStartDrag(BaseTabRenderer* btr, - const views::MouseEvent& event) { - Tab* tab = static_cast<Tab*>(btr); - // Don't accidentally start any drag operations during animations if the - // mouse is down... during an animation tabs are being resized automatically, - // so the View system can misinterpret this easily if the mouse is down that - // the user is dragging. - if (IsAnimating() || tab->closing() || !HasAvailableDragActions()) - return; - int model_index = GetModelIndexOfTab(tab); - if (!IsValidModelIndex(model_index)) { - CHECK(false); - return; - } - drag_controller_.reset(new DraggedTabController(tab, this)); - drag_controller_->CaptureDragInfo(tab, event.location()); -} - -void TabStrip::ContinueDrag(const views::MouseEvent& event) { - // We can get called even if |MaybeStartDrag| wasn't called in the event of - // a TabStrip animation when the mouse button is down. In this case we should - // _not_ continue the drag because it can lead to weird bugs. - if (drag_controller_.get()) { - bool started_drag = drag_controller_->started_drag(); - drag_controller_->Drag(); - if (drag_controller_->started_drag() && !started_drag) { - // The drag just started. Redirect mouse events to us to that the tab that - // originated the drag can be safely deleted. - GetRootView()->SetMouseHandler(this); - } - } +void TabStrip::ViewHierarchyChanged(bool is_add, + views::View* parent, + views::View* child) { + if (is_add && child == this) + InitTabStripButtons(); } -bool TabStrip::EndDrag(bool canceled) { - if (!drag_controller_.get()) +/////////////////////////////////////////////////////////////////////////////// +// TabStrip, Tab::Delegate implementation: + +bool TabStrip::IsTabSelected(const BaseTabRenderer* btr) const { + const Tab* tab = static_cast<const Tab*>(btr); + if (tab->closing() || tab->render_unselected()) return false; - bool started_drag = drag_controller_->started_drag(); - drag_controller_->EndDrag(canceled); - return started_drag; -} -bool TabStrip::HasAvailableDragActions() const { - return controller()->HasAvailableDragActions() != 0; + return BaseTabStrip::IsTabSelected(btr); } /////////////////////////////////////////////////////////////////////////////// @@ -916,17 +828,11 @@ void TabStrip::LoadNewTabButtonImage() { } Tab* TabStrip::GetTabAtTabDataIndex(int tab_data_index) const { - DCHECK_GE(tab_data_index, 0); - DCHECK_LT(tab_data_index, GetTabCount()); - return tab_data_[tab_data_index].tab; + return static_cast<Tab*>(base_tab_at_tab_index(tab_data_index)); } Tab* TabStrip::GetTabAtModelIndex(int model_index) const { - return GetTabAtTabDataIndex(ModelIndexToTabDataIndex(model_index)); -} - -int TabStrip::GetTabCount() const { - return static_cast<int>(tab_data_.size()); + return GetTabAtTabDataIndex(ModelIndexToTabIndex(model_index)); } void TabStrip::GetCurrentTabWidths(double* unselected_width, @@ -1024,7 +930,7 @@ void TabStrip::ResizeLayoutTabs() { // We've been called back after the TabStrip has been emptied out (probably // just prior to the window being destroyed). We need to do nothing here or // else GetTabAt below will crash. - if (GetTabCount() == 0) + if (tab_count() == 0) return; resize_layout_factory_.RevokeAll(); @@ -1035,14 +941,14 @@ void TabStrip::ResizeLayoutTabs() { available_width_for_tabs_ = -1; int mini_tab_count = GetMiniTabCount(); - if (mini_tab_count == GetTabCount()) { + if (mini_tab_count == tab_count()) { // Only mini-tabs, we know the tab widths won't have changed (all // mini-tabs have the same width), so there is nothing to do. return; } Tab* first_tab = GetTabAtTabDataIndex(mini_tab_count); double unselected, selected; - GetDesiredTabWidths(GetTabCount(), mini_tab_count, GetNanoTabCount(), + GetDesiredTabWidths(tab_count(), mini_tab_count, GetNanoTabCount(), &unselected, &selected); int w = Round(first_tab->IsSelected() ? selected : selected); @@ -1093,7 +999,7 @@ gfx::Rect TabStrip::GetDropBounds(int drop_index, bool* is_beneath) { DCHECK(drop_index != -1); int center_x; - if (drop_index < GetTabCount()) { + if (drop_index < tab_count()) { Tab* tab = GetTabAtTabDataIndex(drop_index); if (drop_before) center_x = tab->x() - (kTabHOffset / 2); @@ -1135,7 +1041,7 @@ void TabStrip::UpdateDropIndex(const DropTargetEvent& event) { // original (and therefore non-mirrored) positions of the tabs. const int x = MirroredXCoordinateInsideView(event.x()); // We don't allow replacing the urls of mini-tabs. - for (int i = GetMiniTabCount(); i < GetTabCount(); ++i) { + for (int i = GetMiniTabCount(); i < tab_count(); ++i) { Tab* tab = GetTabAtTabDataIndex(i); const int tab_max_x = tab->x() + tab->width(); const int hot_width = tab->width() / 3; @@ -1151,7 +1057,7 @@ void TabStrip::UpdateDropIndex(const DropTargetEvent& event) { } // The drop isn't over a tab, add it to the end. - SetDropIndex(GetTabCount(), true); + SetDropIndex(tab_count(), true); } void TabStrip::SetDropIndex(int tab_data_index, bool drop_before) { @@ -1249,16 +1155,16 @@ TabStrip::DropInfo::~DropInfo() { // - Tab insertion/removal // - Tab reorder void TabStrip::GenerateIdealBounds() { - int tab_count = GetTabCount(); int non_closing_tab_count = 0; int mini_tab_count = 0; int nano_tab_count = 0; - for (int i = 0; i < tab_count; ++i) { - if (!tab_data_[i].tab->closing()) { + for (int i = 0; i < tab_count(); ++i) { + BaseTabRenderer* tab = base_tab_at_tab_index(i); + if (!tab->closing()) { ++non_closing_tab_count; - if (tab_data_[i].tab->data().mini) + if (tab->data().mini) mini_tab_count++; - if (tab_data_[i].tab->data().app) + if (tab->data().app) nano_tab_count++; } } @@ -1275,9 +1181,9 @@ void TabStrip::GenerateIdealBounds() { int tab_height = Tab::GetStandardSize().height(); double tab_x = 0; bool last_was_mini = false; - for (int i = 0; i < tab_count; ++i) { - if (!tab_data_[i].tab->closing()) { + for (int i = 0; i < tab_count(); ++i) { Tab* tab = GetTabAtTabDataIndex(i); + if (!tab->closing()) { double tab_width = unselected; if (tab->data().mini) { tab_width = Tab::GetMiniWidth(); @@ -1293,9 +1199,9 @@ void TabStrip::GenerateIdealBounds() { } double end_of_tab = tab_x + tab_width; int rounded_tab_x = Round(tab_x); - tab_data_[i].ideal_bounds = + set_ideal_bounds(i, gfx::Rect(rounded_tab_x, 0, Round(end_of_tab) - rounded_tab_x, - tab_height); + tab_height)); tab_x = end_of_tab + kTabHOffset; last_was_mini = tab->data().mini; } @@ -1318,15 +1224,16 @@ void TabStrip::GenerateIdealBounds() { } void TabStrip::NewTabAnimation1Done() { - int tab_data_index = static_cast<int>(tab_data_.size() - 1); + int tab_data_index = tab_count() - 1; Tab* tab = GetTabAtTabDataIndex(tab_data_index); gfx::Rect old_tab_bounds = tab->bounds(); GenerateIdealBounds(); - gfx::Rect& end_bounds = tab_data_[tab_data_index].ideal_bounds; + gfx::Rect end_bounds = ideal_bounds(tab_data_index); end_bounds.Offset(kNewTabOvershoot, 0); + set_ideal_bounds(tab_data_index, end_bounds); int x = old_tab_bounds.right() - end_bounds.width(); int w = end_bounds.width(); @@ -1360,15 +1267,15 @@ void TabStrip::NewTabAnimation2Done() { animation->SetTweenType(Tween::EASE_IN_OUT); // BoundsAnimator takes ownership of animation. - bounds_animator_.SetAnimationForView(tab_data_.back().tab, animation); + bounds_animator_.SetAnimationForView( + GetTabAtTabDataIndex(tab_count() - 1), animation); } void TabStrip::AnimateToIdealBounds() { - for (size_t i = 0; i < tab_data_.size(); ++i) { - if (!tab_data_[i].tab->closing() && !tab_data_[i].tab->dragging()) { - bounds_animator_.AnimateViewTo(tab_data_[i].tab, - tab_data_[i].ideal_bounds); - } + for (int i = 0; i < tab_count(); ++i) { + Tab* tab = GetTabAtTabDataIndex(i); + if (!tab->closing() && !tab->dragging()) + bounds_animator_.AnimateViewTo(tab, ideal_bounds(i)); } if (animation_type_ != ANIMATION_NEW_TAB_3) { @@ -1398,12 +1305,12 @@ void TabStrip::StartInsertTabAnimationAtEnd() { GenerateIdealBounds(); - int tab_data_index = ModelIndexToTabDataIndex(GetModelCount() - 1); - Tab* tab = tab_data_[tab_data_index].tab; + int tab_data_index = ModelIndexToTabIndex(GetModelCount() - 1); + Tab* tab = GetTabAtTabDataIndex(tab_data_index); tab->SizeToNewTabButtonImages(); tab->SetBounds(newtab_button_->x() + (newtab_button_->width() - tab->width()) / 2, - tab_data_[tab_data_index].ideal_bounds.y(), + ideal_bounds(tab_data_index).y(), tab->width(), tab->height()); tab->set_render_as_new_tab(true); @@ -1411,7 +1318,7 @@ void TabStrip::StartInsertTabAnimationAtEnd() { this, &TabStrip::NewTabAnimation1Done); } -void TabStrip::StartInsertTabAnimation(int model_index) { +void TabStrip::StartInsertTabAnimationImpl(int model_index) { ResetAnimationState(true); // The TabStrip can now use its entire width to lay out Tabs. @@ -1419,16 +1326,16 @@ void TabStrip::StartInsertTabAnimation(int model_index) { GenerateIdealBounds(); - int tab_data_index = ModelIndexToTabDataIndex(model_index); - Tab* tab = tab_data_[tab_data_index].tab; + int tab_data_index = ModelIndexToTabIndex(model_index); + BaseTabRenderer* tab = base_tab_at_tab_index(tab_data_index); if (model_index == 0) { - tab->SetBounds(0, tab_data_[tab_data_index].ideal_bounds.y(), 0, - tab_data_[tab_data_index].ideal_bounds.height()); + tab->SetBounds(0, ideal_bounds(tab_data_index).y(), 0, + ideal_bounds(tab_data_index).height()); } else { - Tab* last_tab = tab_data_[tab_data_index - 1].tab; + BaseTabRenderer* last_tab = base_tab_at_tab_index(tab_data_index - 1); tab->SetBounds(last_tab->bounds().right() + kTabHOffset, - tab_data_[tab_data_index].ideal_bounds.y(), 0, - tab_data_[tab_data_index].ideal_bounds.height()); + ideal_bounds(tab_data_index).y(), 0, + ideal_bounds(tab_data_index).height()); } AnimateToIdealBounds(); @@ -1438,8 +1345,7 @@ void TabStrip::StartRemoveTabAnimation(int model_index) { ResetAnimationState(true); // Mark the tab as closing. - int tab_data_index = ModelIndexToTabDataIndex(model_index); - Tab* tab = tab_data_[tab_data_index].tab; + Tab* tab = GetTabAtModelIndex(model_index); tab->set_closing(true); // Start an animation for the tabs. @@ -1457,25 +1363,6 @@ void TabStrip::StartRemoveTabAnimation(int model_index) { true); } -void TabStrip::StartMoveTabAnimation(int from_model_index, - int to_model_index) { - ResetAnimationState(true); - - int from_tab_data_index = ModelIndexToTabDataIndex(from_model_index); - - Tab* tab = tab_data_[from_tab_data_index].tab; - tab_data_.erase(tab_data_.begin() + from_tab_data_index); - - TabData data = {tab, gfx::Rect()}; - - int to_tab_data_index = ModelIndexToTabDataIndex(to_model_index); - - tab_data_.insert(tab_data_.begin() + to_tab_data_index, data); - - GenerateIdealBounds(); - AnimateToIdealBounds(); -} - void TabStrip::StartMiniTabAnimation() { ResetAnimationState(true); @@ -1515,7 +1402,7 @@ void TabStrip::ResetAnimationState(bool stop_new_tab_timer) { animation_type_ = ANIMATION_DEFAULT; // Reset the animation state of each tab. - for (int i = 0, count = GetTabCount(); i < count; ++i) { + for (int i = 0; i < tab_count(); ++i) { Tab* tab = GetTabAtTabDataIndex(i); tab->set_render_as_new_tab(false); tab->set_render_unselected(false); @@ -1525,8 +1412,8 @@ void TabStrip::ResetAnimationState(bool stop_new_tab_timer) { int TabStrip::GetMiniTabCount() const { int mini_count = 0; - for (size_t i = 0; i < tab_data_.size(); ++i) { - if (tab_data_[i].tab->data().mini) + for (int i = 0; i < tab_count(); ++i) { + if (base_tab_at_tab_index(i)->data().mini) mini_count++; else return mini_count; @@ -1536,8 +1423,8 @@ int TabStrip::GetMiniTabCount() const { int TabStrip::GetNanoTabCount() const { int nano_count = 0; - for (size_t i = 0; i < tab_data_.size(); ++i) { - if (tab_data_[i].tab->data().app) + for (int i = 0; i < tab_count(); ++i) { + if (base_tab_at_tab_index(i)->data().app) nano_count++; else return nano_count; @@ -1556,17 +1443,6 @@ bool TabStrip::IsPointInTab(Tab* tab, return tab->HitTest(point_in_tab_coords); } -void TabStrip::RemoveTab(Tab* tab) { - int tab_data_index = TabDataIndexOfTab(tab); - - DCHECK(tab_data_index != -1); - - // Remove the Tab from the TabStrip's list... - tab_data_.erase(tab_data_.begin() + tab_data_index); - - delete tab; -} - void TabStrip::HandleGlobalMouseMoveEvent() { if (!IsCursorInTabStripZone()) { // Mouse moved outside the tab slop zone, start a timer to do a resize @@ -1586,77 +1462,9 @@ void TabStrip::HandleGlobalMouseMoveEvent() { } bool TabStrip::HasPhantomTabs() const { - for (int i = 0; i < GetTabCount(); ++i) { + for (int i = 0; i < tab_count(); ++i) { if (GetTabAtTabDataIndex(i)->data().phantom) return true; } return false; } - -int TabStrip::GetModelIndexOfTab(const Tab* tab) const { - for (int i = 0, model_index = 0; i < GetTabCount(); ++i) { - Tab* current_tab = GetTabAtTabDataIndex(i); - if (!current_tab->closing()) { - if (current_tab == tab) - return model_index; - model_index++; - } - } - return -1; -} - -int TabStrip::ModelIndexToTabDataIndex(int model_index) const { - int current_model_index = 0; - for (size_t i = 0; i < tab_data_.size(); ++i) { - if (!tab_data_[i].tab->closing()) { - if (current_model_index == model_index) - return i; - current_model_index++; - } - } - return tab_data_.size(); -} - -int TabStrip::TabDataIndexOfTab(Tab* tab) const { - for (size_t i = 0; i < tab_data_.size(); ++i) { - if (tab_data_[i].tab == tab) - return i; - } - return -1; -} - -void TabStrip::StartedDraggingTab(Tab* tab) { - tab->set_dragging(true); - - // Stop any animations on the tab. - bounds_animator_.StopAnimatingView(tab); - - // Move the tab to its ideal bounds. - GenerateIdealBounds(); - int tab_data_index = TabDataIndexOfTab(tab); - DCHECK(tab_data_index != -1); - tab->SetBounds(tab_data_[tab_data_index].ideal_bounds); - SchedulePaint(); -} - -void TabStrip::StoppedDraggingTab(Tab* tab) { - int tab_data_index = TabDataIndexOfTab(tab); - if (tab_data_index == -1) { - // The tab was removed before the drag completed. Don't do anything. - return; - } - - // Animate the view back to its correct position. - ResetAnimationState(true); - GenerateIdealBounds(); - AnimateToIdealBounds(); - bounds_animator_.AnimateViewTo( - tab, - tab_data_[TabDataIndexOfTab(tab)].ideal_bounds); - - // Install a delegate to reset the dragging state when done. We have to leave - // dragging true for the tab otherwise it'll draw beneath the new tab button. - bounds_animator_.SetAnimationDelegate(tab, - new ResetDraggingStateDelegate(tab), - true); -} diff --git a/chrome/browser/views/tabs/tab_strip.h b/chrome/browser/views/tabs/tab_strip.h index 7c2e19f..0eadbc1 100644 --- a/chrome/browser/views/tabs/tab_strip.h +++ b/chrome/browser/views/tabs/tab_strip.h @@ -5,8 +5,6 @@ #ifndef CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_ #define CHROME_BROWSER_VIEWS_TABS_TAB_STRIP_H_ -#include <vector> - #include "app/animation_container.h" #include "base/message_loop.h" #include "base/ref_counted.h" @@ -18,8 +16,6 @@ #include "views/animation/bounds_animator.h" #include "views/controls/button/image_button.h" -class DraggedTabController; - namespace views { class ImageView; #if defined(OS_LINUX) @@ -60,12 +56,6 @@ class TabStrip : public BaseTabStrip, return new_tab_button_enabled_; } - // Destroys the active drag controller. - void DestroyDragController(); - - // Retrieves the ideal bounds for the Tab at the specified index. - gfx::Rect GetIdealBounds(int tab_data_index); - // Creates the new tab button. void InitTabStripButtons(); @@ -78,22 +68,14 @@ class TabStrip : public BaseTabStrip, virtual bool IsPositionInWindowCaption(const gfx::Point& point); virtual void SetDraggedTabBounds(int tab_index, const gfx::Rect& tab_bounds); - virtual bool IsDragSessionActive() const; virtual bool IsAnimating() const; virtual TabStrip* AsTabStrip(); - virtual void AddTabAt(int model_index, - bool foreground, - const TabRendererData& data); virtual void RemoveTabAt(int model_index, bool initiated_close); virtual void SelectTabAt(int old_model_index, int new_model_index); - virtual void MoveTab(int from_model_index, int to_model_index); virtual void TabTitleChangedNotLoading(int model_index); virtual void SetTabData(int model_index, const TabRendererData& data); virtual void StartHighlight(int model_index); virtual void StopAllHighlighting(); - virtual BaseTabRenderer* GetBaseTabAtModelIndex(int model_index) const; - virtual BaseTabRenderer* GetBaseTabAtTabIndex(int tab_index) const; - virtual int GetModelIndexOfBaseTab(const BaseTabRenderer* tab) const; virtual BaseTabRenderer* CreateTabForDragging(); // views::View overrides: @@ -115,25 +97,20 @@ class TabStrip : public BaseTabStrip, virtual void OnBoundsAnimatorDone(views::BoundsAnimator* animator); protected: - // Creates a new tab. + // BaseTabStrip overrides: virtual Tab* CreateTab(); + virtual void StartInsertTabAnimation(int model_index, bool foreground); + virtual void StartMoveTabAnimation(); + virtual void StartedDraggingTab(BaseTabRenderer* tab); + virtual void StoppedDraggingTab(BaseTabRenderer* tab); // views::View implementation: virtual void ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child); - virtual bool OnMouseDragged(const views::MouseEvent& event); - virtual void OnMouseReleased(const views::MouseEvent& event, - bool canceled); // TabController overrides. virtual bool IsTabSelected(const BaseTabRenderer* btr) const; - virtual bool IsTabPinned(const BaseTabRenderer* btr) const; - virtual void MaybeStartDrag(BaseTabRenderer* btr, - const views::MouseEvent& event); - virtual void ContinueDrag(const views::MouseEvent& event); - virtual bool EndDrag(bool canceled); - virtual bool HasAvailableDragActions() const; // views::ButtonListener implementation: virtual void ButtonPressed(views::Button* sender, const views::Event& event); @@ -214,12 +191,6 @@ class TabStrip : public BaseTabStrip, DISALLOW_COPY_AND_ASSIGN(DropInfo); }; - // The Tabs we contain, and their last generated "good" bounds. - struct TabData { - Tab* tab; - gfx::Rect ideal_bounds; - }; - void Init(); // Set the images for the new tab button. @@ -238,12 +209,6 @@ class TabStrip : public BaseTabStrip, // Use this instead of GetTabAtTabDataIndex if the index comes from the model. Tab* GetTabAtModelIndex(int model_index) const; - // Gets the number of Tabs in the collection. - // WARNING: this is the number of tabs displayed by the tabstrip, which if - // an animation is ongoing is not necessarily the same as the number of tabs - // in the model. - virtual int GetTabCount() const; - // Returns the number of mini-tabs. int GetMiniTabCount() const; @@ -327,7 +292,7 @@ class TabStrip : public BaseTabStrip, // Starts various types of TabStrip animations. void StartResizeLayoutAnimation(); void StartInsertTabAnimationAtEnd(); - void StartInsertTabAnimation(int model_index); + void StartInsertTabAnimationImpl(int model_index); void StartRemoveTabAnimation(int model_index); void StartMoveTabAnimation(int from_model_index, int to_model_index); @@ -335,7 +300,7 @@ class TabStrip : public BaseTabStrip, // Stops any ongoing animations. If |layout| is true and an animation is // ongoing this does a layout. - void StopAnimating(bool layout); + virtual void StopAnimating(bool layout); // Resets all state related to animations. This is invoked when an animation // completes, prior to starting an animation or when we cancel an animation. @@ -349,10 +314,6 @@ class TabStrip : public BaseTabStrip, // hit-test region of the specified Tab. bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords); - // Cleans up the Tab from the TabStrip. This is called from the tab animation - // code and is not a general-purpose method. - void RemoveTab(Tab* tab); - // Called from the message loop observer when a mouse movement has occurred // anywhere over our containing window. void HandleGlobalMouseMoveEvent(); @@ -360,26 +321,6 @@ class TabStrip : public BaseTabStrip, // Returns true if any of the tabs are phantom. bool HasPhantomTabs() const; - // Returns the index of the specified tab in the model coordiate system, or - // -1 if tab is closing or not in |tab_data_|. - int GetModelIndexOfTab(const Tab* tab) const; - - // Returns the index into |tab_data_| corresponding to the index from the - // TabStripModel, or |tab_data_.size()| if there is no tab representing - // |model_index|. - int ModelIndexToTabDataIndex(int model_index) const; - - // Returns the index into |tab_data_| corresponding to the specified tab, or - // -1 if the tab isn't in |tab_data_|. - int TabDataIndexOfTab(Tab* tab) const; - - // See description above field for details. - void set_attaching_dragged_tab(bool value) { attaching_dragged_tab_ = value; } - - // Used by DraggedTabController when the user starts or stops dragging a tab. - void StartedDraggingTab(Tab* tab); - void StoppedDraggingTab(Tab* tab); - // -- Member Variables ------------------------------------------------------ // A factory that is used to construct a delayed callback to the @@ -425,12 +366,6 @@ class TabStrip : public BaseTabStrip, // Valid for the lifetime of a drag over us. scoped_ptr<DropInfo> drop_info_; - // The controller for a drag initiated from a Tab. Valid for the lifetime of - // the drag session. - scoped_ptr<DraggedTabController> drag_controller_; - - std::vector<TabData> tab_data_; - // To ensure all tabs pulse at the same time they share the same animation // container. This is that animation container. scoped_refptr<AnimationContainer> animation_container_; @@ -449,9 +384,6 @@ class TabStrip : public BaseTabStrip, // If true, we're cancelling the animation. bool cancelling_animation_; - // Used by DraggedTabController when inserting a tab into our model. - bool attaching_dragged_tab_; - DISALLOW_COPY_AND_ASSIGN(TabStrip); }; |