summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-27 00:54:18 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-27 00:54:18 +0000
commite25a71ed5aa15c11c2a6fdeeae22413235b8f914 (patch)
tree0f88732ba20a720d837246606c5871a3f824a514
parentec139f4d357a8966194178f6a0f18fcf46d512b1 (diff)
downloadchromium_src-e25a71ed5aa15c11c2a6fdeeae22413235b8f914.zip
chromium_src-e25a71ed5aa15c11c2a6fdeeae22413235b8f914.tar.gz
chromium_src-e25a71ed5aa15c11c2a6fdeeae22413235b8f914.tar.bz2
Improves semantics for changing set of visible tabs on the touch tab
strip. Stills needs a bunch of work, but this is at least some what usable. BUG=123274 TEST=none R=ben@chromium.org Review URL: http://codereview.chromium.org/10231014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@134194 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/views/tabs/default_tab_drag_controller.cc60
-rw-r--r--chrome/browser/ui/views/tabs/default_tab_drag_controller.h16
-rw-r--r--chrome/browser/ui/views/tabs/tab_controller.h2
-rw-r--r--chrome/browser/ui/views/tabs/tab_drag_controller.h11
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip.cc33
-rw-r--r--chrome/browser/ui/views/tabs/tab_strip.h9
-rw-r--r--chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc2
-rw-r--r--ui/views/view_model_utils.cc10
-rw-r--r--ui/views/view_model_utils.h3
9 files changed, 109 insertions, 37 deletions
diff --git a/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc b/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc
index 9ee3bb7..02132c6 100644
--- a/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/default_tab_drag_controller.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/ui/views/tabs/native_view_photobooth.h"
#include "chrome/browser/ui/views/tabs/tab.h"
#include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "chrome/browser/ui/views/tabs/touch_tab_strip_layout.h"
#include "chrome/common/chrome_switches.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h"
@@ -320,8 +321,7 @@ DefaultTabDragController::DefaultTabDragController()
active_(true),
source_tab_index_(std::numeric_limits<size_t>::max()),
initial_move_(true),
- // TODO: remove.
- stacking_(false) {
+ move_only_(false) {
instance_ = this;
}
@@ -348,13 +348,21 @@ void DefaultTabDragController::Init(
const std::vector<BaseTab*>& tabs,
const gfx::Point& mouse_offset,
int source_tab_offset,
- const TabStripSelectionModel& initial_selection_model) {
+ const TabStripSelectionModel& initial_selection_model,
+ bool move_only) {
DCHECK(!tabs.empty());
DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end());
source_tabstrip_ = source_tabstrip;
source_tab_offset_ = source_tab_offset;
start_screen_point_ = GetCursorScreenPoint();
mouse_offset_ = mouse_offset;
+ move_only_ = move_only;
+
+ if (move_only_) {
+ last_move_screen_loc_ =
+ MajorAxisValue(start_screen_point_, attached_tabstrip_);
+ initial_tab_positions_ = source_tabstrip->GetTabXCoordinates();
+ }
drag_data_.resize(tabs.size());
for (size_t i = 0; i < tabs.size(); ++i)
@@ -645,19 +653,14 @@ void DefaultTabDragController::ContinueDragging() {
// guaranteed to be correct regardless of monitor config.
gfx::Point screen_point = GetCursorScreenPoint();
+ // TODO(sky): this file shouldn't be built on chromeos.
#if defined(OS_WIN) && !defined(USE_AURA)
- // Currently only allowed on windows (and not aura).
- // 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.
- // TODO(scottmg): Determine design for when tabs should actually detach when
- // in stacking mode.
- TabStrip* target_tabstrip = stacking_ ?
- source_tabstrip_ :
- GetTabStripForPoint(screen_point);
+ TabStrip* target_tabstrip = move_only_ ?
+ source_tabstrip_ : GetTabStripForPoint(screen_point);
#else
TabStrip* target_tabstrip = source_tabstrip_;
#endif
+
if (target_tabstrip != attached_tabstrip_) {
// Make sure we're fully detached from whatever TabStrip we're attached to
// (if any).
@@ -674,10 +677,24 @@ void DefaultTabDragController::ContinueDragging() {
UpdateDockInfo(screen_point);
- if (attached_tabstrip_)
- MoveAttached(screen_point);
- else
+ if (attached_tabstrip_) {
+ if (move_only_)
+ MoveAttachedStacked(screen_point);
+ else
+ MoveAttached(screen_point);
+ } else {
MoveDetached(screen_point);
+ }
+}
+
+void DefaultTabDragController::MoveAttachedStacked(
+ const gfx::Point& screen_point) {
+ if (attached_tabstrip_->tab_count() !=
+ static_cast<int>(initial_tab_positions_.size()))
+ return; // TODO: should cancel drag if this happens.
+
+ int delta = screen_point.x() - start_screen_point_.x();
+ attached_tabstrip_->DragActiveTab(initial_tab_positions_, delta);
}
void DefaultTabDragController::MoveAttached(const gfx::Point& screen_point) {
@@ -704,7 +721,7 @@ void DefaultTabDragController::MoveAttached(const gfx::Point& screen_point) {
// Update the model, moving the WebContents from one index to another. Do this
// only if we have moved a minimum distance since the last reorder (to prevent
// jitter) or if this the first move and the tabs are not consecutive.
- if (!stacking_ && (abs(MajorAxisValue(screen_point, attached_tabstrip_) -
+ if ((abs(MajorAxisValue(screen_point, attached_tabstrip_) -
last_move_screen_loc_) > threshold ||
(initial_move_ && !AreTabsConsecutive()))) {
TabStripModel* attached_model = GetModel(attached_tabstrip_);
@@ -1033,11 +1050,6 @@ gfx::Point DefaultTabDragController::GetAttachedDragPoint(
attached_tabstrip_->GetMirroredXInView(tab_loc.x()) - mouse_offset_.x();
int y = tab_loc.y() - mouse_offset_.y();
- // Don't limit the edge of tab strip when stacking so tabs can be pulled past
- // the edge to stack.
- if (stacking_)
- return gfx::Point(x, 0);
-
// TODO: consider caching this.
std::vector<BaseTab*> attached_tabs;
for (size_t i = 0; i < drag_data_.size(); ++i)
@@ -1447,10 +1459,12 @@ TabDragController* TabDragController::Create(
const std::vector<BaseTab*>& tabs,
const gfx::Point& mouse_offset,
int source_tab_offset,
- const TabStripSelectionModel& initial_selection_model) {
+ const TabStripSelectionModel& initial_selection_model,
+ bool move_only) {
#if defined(USE_AURA) || defined(OS_WIN)
if (ShouldCreateTabDragController2()) {
TabDragController2* controller = new TabDragController2;
+ // TODO: get TabDragController2 working with move_only.
controller->Init(source_tabstrip, source_tab, tabs, mouse_offset,
source_tab_offset, initial_selection_model);
return controller;
@@ -1458,7 +1472,7 @@ TabDragController* TabDragController::Create(
#endif
DefaultTabDragController* controller = new DefaultTabDragController;
controller->Init(source_tabstrip, source_tab, tabs, mouse_offset,
- source_tab_offset, initial_selection_model);
+ source_tab_offset, initial_selection_model, move_only);
return controller;
}
diff --git a/chrome/browser/ui/views/tabs/default_tab_drag_controller.h b/chrome/browser/ui/views/tabs/default_tab_drag_controller.h
index 33e909b..6be30e7 100644
--- a/chrome/browser/ui/views/tabs/default_tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/default_tab_drag_controller.h
@@ -48,12 +48,14 @@ class DefaultTabDragController : public TabDragController,
// for a horizontal tab strip, and the vertical distance for a vertical tab
// strip. |initial_selection_model| is the selection model before the drag
// started and is only non-empty if |source_tab| was not initially selected.
+ // TODO(sky): clean up move_only.
void Init(TabStrip* source_tabstrip,
BaseTab* source_tab,
const std::vector<BaseTab*>& tabs,
const gfx::Point& mouse_offset,
int source_tab_offset,
- const TabStripSelectionModel& initial_selection_model);
+ const TabStripSelectionModel& initial_selection_model,
+ bool move_only);
// See description above fields for details on these.
bool active() const { return active_; }
@@ -167,6 +169,10 @@ class DefaultTabDragController : public TabDragController,
// potentially updating the source and other TabStrips.
void ContinueDragging();
+ // Handles dragging for a touch tabstrip when the tabs are stacked. Doesn't
+ // actually reorder the tabs in anyway, just changes what's visible.
+ void MoveAttachedStacked(const gfx::Point& screen_point);
+
// Handles dragging tabs while the tabs are attached.
void MoveAttached(const gfx::Point& screen_point);
@@ -361,8 +367,12 @@ class DefaultTabDragController : public TabDragController,
// The selection model of |attached_tabstrip_| before the tabs were attached.
TabStripSelectionModel selection_model_before_attach_;
- // Are we operating with tabs stacking/scrolling?
- bool stacking_;
+ // Initial x-coordinates of the tabs when the drag started. Only used for
+ // touch mode.
+ std::vector<int> initial_tab_positions_;
+
+ // TODO(sky): clean up.
+ bool move_only_;
DISALLOW_COPY_AND_ASSIGN(DefaultTabDragController);
};
diff --git a/chrome/browser/ui/views/tabs/tab_controller.h b/chrome/browser/ui/views/tabs/tab_controller.h
index 0e2583f..054fd2d 100644
--- a/chrome/browser/ui/views/tabs/tab_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_controller.h
@@ -58,7 +58,7 @@ class TabController {
// Potentially starts a drag for the specified Tab.
virtual void MaybeStartDrag(
BaseTab* tab,
- const views::MouseEvent& event,
+ const views::LocatedEvent& event,
const TabStripSelectionModel& original_selection) = 0;
// Continues dragging a Tab.
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.h b/chrome/browser/ui/views/tabs/tab_drag_controller.h
index 68e9211..7d0df87 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.h
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.h
@@ -35,17 +35,18 @@ class TabDragController {
// the drag (the one the user pressed the moused down on) and is contained in
// |tabs|. |mouse_offset| is the distance of the mouse pointer from the
// origin of the first tab in |tabs| and |source_tab_offset| the offset from
- // |source_tab|. |source_tab_offset| is the horizontal distant for a
- // horizontal tab strip, and the vertical distance for a vertical tab
- // strip. |initial_selection_model| is the selection model before the drag
- // started and is only non-empty if |source_tab| was not initially selected.
+ // |source_tab| (along the horizontal axis). |initial_selection_model| is the
+ // selection model before the drag started and is only non-empty if
+ // |source_tab| was not initially selected. |move_only| is true if the drag
+ // is the result of a touch event.
static TabDragController* Create(
TabStrip* source_tabstrip,
BaseTab* source_tab,
const std::vector<BaseTab*>& tabs,
const gfx::Point& mouse_offset,
int source_tab_offset,
- const TabStripSelectionModel& initial_selection_model);
+ const TabStripSelectionModel& initial_selection_model,
+ bool move_only);
// Returns true if there is a drag underway and the drag is attached to
// |tab_strip|.
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc
index 6ded840..449fe44 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -590,8 +590,12 @@ void TabStrip::SetSelection(const TabStripSelectionModel& old_selection,
const TabStripSelectionModel& new_selection) {
if (touch_layout_.get()) {
touch_layout_->SetActiveIndex(new_selection.active());
+ // Only start an animation if we need to. Otherwise clicking on an
+ // unselected tab and dragging won't work because dragging is only allowed
+ // if not animating.
+ if (!views::ViewModelUtils::IsAtIdealBounds(tabs_))
+ AnimateToIdealBounds();
SchedulePaint();
- AnimateToIdealBounds();
} else {
// We have "tiny tabs" if the tabs are so tiny that the unselected ones are
// a different size to the selected ones.
@@ -749,7 +753,7 @@ bool TabStrip::IsTabCloseable(const BaseTab* tab) const {
void TabStrip::MaybeStartDrag(
BaseTab* tab,
- const views::MouseEvent& event,
+ const views::LocatedEvent& event,
const TabStripSelectionModel& original_selection) {
// Don't accidentally start any drag operations during animations if the
// mouse is down... during an animation tabs are being resized automatically,
@@ -791,7 +795,10 @@ void TabStrip::MaybeStartDrag(
drag_controller_.reset();
drag_controller_.reset(TabDragController::Create(
this, tab, tabs, gfx::Point(x, y), tab->GetMirroredXInView(event.x()),
- selection_model));
+ selection_model, touch_layout_.get() != NULL));
+ // TODO: Instead of touch layout need to look at event type, eg
+ // event.type() == ui::ET_TOUCH_PRESSED)), and need to plumb through long
+ // press and touch stuff.
}
void TabStrip::ContinueDrag(const views::MouseEvent& event) {
@@ -1290,6 +1297,19 @@ void TabStrip::DoLayout() {
newtab_button_->SetBoundsRect(newtab_button_bounds_);
}
+void TabStrip::DragActiveTab(const std::vector<int>& initial_positions,
+ int delta) {
+ DCHECK(touch_layout_.get());
+ DCHECK_EQ(tab_count(), static_cast<int>(initial_positions.size()));
+ for (int i = 0; i < tab_count(); ++i) {
+ gfx::Rect bounds(ideal_bounds(i));
+ bounds.set_x(initial_positions[i]);
+ set_ideal_bounds(i, bounds);
+ }
+ touch_layout_->DragActiveTab(delta);
+ DoLayout();
+}
+
void TabStrip::LayoutDraggedTabsAt(const std::vector<BaseTab*>& tabs,
BaseTab* active_tab,
const gfx::Point& location,
@@ -1917,3 +1937,10 @@ Tab* TabStrip::FindTabForEvent(const gfx::Point& point, int start, int delta) {
}
return NULL;
}
+
+std::vector<int> TabStrip::GetTabXCoordinates() {
+ std::vector<int> results;
+ for (int i = 0; i < tab_count(); ++i)
+ results.push_back(ideal_bounds(i).x());
+ return results;
+}
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index 80fab67..27e8168 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -147,7 +147,7 @@ class TabStrip : public AbstractTabStripView,
virtual bool IsTabCloseable(const BaseTab* tab) const OVERRIDE;
virtual void MaybeStartDrag(
BaseTab* tab,
- const views::MouseEvent& event,
+ const views::LocatedEvent& event,
const TabStripSelectionModel& original_selection) OVERRIDE;
virtual void ContinueDrag(const views::MouseEvent& event) OVERRIDE;
virtual bool EndDrag(bool canceled) OVERRIDE;
@@ -271,6 +271,10 @@ class TabStrip : public AbstractTabStripView,
// Invoked from Layout if the size changes or layout is really needed.
void DoLayout();
+ // Drags the active tab by |delta|. |initial_positions| is the x-coordinates
+ // of the tabs when the drag started.
+ void DragActiveTab(const std::vector<int>& initial_positions, int delta);
+
// Invoked during drag to layout the tabs being dragged in |tabs| at
// |location|. If |initial_drag| is true, this is the initial layout after the
// user moved the mouse far enough to trigger a drag.
@@ -418,6 +422,9 @@ class TabStrip : public AbstractTabStripView,
// iterating by |delta|.
Tab* FindTabForEvent(const gfx::Point& point, int start, int delta);
+ // Returns the x-coordinates of the tabs.
+ std::vector<int> GetTabXCoordinates();
+
// -- Member Variables ------------------------------------------------------
// There is a one-to-one mapping between each of the tabs in the
diff --git a/chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc b/chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc
index 3cfda68..c96c37f 100644
--- a/chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc
+++ b/chrome/browser/ui/views/tabs/touch_tab_strip_layout.cc
@@ -60,7 +60,7 @@ void TouchTabStripLayout::SetActiveIndex(int index) {
}
void TouchTabStripLayout::DragActiveTab(int delta) {
- if (delta == 0 && !requires_stacking())
+ if (delta == 0 || !requires_stacking())
return;
int initial_x = ideal_x(active_index());
// If we're at a particular edge and start dragging, reset to ideal state.
diff --git a/ui/views/view_model_utils.cc b/ui/views/view_model_utils.cc
index a49fbcd..addeee7 100644
--- a/ui/views/view_model_utils.cc
+++ b/ui/views/view_model_utils.cc
@@ -18,6 +18,16 @@ void ViewModelUtils::SetViewBoundsToIdealBounds(const ViewModel& model) {
}
// static
+bool ViewModelUtils::IsAtIdealBounds(const ViewModel& model) {
+ for (int i = 0; i < model.view_size(); ++i) {
+ View* view = model.view_at(i);
+ if (view->bounds() != model.ideal_bounds(i))
+ return false;
+ }
+ return true;
+}
+
+// static
int ViewModelUtils::DetermineMoveIndex(const ViewModel& model,
View* view,
int x) {
diff --git a/ui/views/view_model_utils.h b/ui/views/view_model_utils.h
index 5219ff8..d7f8bd3 100644
--- a/ui/views/view_model_utils.h
+++ b/ui/views/view_model_utils.h
@@ -19,6 +19,9 @@ class VIEWS_EXPORT ViewModelUtils {
// Sets the bounds of each view to its ideal bounds.
static void SetViewBoundsToIdealBounds(const ViewModel& model);
+ // Returns true if the Views in |model| are at their ideal bounds.
+ static bool IsAtIdealBounds(const ViewModel& model);
+
// Returns the index to move |view| to based on a x-coordinate of |x|.
static int DetermineMoveIndex(const ViewModel& model,
View* view,