Commit 7be81ff2 authored by sky@chromium.org's avatar sky@chromium.org

Attempt 3 at a better touch tabstrip. There is still a bunch to do,

but this gets things in a better state.

BUG=123274
TEST=covered by unit tests.
R=ben@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10213011

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133930 0039d316-1c4b-4281-b951-d872f2087c98
parent fde2649e
...@@ -290,20 +290,24 @@ bool BaseTab::OnMousePressed(const views::MouseEvent& event) { ...@@ -290,20 +290,24 @@ bool BaseTab::OnMousePressed(const views::MouseEvent& event) {
if (event.IsOnlyLeftMouseButton()) { if (event.IsOnlyLeftMouseButton()) {
TabStripSelectionModel original_selection; TabStripSelectionModel original_selection;
original_selection.Copy(controller()->GetSelectionModel()); original_selection.Copy(controller()->GetSelectionModel());
if (event.IsShiftDown() && event.IsControlDown()) { if (controller()->SupportsMultipleSelection()) {
controller()->AddSelectionFromAnchorTo(this); if (event.IsShiftDown() && event.IsControlDown()) {
} else if (event.IsShiftDown()) { controller()->AddSelectionFromAnchorTo(this);
controller()->ExtendSelectionTo(this); } else if (event.IsShiftDown()) {
} else if (event.IsControlDown()) { controller()->ExtendSelectionTo(this);
controller()->ToggleSelected(this); } else if (event.IsControlDown()) {
if (!IsSelected()) { controller()->ToggleSelected(this);
// Don't allow dragging non-selected tabs. if (!IsSelected()) {
return false; // Don't allow dragging non-selected tabs.
return false;
}
} else if (!IsSelected()) {
controller()->SelectTab(this);
} else if (IsActive()) {
controller()->ClickActiveTab(this);
} }
} else if (!IsSelected()) { } else if (!IsSelected()) {
controller()->SelectTab(this); controller()->SelectTab(this);
} else if (IsActive()) {
controller()->ClickActiveTab(this);
} }
controller()->MaybeStartDrag(this, event, original_selection); controller()->MaybeStartDrag(this, event, original_selection);
} }
......
...@@ -199,6 +199,10 @@ bool BrowserTabStripController::IsActiveTab(int model_index) const { ...@@ -199,6 +199,10 @@ bool BrowserTabStripController::IsActiveTab(int model_index) const {
return model_->active_index() == model_index; return model_->active_index() == model_index;
} }
int BrowserTabStripController::GetActiveIndex() const {
return model_->active_index();
}
bool BrowserTabStripController::IsTabSelected(int model_index) const { bool BrowserTabStripController::IsTabSelected(int model_index) const {
return model_->IsTabSelected(model_index); return model_->IsTabSelected(model_index);
} }
...@@ -323,7 +327,7 @@ bool BrowserTabStripController::IsIncognito() { ...@@ -323,7 +327,7 @@ bool BrowserTabStripController::IsIncognito() {
void BrowserTabStripController::TabInsertedAt(TabContentsWrapper* contents, void BrowserTabStripController::TabInsertedAt(TabContentsWrapper* contents,
int model_index, int model_index,
bool active) { bool is_active) {
DCHECK(contents); DCHECK(contents);
DCHECK(model_index == TabStripModel::kNoTab || DCHECK(model_index == TabStripModel::kNoTab ||
model_->ContainsIndex(model_index)); model_->ContainsIndex(model_index));
...@@ -334,7 +338,7 @@ void BrowserTabStripController::TabInsertedAt(TabContentsWrapper* contents, ...@@ -334,7 +338,7 @@ void BrowserTabStripController::TabInsertedAt(TabContentsWrapper* contents,
TabRendererData data; TabRendererData data;
SetTabRendererDataFromModel(contents->web_contents(), model_index, &data, SetTabRendererDataFromModel(contents->web_contents(), model_index, &data,
NEW_TAB); NEW_TAB);
tabstrip_->AddTabAt(model_index, data); tabstrip_->AddTabAt(model_index, data, is_active);
} }
void BrowserTabStripController::TabDetachedAt(TabContentsWrapper* contents, void BrowserTabStripController::TabDetachedAt(TabContentsWrapper* contents,
...@@ -357,13 +361,11 @@ void BrowserTabStripController::TabMoved(TabContentsWrapper* contents, ...@@ -357,13 +361,11 @@ void BrowserTabStripController::TabMoved(TabContentsWrapper* contents,
// Cancel any pending tab transition. // Cancel any pending tab transition.
hover_tab_selector_.CancelTabTransition(); hover_tab_selector_.CancelTabTransition();
// Update the data first as the pinned state may have changed. // Pass in the TabRendererData as the pinned state may have changed.
TabRendererData data; TabRendererData data;
SetTabRendererDataFromModel(contents->web_contents(), to_model_index, &data, SetTabRendererDataFromModel(contents->web_contents(), to_model_index, &data,
EXISTING_TAB); EXISTING_TAB);
tabstrip_->SetTabData(from_model_index, data); tabstrip_->MoveTab(from_model_index, to_model_index, data);
tabstrip_->MoveTab(from_model_index, to_model_index);
} }
void BrowserTabStripController::TabChangedAt(TabContentsWrapper* contents, void BrowserTabStripController::TabChangedAt(TabContentsWrapper* contents,
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -48,6 +48,7 @@ class BrowserTabStripController : public TabStripController, ...@@ -48,6 +48,7 @@ class BrowserTabStripController : public TabStripController,
virtual int GetCount() const OVERRIDE; virtual int GetCount() const OVERRIDE;
virtual bool IsValidIndex(int model_index) const OVERRIDE; virtual bool IsValidIndex(int model_index) const OVERRIDE;
virtual bool IsActiveTab(int model_index) const OVERRIDE; virtual bool IsActiveTab(int model_index) const OVERRIDE;
virtual int GetActiveIndex() const OVERRIDE;
virtual bool IsTabSelected(int model_index) const OVERRIDE; virtual bool IsTabSelected(int model_index) const OVERRIDE;
virtual bool IsTabPinned(int model_index) const OVERRIDE; virtual bool IsTabPinned(int model_index) const OVERRIDE;
virtual bool IsTabCloseable(int model_index) const OVERRIDE; virtual bool IsTabCloseable(int model_index) const OVERRIDE;
...@@ -73,7 +74,7 @@ class BrowserTabStripController : public TabStripController, ...@@ -73,7 +74,7 @@ class BrowserTabStripController : public TabStripController,
// TabStripModelObserver implementation: // TabStripModelObserver implementation:
virtual void TabInsertedAt(TabContentsWrapper* contents, virtual void TabInsertedAt(TabContentsWrapper* contents,
int model_index, int model_index,
bool active) OVERRIDE; bool is_active) OVERRIDE;
virtual void TabDetachedAt(TabContentsWrapper* contents, virtual void TabDetachedAt(TabContentsWrapper* contents,
int model_index) OVERRIDE; int model_index) OVERRIDE;
virtual void TabSelectionChanged( virtual void TabSelectionChanged(
......
...@@ -320,6 +320,7 @@ DefaultTabDragController::DefaultTabDragController() ...@@ -320,6 +320,7 @@ DefaultTabDragController::DefaultTabDragController()
active_(true), active_(true),
source_tab_index_(std::numeric_limits<size_t>::max()), source_tab_index_(std::numeric_limits<size_t>::max()),
initial_move_(true), initial_move_(true),
// TODO: remove.
stacking_(false) { stacking_(false) {
instance_ = this; instance_ = this;
} }
...@@ -354,7 +355,6 @@ void DefaultTabDragController::Init( ...@@ -354,7 +355,6 @@ void DefaultTabDragController::Init(
source_tab_offset_ = source_tab_offset; source_tab_offset_ = source_tab_offset;
start_screen_point_ = GetCursorScreenPoint(); start_screen_point_ = GetCursorScreenPoint();
mouse_offset_ = mouse_offset; mouse_offset_ = mouse_offset;
stacking_ = source_tabstrip->IsStacking();
drag_data_.resize(tabs.size()); drag_data_.resize(tabs.size());
for (size_t i = 0; i < tabs.size(); ++i) for (size_t i = 0; i < tabs.size(); ++i)
......
...@@ -15,7 +15,7 @@ FakeBaseTabStripController::~FakeBaseTabStripController() { ...@@ -15,7 +15,7 @@ FakeBaseTabStripController::~FakeBaseTabStripController() {
void FakeBaseTabStripController::AddTab(int index) { void FakeBaseTabStripController::AddTab(int index) {
num_tabs_++; num_tabs_++;
tab_strip_->AddTabAt(index, TabRendererData()); tab_strip_->AddTabAt(index, TabRendererData(), false);
} }
void FakeBaseTabStripController::RemoveTab(int index) { void FakeBaseTabStripController::RemoveTab(int index) {
...@@ -39,6 +39,10 @@ bool FakeBaseTabStripController::IsActiveTab(int index) const { ...@@ -39,6 +39,10 @@ bool FakeBaseTabStripController::IsActiveTab(int index) const {
return false; return false;
} }
int FakeBaseTabStripController::GetActiveIndex() const {
return -1;
}
bool FakeBaseTabStripController::IsTabSelected(int index) const { bool FakeBaseTabStripController::IsTabSelected(int index) const {
return false; return false;
} }
......
...@@ -27,6 +27,7 @@ class FakeBaseTabStripController : public TabStripController { ...@@ -27,6 +27,7 @@ class FakeBaseTabStripController : public TabStripController {
virtual int GetCount() const OVERRIDE; virtual int GetCount() const OVERRIDE;
virtual bool IsValidIndex(int index) const OVERRIDE; virtual bool IsValidIndex(int index) const OVERRIDE;
virtual bool IsActiveTab(int index) const OVERRIDE; virtual bool IsActiveTab(int index) const OVERRIDE;
virtual int GetActiveIndex() const OVERRIDE;
virtual bool IsTabSelected(int index) const OVERRIDE; virtual bool IsTabSelected(int index) const OVERRIDE;
virtual bool IsTabPinned(int index) const OVERRIDE; virtual bool IsTabPinned(int index) const OVERRIDE;
virtual bool IsTabCloseable(int index) const OVERRIDE; virtual bool IsTabCloseable(int index) const OVERRIDE;
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "ui/base/animation/multi_animation.h" #include "ui/base/animation/multi_animation.h"
#include "ui/base/animation/throb_animation.h" #include "ui/base/animation/throb_animation.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/touch/touch_mode_support.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/favicon_size.h" #include "ui/gfx/favicon_size.h"
#include "ui/gfx/font.h" #include "ui/gfx/font.h"
...@@ -72,7 +71,6 @@ static const int kCloseButtonHorzFuzz = 7; ...@@ -72,7 +71,6 @@ static const int kCloseButtonHorzFuzz = 7;
#else #else
static const int kCloseButtonHorzFuzz = 5; static const int kCloseButtonHorzFuzz = 5;
#endif #endif
static const int kTouchModeMinimumWidth = 160;
// When a non-mini-tab becomes a mini-tab the width of the tab animates. If // When a non-mini-tab becomes a mini-tab the width of the tab animates. If
// the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab // the width of a mini-tab is >= kMiniTabRendererAsNormalTabWidth then the tab
...@@ -172,15 +170,11 @@ gfx::Size Tab::GetBasicMinimumUnselectedSize() { ...@@ -172,15 +170,11 @@ gfx::Size Tab::GetBasicMinimumUnselectedSize() {
} }
gfx::Size Tab::GetMinimumUnselectedSize() { gfx::Size Tab::GetMinimumUnselectedSize() {
if (TouchModeSupport::IsTouchOptimized())
return GetTouchModeMinimumSize();
return GetBasicMinimumUnselectedSize(); return GetBasicMinimumUnselectedSize();
} }
// static // static
gfx::Size Tab::GetMinimumSelectedSize() { gfx::Size Tab::GetMinimumSelectedSize() {
if (TouchModeSupport::IsTouchOptimized())
return GetTouchModeMinimumSize();
gfx::Size minimum_size = GetBasicMinimumUnselectedSize(); gfx::Size minimum_size = GetBasicMinimumUnselectedSize();
minimum_size.set_width(kLeftPadding + gfx::kFaviconSize + kRightPadding); minimum_size.set_width(kLeftPadding + gfx::kFaviconSize + kRightPadding);
return minimum_size; return minimum_size;
...@@ -199,15 +193,6 @@ int Tab::GetMiniWidth() { ...@@ -199,15 +193,6 @@ int Tab::GetMiniWidth() {
return browser_defaults::kMiniTabWidth; return browser_defaults::kMiniTabWidth;
} }
// static
gfx::Size Tab::GetTouchModeMinimumSize() {
InitTabResources();
gfx::Size size;
size.set_width(kTouchModeMinimumWidth);
size.set_height(tab_active_.image_l->height());
return size;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Tab, protected: // Tab, protected:
......
...@@ -54,9 +54,6 @@ class Tab : public BaseTab { ...@@ -54,9 +54,6 @@ class Tab : public BaseTab {
// Returns the width for mini-tabs. Mini-tabs always have this width. // Returns the width for mini-tabs. Mini-tabs always have this width.
static int GetMiniWidth(); static int GetMiniWidth();
// Returns the smallest tabs can get when in touch mode.
static gfx::Size GetTouchModeMinimumSize();
protected: protected:
// BaseTab overrides: // BaseTab overrides:
virtual const gfx::Rect& GetTitleBounds() const OVERRIDE; virtual const gfx::Rect& GetTitleBounds() const OVERRIDE;
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -21,6 +21,9 @@ class TabController { ...@@ -21,6 +21,9 @@ class TabController {
public: public:
virtual const TabStripSelectionModel& GetSelectionModel() = 0; virtual const TabStripSelectionModel& GetSelectionModel() = 0;
// Returns true if multiple selection is supported.
virtual bool SupportsMultipleSelection() = 0;
// Selects the tab. // Selects the tab.
virtual void SelectTab(BaseTab* tab) = 0; virtual void SelectTab(BaseTab* tab) = 0;
......
This diff is collapsed.
...@@ -28,6 +28,7 @@ class Tab; ...@@ -28,6 +28,7 @@ class Tab;
class TabDragController; class TabDragController;
class TabStripController; class TabStripController;
class TabStripSelectionModel; class TabStripSelectionModel;
class TouchTabStripLayout;
namespace views { namespace views {
class ImageView; class ImageView;
...@@ -70,10 +71,12 @@ class TabStrip : public AbstractTabStripView, ...@@ -70,10 +71,12 @@ class TabStrip : public AbstractTabStripView,
void StopAllHighlighting(); void StopAllHighlighting();
// Adds a tab at the specified index. // Adds a tab at the specified index.
void AddTabAt(int model_index, const TabRendererData& data); void AddTabAt(int model_index, const TabRendererData& data, bool is_active);
// Moves a tab. // Moves a tab.
void MoveTab(int from_model_index, int to_model_index); void MoveTab(int from_model_index,
int to_model_index,
const TabRendererData& data);
// Removes a tab at the specified index. // Removes a tab at the specified index.
void RemoveTabAt(int model_index); void RemoveTabAt(int model_index);
...@@ -128,11 +131,9 @@ class TabStrip : public AbstractTabStripView, ...@@ -128,11 +131,9 @@ class TabStrip : public AbstractTabStripView,
// Returns true if a tab is being dragged into this tab strip. // Returns true if a tab is being dragged into this tab strip.
bool IsActiveDropTarget() const; bool IsActiveDropTarget() const;
// Returns true if this tab strip is in stacking mode.
bool IsStacking() const;
// TabController overrides: // TabController overrides:
virtual const TabStripSelectionModel& GetSelectionModel() OVERRIDE; virtual const TabStripSelectionModel& GetSelectionModel() OVERRIDE;
virtual bool SupportsMultipleSelection() OVERRIDE;
virtual void SelectTab(BaseTab* tab) OVERRIDE; virtual void SelectTab(BaseTab* tab) OVERRIDE;
virtual void ExtendSelectionTo(BaseTab* tab) OVERRIDE; virtual void ExtendSelectionTo(BaseTab* tab) OVERRIDE;
virtual void ToggleSelected(BaseTab* tab) OVERRIDE; virtual void ToggleSelected(BaseTab* tab) OVERRIDE;
...@@ -196,9 +197,6 @@ class TabStrip : public AbstractTabStripView, ...@@ -196,9 +197,6 @@ class TabStrip : public AbstractTabStripView,
const views::Event& event) OVERRIDE; const views::Event& event) OVERRIDE;
// View overrides. // View overrides.
virtual void ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) OVERRIDE;
virtual const views::View* GetViewByID(int id) const OVERRIDE; virtual const views::View* GetViewByID(int id) const OVERRIDE;
virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE; virtual bool OnMouseDragged(const views::MouseEvent& event) OVERRIDE;
virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE; virtual void OnMouseReleased(const views::MouseEvent& event) OVERRIDE;
...@@ -241,9 +239,6 @@ class TabStrip : public AbstractTabStripView, ...@@ -241,9 +239,6 @@ class TabStrip : public AbstractTabStripView,
void Init(); void Init();
// Creates the new tab button.
void InitTabStripButtons();
// Creates and returns a new tab. The caller owners the returned tab. // Creates and returns a new tab. The caller owners the returned tab.
BaseTab* CreateTab(); BaseTab* CreateTab();
...@@ -257,6 +252,10 @@ class TabStrip : public AbstractTabStripView, ...@@ -257,6 +252,10 @@ class TabStrip : public AbstractTabStripView,
// Starts the remove tab animation. // Starts the remove tab animation.
void StartRemoveTabAnimation(int model_index); void StartRemoveTabAnimation(int model_index);
// Schedules the animations and bounds changes necessary for a remove tab
// animation.
void ScheduleRemoveTabAnimation(BaseTab* tab);
// Stops any ongoing animations. If |layout| is true and an animation is // Stops any ongoing animations. If |layout| is true and an animation is
// ongoing this does a layout. // ongoing this does a layout.
void StopAnimating(bool layout); void StopAnimating(bool layout);
...@@ -280,11 +279,6 @@ class TabStrip : public AbstractTabStripView, ...@@ -280,11 +279,6 @@ class TabStrip : public AbstractTabStripView,
const gfx::Point& location, const gfx::Point& location,
bool initial_drag); bool initial_drag);
// Invoked during drag to layout all tabs when in stacking mode, with
// |active_tab| positioned at |location|.
void LayoutDraggedTabsAtWithStacking(BaseTab* active_tab,
const gfx::Point& location);
// Calculates the bounds needed for each of the tabs, placing the result in // Calculates the bounds needed for each of the tabs, placing the result in
// |bounds|. // |bounds|.
void CalculateBoundsForDraggedTabs( void CalculateBoundsForDraggedTabs(
...@@ -333,19 +327,6 @@ class TabStrip : public AbstractTabStripView, ...@@ -333,19 +327,6 @@ class TabStrip : public AbstractTabStripView,
// Releases ownership of the current TabDragController. // Releases ownership of the current TabDragController.
TabDragController* ReleaseDragController(); TabDragController* ReleaseDragController();
// Returns the number of non-closing tabs between |index1| and |index2|.
int NumNonClosingTabs(int index1, int index2) const;
// Updates |num_visible_tabs_| based on |width| and the specified tab size.
// Additionally updates |first_visible_tab_index_|.
void UpdateNumVisibleTabs(int non_closing_tab_count,
int width,
double tab_size);
// Makes sure |model_index| is within the set of visible tabs. Only does
// something if stacking.
void EnsureModelIndexIsVisible(int model_index);
// Paints all the tabs in |tabs_closing_map_[index]|. // Paints all the tabs in |tabs_closing_map_[index]|.
void PaintClosingTabs(gfx::Canvas* canvas, int index); void PaintClosingTabs(gfx::Canvas* canvas, int index);
...@@ -411,13 +392,13 @@ class TabStrip : public AbstractTabStripView, ...@@ -411,13 +392,13 @@ class TabStrip : public AbstractTabStripView,
// button. // button.
void GenerateIdealBounds(); void GenerateIdealBounds();
// Same as GenerateIdealBounds, except used with in stacking mode. Only // Generates the ideal bounds for the mini tabs. Returns the index to position
// intended to be called by GenerateIdealBounds. Returns location for // the first non-mini tab and sets |first_non_mini_index| to the index of the
// new tab button. // first non-mini tab.
double GenerateIdealBoundsWithStacking(int mini_tab_count, int GenerateIdealBoundsForMiniTabs(int* first_non_mini_index);
int non_closing_tab_count,
double new_tab_x, // Returns the width needed for the new tab button (and padding).
double selected_size); int new_tab_button_width() const;
// Starts various types of TabStrip animations. // Starts various types of TabStrip animations.
void StartResizeLayoutAnimation(); void StartResizeLayoutAnimation();
...@@ -428,6 +409,15 @@ class TabStrip : public AbstractTabStripView, ...@@ -428,6 +409,15 @@ class TabStrip : public AbstractTabStripView,
// hit-test region of the specified Tab. // hit-test region of the specified Tab.
bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords); bool IsPointInTab(Tab* tab, const gfx::Point& point_in_tabstrip_coords);
// -- Touch Layout ----------------------------------------------------------
// Returns the position normal tabs start at.
int GetStartXForNormalTabs() const;
// Returns the tab to use for event handling starting at index |start| and
// iterating by |delta|.
Tab* FindTabForEvent(const gfx::Point& point, int start, int delta);
// -- Member Variables ------------------------------------------------------ // -- Member Variables ------------------------------------------------------
// There is a one-to-one mapping between each of the tabs in the // There is a one-to-one mapping between each of the tabs in the
...@@ -505,16 +495,8 @@ class TabStrip : public AbstractTabStripView, ...@@ -505,16 +495,8 @@ class TabStrip : public AbstractTabStripView,
// Size we last layed out at. // Size we last layed out at.
gfx::Size last_layout_size_; gfx::Size last_layout_size_;
// If |stacking_| is true this is the index (into tab_data_) of the first // Only used while in touch mode.
// tab completely shown. scoped_ptr<TouchTabStripLayout> touch_layout_;
int first_visible_tab_index_;
// If |stacking_| is true this is the number of tabs totally visible, the
// rest are compresses on the left/right edge.
int num_visible_tabs_;
// Are we in stacking/scrolling mode?
bool stacking_;
DISALLOW_COPY_AND_ASSIGN(TabStrip); DISALLOW_COPY_AND_ASSIGN(TabStrip);
}; };
......
// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -34,6 +34,9 @@ class TabStripController { ...@@ -34,6 +34,9 @@ class TabStripController {
// one whose content is shown. // one whose content is shown.
virtual bool IsActiveTab(int index) const = 0; virtual bool IsActiveTab(int index) const = 0;
// Returns the index of the active tab.
virtual int GetActiveIndex() const = 0;
// Returns true if the selected index is selected. // Returns true if the selected index is selected.
virtual bool IsTabSelected(int index) const = 0; virtual bool IsTabSelected(int index) const = 0;
......
...@@ -50,7 +50,7 @@ TEST_F(TabStripTest, CreateTabForDragging) { ...@@ -50,7 +50,7 @@ TEST_F(TabStripTest, CreateTabForDragging) {
} }
TEST_F(TabStripTest, AddTabAt) { TEST_F(TabStripTest, AddTabAt) {
tab_strip_->AddTabAt(0, TabRendererData()); tab_strip_->AddTabAt(0, TabRendererData(), false);
ASSERT_EQ(1, tab_strip_->tab_count()); ASSERT_EQ(1, tab_strip_->tab_count());
Tab* tab = tab_strip_->tab_at(0); Tab* tab = tab_strip_->tab_at(0);
EXPECT_FALSE(tab == NULL); EXPECT_FALSE(tab == NULL);
......
This diff is collapsed.
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_TABS_TOUCH_TAB_STRIP_LAYOUT_H_
#define CHROME_BROWSER_UI_VIEWS_TABS_TOUCH_TAB_STRIP_LAYOUT_H_
#pragma once
#include "base/basictypes.h"
#include "ui/gfx/size.h"
#include "ui/views/view_model.h"
namespace views {
class ViewModel;
}
// TouchTabStripLayout is used by TabStrip in touch mode. TouchTabStripLayout is
// responsible for managing the bounds of the tabs. TouchTabStripLayout differs
// from the normal layout in that it stacks tabs. Stacked tabs are tabs placed
// nearly on top of each other, and if enough consecutive stacked tabs exist
// they are placed on top of each other. Normally stacked tabs are placed after
// mini-tabs, or at the end of the tabstrip, but during dragging tabs may be
// stacked before or after the active tab.
class TouchTabStripLayout {
public:
static const int kAddTypeMini = 1 << 0;
static const int kAddTypeActive = 1 << 1;
// |size| is the size for tabs, |padding| the padding between consecutive
// tabs, |stacked_padding| the padding between stacked tabs,
// |max_stacked_count| the maximum number of consecutive tabs that can be
// stacked before they are placed on top of each other, |view_model| is the
// ViewModel the bounds of the tabs are placed in.
TouchTabStripLayout(const gfx::Size& size,
int padding,
int stacked_padding,
int max_stacked_count,
views::ViewModel* view_model);
~TouchTabStripLayout();
// Sets the x-coordinate the normal tabs start at as well as the mini-tab
// count. This is only useful if the mini-tab count or x-coordinate change.
void SetXAndMiniCount(int x, int mini_tab_count);
// Sets the width available for sizing the tabs to.
void SetWidth(int width);
int width() const { return width_; }
// Sets the index of the active tab.
void SetActiveIndex(int index);
// Drags the active tab.
void DragActiveTab(int delta);
// Adds a new tab at the specified index. |add_types| is a bitmask of
// kAddType*. |start_x| is the new x-coordinate non-mini tabs start at.
void AddTab(int index, int add_types, int start_x);
// Removes the tab at the specified index. |start_x| is the new x-coordinate
// normal tabs start at, and |old_x| the old x-coordinate of the tab. It is
// expected that the ViewModel hash been updated at the time this is invoked.
void RemoveTab(int index, int start_x, int old_x);
// Moves the tab from |from| to |to|. |new_active_index| is the index of the
// currently active tab.
void MoveTab(int from,
int to,
int new_active_index,
int start_x,
int mini_tab_count);
// Returns the active index as used by this class. The active index dictates
// stacking and what tabs are visible. As mini-tabs are never stacked,
// TouchTabStripLayout forces the active index to be in the normal tabs.
int active_index() const {
return active_index_ < mini_tab_count_ ? mini_tab_count_ : active_index_;
}
private:
friend class TouchTabStripLayoutTest;
// Sets the x-coordinate normal tabs start at, width mini-tab count and
// active index at once.
void Reset(int x, int width, int mini_tab_count, int active_index);
// Resets to an ideal layout state.
void ResetToIdealState();
// Returns the x-coordinate for the active tab constrained by the current tab
// counts.
int ConstrainActiveX(int x) const;
// Reset the bounds of the active tab (based on ConstrainActiveX()) and resets
// the bounds of the remaining tabs by way of LayoutUsingCurrent*.
void SetActiveBoundsAndLayoutFromActiveTab();
// Sets the bounds of the tabs after |index| relative to the position of the
// tab at |index|. Each tab is placed |tab_offset()| pixels after the previous
// tab, stacking as necessary.
void LayoutByTabOffsetAfter(int index);
// Same as LayoutByTabOffsetAfter(), but iterates toward
// |mini_tab_count_|.
void LayoutByTabOffsetBefore(int index);
// Similar to LayoutByTabOffsetAfter(), but uses the current x-coordinate
// if possible.
void LayoutUsingCurrentAfter(int index);
void LayoutUsingCurrentBefore(int index);
// Used when the tabs are stacked at one side. The remaining tabs are stacked
// against the |active_index()|. |delta| is the amount of space to resize the
// the tabs by.
void ExpandTabsBefore(int index, int delta);
void ExpandTabsAfter(int index, int delta);
// Adjusts the stacked tabs so that if there are more than
// |max_stacked_count_| tabs, the set > max_stacked_count_ have an
// x-coordinate of |x_|. Similarly those at the end have the same x-coordinate
// and are pushed all the way to the right.
void AdjustStackedTabs();
void AdjustLeadingStackedTabs();
void AdjustTrailingStackedTabs();
// Sets the bounds of the tab at |index|.
void SetIdealBoundsAt(int index, int x);
// Returns the min x-coordinate for the sepcified index. This is calculated
// assuming all the tabs before |index| are stacked.
int GetMinX(int index) const;
// Returns the max x-coordinage for the speficifed index. This is calculated
// assuming all the tabs after |index| are stacked.
int GetMaxX(int index) const;
// Returns the max x-coordinate for the tab at |index|. This is relative
// to the |active_index()| and is only useful when the active tab is pushed
// against the right side.
int GetMaxXCompressed(int index) const;
// Returns the min x-coordinate for the tab at |index|. This is relative
// to the |active_index()| and is only useful when the active tab is pushed
// against the left side.
int GetMinXCompressed(int index) const;
// Width needed to display |count| tabs.
int width_for_count(int count) const {
return count == 0 ? 0 :
(count * size_.width()) + (std::max(count - 1, 0) * padding_);
}
// Padding needed for |count| stacked tabs.
int stacked_padding_for_count(int count) const {
return std::min(count, max_stacked_count_) * stacked_padding_;
}
// Max stacked padding.
int max_stacked_width() const {
return stacked_padding_ * max_stacked_count_;
}
int ideal_x(int index) const { return view_model_->ideal_bounds(index).x(); }
// Returns true if some of the tabs need to be stacked.
bool requires_stacking() const {
return tab_count() != mini_tab_count_ &&
x_ + width_for_count(tab_count() - mini_tab_count_) > width_;
}
// Number of tabs.
int tab_count() const { return view_model_->view_size(); }
// Number of normal (non-mini) tabs.
int normal_tab_count() const { return tab_count() - mini_tab_count_; }
// Distance between one tab to the next.
int tab_offset() const { return size_.width() + padding_; }
#if !defined(NDEBUG)
std::string BoundsString() const;
#endif
// Size of tabs.
const gfx::Size size_;
// Padding between tabs.
const int padding_;
// Padding between stacked tabs.
const int stacked_padding_;
// Max number of stacked tabs.
const int max_stacked_count_;
// Where bounds are placed. This is owned by TabStrip.
views::ViewModel* view_model_;
// x-coordinate normal tabs start at.
int x_;
// Available width.
int width_;
// Number of mini-tabs.
int mini_tab_count_;
// Index of the active tab.
int active_index_;
DISALLOW_COPY_AND_ASSIGN(TouchTabStripLayout);
};
#endif // CHROME_BROWSER_UI_VIEWS_TABS_TOUCH_TAB_STRIP_LAYOUT_H_
...@@ -3532,6 +3532,8 @@ ...@@ -3532,6 +3532,8 @@
'browser/ui/views/tabs/tab_strip_controller.h', 'browser/ui/views/tabs/tab_strip_controller.h',
'browser/ui/views/tabs/tab_strip_factory.cc', 'browser/ui/views/tabs/tab_strip_factory.cc',
'browser/ui/views/tabs/tab_strip_factory.h', 'browser/ui/views/tabs/tab_strip_factory.h',
'browser/ui/views/tabs/touch_tab_strip_layout.cc',
'browser/ui/views/tabs/touch_tab_strip_layout.h',
'browser/ui/views/task_manager_view.cc', 'browser/ui/views/task_manager_view.cc',
'browser/ui/views/theme_background.cc', 'browser/ui/views/theme_background.cc',
'browser/ui/views/theme_background.h', 'browser/ui/views/theme_background.h',
...@@ -4983,9 +4985,11 @@ ...@@ -4983,9 +4985,11 @@
['include', '^browser/ui/views/tabs/tab_renderer_data.cc'], ['include', '^browser/ui/views/tabs/tab_renderer_data.cc'],
['include', '^browser/ui/views/tabs/tab_renderer_data.h'], ['include', '^browser/ui/views/tabs/tab_renderer_data.h'],
['include', '^browser/ui/views/tabs/tab_strip.cc'], ['include', '^browser/ui/views/tabs/tab_strip.cc'],
['include', '^browser/ui/views/tabs/tab_strip.h'],
['include', '^browser/ui/views/tabs/tab_strip_factory.cc'], ['include', '^browser/ui/views/tabs/tab_strip_factory.cc'],
['include', '^browser/ui/views/tabs/tab_strip_factory.h'], ['include', '^browser/ui/views/tabs/tab_strip_factory.h'],
['include', '^browser/ui/views/tabs/tab_strip.h'], ['include', '^browser/ui/views/tabs/touch_tab_strip_layout.cc'],
['include', '^browser/ui/views/tabs/touch_tab_strip_layout.h'],
['include', '^browser/ui/views/theme_background.cc'], ['include', '^browser/ui/views/theme_background.cc'],
['include', '^browser/ui/views/theme_background.h'], ['include', '^browser/ui/views/theme_background.h'],
['include', '^browser/ui/views/toolbar_view.cc'], ['include', '^browser/ui/views/toolbar_view.cc'],
......
...@@ -1907,6 +1907,7 @@ ...@@ -1907,6 +1907,7 @@
'browser/ui/views/tabs/fake_base_tab_strip_controller.cc', 'browser/ui/views/tabs/fake_base_tab_strip_controller.cc',
'browser/ui/views/tabs/fake_base_tab_strip_controller.h', 'browser/ui/views/tabs/fake_base_tab_strip_controller.h',
'browser/ui/views/tabs/tab_strip_unittest.cc', 'browser/ui/views/tabs/tab_strip_unittest.cc',
'browser/ui/views/tabs/touch_tab_strip_layout_unittest.cc',
'browser/ui/webui/chrome_web_ui_data_source_unittest.cc', 'browser/ui/webui/chrome_web_ui_data_source_unittest.cc',
'browser/ui/webui/fileicon_source_unittest.cc', 'browser/ui/webui/fileicon_source_unittest.cc',
'browser/ui/webui/html_dialog_tab_contents_delegate_unittest.cc', 'browser/ui/webui/html_dialog_tab_contents_delegate_unittest.cc',
......
...@@ -17,6 +17,8 @@ ViewModel::~ViewModel() { ...@@ -17,6 +17,8 @@ ViewModel::~ViewModel() {
} }
void ViewModel::Add(View* view, int index) { void ViewModel::Add(View* view, int index) {
DCHECK_LE(index, static_cast<int>(entries_.size()));
DCHECK_GE(index, 0);
Entry entry; Entry entry;
entry.view = view; entry.view = view;
entries_.insert(entries_.begin() + index, entry); entries_.insert(entries_.begin() + index, entry);
...@@ -26,6 +28,7 @@ void ViewModel::Remove(int index) { ...@@ -26,6 +28,7 @@ void ViewModel::Remove(int index) {
if (index == -1) if (index == -1)
return; return;
check_index(index);
entries_.erase(entries_.begin() + index); entries_.erase(entries_.begin() + index);
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <vector> #include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/logging.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/views/views_export.h" #include "ui/views/views_export.h"
...@@ -46,14 +47,17 @@ class VIEWS_EXPORT ViewModel { ...@@ -46,14 +47,17 @@ class VIEWS_EXPORT ViewModel {
// Returns the view at the specified index. // Returns the view at the specified index.
View* view_at(int index) const { View* view_at(int index) const {
check_index(index);
return entries_[index].view; return entries_[index].view;
} }
void set_ideal_bounds(int index, const gfx::Rect& bounds) { void set_ideal_bounds(int index, const gfx::Rect& bounds) {
check_index(index);
entries_[index].ideal_bounds = bounds; entries_[index].ideal_bounds = bounds;
} }
const gfx::Rect& ideal_bounds(int index) const { const gfx::Rect& ideal_bounds(int index) const {
check_index(index);
return entries_[index].ideal_bounds; return entries_[index].ideal_bounds;
} }
...@@ -70,6 +74,15 @@ class VIEWS_EXPORT ViewModel { ...@@ -70,6 +74,15 @@ class VIEWS_EXPORT ViewModel {
}; };
typedef std::vector<Entry> Entries; typedef std::vector<Entry> Entries;
#if !defined(NDEBUG)
void check_index(int index) const {
DCHECK_LT(index, static_cast<int>(entries_.size()));
DCHECK_GE(index, 0);
}
#else
void check_index(int index) const {}
#endif
Entries entries_; Entries entries_;
DISALLOW_COPY_AND_ASSIGN(ViewModel); DISALLOW_COPY_AND_ASSIGN(ViewModel);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment