summaryrefslogtreecommitdiffstats
path: root/chrome/browser/views/tabs
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-16 22:13:22 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-16 22:13:22 +0000
commitec348507c86c875b051f561bdb5cde1162534d97 (patch)
tree8a6381fac4ad3f4610307b6c48ce99cdd81bb953 /chrome/browser/views/tabs
parent2152600d98b5c802fec1caba84ae9d0cb16af235 (diff)
downloadchromium_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.cc4
-rw-r--r--chrome/browser/views/tabs/base_tab_renderer.h14
-rw-r--r--chrome/browser/views/tabs/base_tab_strip.cc167
-rw-r--r--chrome/browser/views/tabs/base_tab_strip.h152
-rw-r--r--chrome/browser/views/tabs/browser_tab_strip_controller.cc4
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.cc99
-rw-r--r--chrome/browser/views/tabs/dragged_tab_controller.h42
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.cc74
-rw-r--r--chrome/browser/views/tabs/side_tab_strip.h23
-rw-r--r--chrome/browser/views/tabs/tab.cc4
-rw-r--r--chrome/browser/views/tabs/tab.h14
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc422
-rw-r--r--chrome/browser/views/tabs/tab_strip.h82
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);
};