Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(388)

Side by Side Diff: chrome/browser/ui/views/tabs/tab_drag_controller.cc

Issue 10824200: Handful of tweaks for tab dragging with touch: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix windows Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h" 5 #include "chrome/browser/ui/views/tabs/tab_drag_controller.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 #include <set> 8 #include <set>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 199
200 bool ShouldDetachIntoNewBrowser() { 200 bool ShouldDetachIntoNewBrowser() {
201 #if defined(USE_AURA) 201 #if defined(USE_AURA)
202 return true; 202 return true;
203 #else 203 #else
204 return CommandLine::ForCurrentProcess()->HasSwitch( 204 return CommandLine::ForCurrentProcess()->HasSwitch(
205 switches::kTabBrowserDragging); 205 switches::kTabBrowserDragging);
206 #endif 206 #endif
207 } 207 }
208 208
209 // Returns true if |bounds| contains the y-coordinate |y|. The y-coordinate
210 // of |bounds| is adjusted by |vertical_adjustment|.
211 bool DoesRectContainVerticalPointExpanded(
212 const gfx::Rect& bounds,
213 int vertical_adjustment,
214 int y) {
215 int upper_threshold = bounds.bottom() + vertical_adjustment;
216 int lower_threshold = bounds.y() - vertical_adjustment;
217 return y >= lower_threshold && y <= upper_threshold;
218 }
219
209 } // namespace 220 } // namespace
210 221
211 /////////////////////////////////////////////////////////////////////////////// 222 ///////////////////////////////////////////////////////////////////////////////
212 // DockDisplayer 223 // DockDisplayer
213 224
214 // DockDisplayer is responsible for giving the user a visual indication of a 225 // DockDisplayer is responsible for giving the user a visual indication of a
215 // possible dock position (as represented by DockInfo). DockDisplayer shows 226 // possible dock position (as represented by DockInfo). DockDisplayer shows
216 // a window with a DockView in it. Two animations are used that correspond to 227 // a window with a DockView in it. Two animations are used that correspond to
217 // the state of DockInfo::in_enable_area. 228 // the state of DockInfo::in_enable_area.
218 class TabDragController::DockDisplayer : public ui::AnimationDelegate { 229 class TabDragController::DockDisplayer : public ui::AnimationDelegate {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 attached_tab(NULL), 331 attached_tab(NULL),
321 pinned(false) { 332 pinned(false) {
322 } 333 }
323 334
324 TabDragController::TabDragData::~TabDragData() { 335 TabDragController::TabDragData::~TabDragData() {
325 } 336 }
326 337
327 /////////////////////////////////////////////////////////////////////////////// 338 ///////////////////////////////////////////////////////////////////////////////
328 // TabDragController, public: 339 // TabDragController, public:
329 340
341 // static
342 const int TabDragController::kTouchVerticalDetachMagnetism = 50;
343
344 // static
345 const int TabDragController::kVerticalDetachMagnetism = 15;
346
330 TabDragController::TabDragController() 347 TabDragController::TabDragController()
331 : detach_into_browser_(ShouldDetachIntoNewBrowser()), 348 : detach_into_browser_(ShouldDetachIntoNewBrowser()),
332 source_tabstrip_(NULL), 349 source_tabstrip_(NULL),
333 attached_tabstrip_(NULL), 350 attached_tabstrip_(NULL),
334 source_tab_offset_(0), 351 source_tab_offset_(0),
335 offset_to_width_ratio_(0), 352 offset_to_width_ratio_(0),
336 old_focused_view_(NULL), 353 old_focused_view_(NULL),
337 last_move_screen_loc_(0), 354 last_move_screen_loc_(0),
338 started_drag_(false), 355 started_drag_(false),
339 active_(true), 356 active_(true),
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x()); 734 int x_offset = abs(point_in_screen.x() - start_point_in_screen_.x());
718 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y()); 735 int y_offset = abs(point_in_screen.y() - start_point_in_screen_.y());
719 return sqrt(pow(static_cast<float>(x_offset), 2) + 736 return sqrt(pow(static_cast<float>(x_offset), 2) +
720 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; 737 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance;
721 } 738 }
722 739
723 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) { 740 void TabDragController::ContinueDragging(const gfx::Point& point_in_screen) {
724 DCHECK(!detach_into_browser_ || attached_tabstrip_); 741 DCHECK(!detach_into_browser_ || attached_tabstrip_);
725 742
726 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? 743 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ?
727 GetTabStripForPoint(point_in_screen) : source_tabstrip_; 744 GetTargetTabStripForPoint(point_in_screen) : source_tabstrip_;
728 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_); 745 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_);
729 746
730 if (attached_tabstrip_) { 747 if (attached_tabstrip_) {
731 int move_delta = point_in_screen.x() - last_point_in_screen_.x(); 748 int move_delta = point_in_screen.x() - last_point_in_screen_.x();
732 if (move_delta > 0) 749 if (move_delta > 0)
733 mouse_move_direction_ |= kMovedMouseRight; 750 mouse_move_direction_ |= kMovedMouseRight;
734 else if (move_delta < 0) 751 else if (move_delta < 0)
735 mouse_move_direction_ |= kMovedMouseLeft; 752 mouse_move_direction_ |= kMovedMouseLeft;
736 } 753 }
737 last_point_in_screen_ = point_in_screen; 754 last_point_in_screen_ = point_in_screen;
(...skipping 15 matching lines...) Expand all
753 base::TimeDelta::FromMilliseconds(kBringToFrontDelay), 770 base::TimeDelta::FromMilliseconds(kBringToFrontDelay),
754 base::Bind(&TabDragController::BringWindowUnderPointToFront, 771 base::Bind(&TabDragController::BringWindowUnderPointToFront,
755 base::Unretained(this), point_in_screen)); 772 base::Unretained(this), point_in_screen));
756 } 773 }
757 774
758 UpdateDockInfo(point_in_screen); 775 UpdateDockInfo(point_in_screen);
759 776
760 if (!is_dragging_window_) { 777 if (!is_dragging_window_) {
761 if (attached_tabstrip_) { 778 if (attached_tabstrip_) {
762 if (move_only()) { 779 if (move_only()) {
763 DragActiveTabStacked(point_in_screen); 780 if (attached_tabstrip_->touch_layout_.get())
781 DragActiveTabStacked(point_in_screen);
764 } else { 782 } else {
765 MoveAttached(point_in_screen); 783 MoveAttached(point_in_screen);
766 if (tab_strip_changed) { 784 if (tab_strip_changed) {
767 // Move the corresponding window to the front. We do this after the 785 // Move the corresponding window to the front. We do this after the
768 // move as on windows activate triggers a synchronous paint. 786 // move as on windows activate triggers a synchronous paint.
769 attached_tabstrip_->GetWidget()->Activate(); 787 attached_tabstrip_->GetWidget()->Activate();
770 } 788 }
771 } 789 }
772 } else { 790 } else {
773 MoveDetached(point_in_screen); 791 MoveDetached(point_in_screen);
(...skipping 18 matching lines...) Expand all
792 move_loop_widget_ = NULL; 810 move_loop_widget_ = NULL;
793 #endif 811 #endif
794 views::Widget* browser_widget = GetAttachedBrowserWidget(); 812 views::Widget* browser_widget = GetAttachedBrowserWidget();
795 // Need to release the drag controller before starting the move loop as it's 813 // Need to release the drag controller before starting the move loop as it's
796 // going to trigger capture lost, which cancels drag. 814 // going to trigger capture lost, which cancels drag.
797 attached_tabstrip_->ReleaseDragController(); 815 attached_tabstrip_->ReleaseDragController();
798 target_tabstrip->OwnDragController(this); 816 target_tabstrip->OwnDragController(this);
799 // Disable animations so that we don't see a close animation on aero. 817 // Disable animations so that we don't see a close animation on aero.
800 browser_widget->SetVisibilityChangedAnimationsEnabled(false); 818 browser_widget->SetVisibilityChangedAnimationsEnabled(false);
801 // For aura we can't release capture, otherwise it'll cancel a gesture. 819 // For aura we can't release capture, otherwise it'll cancel a gesture.
802 // Insteat we have to directly change capture. 820 // Instead we have to directly change capture.
803 #if !defined(USE_ASH) 821 #if !defined(USE_ASH)
804 browser_widget->ReleaseCapture(); 822 browser_widget->ReleaseCapture();
805 #else 823 #else
806 attached_tabstrip_->ReleaseDragController(); 824 attached_tabstrip_->ReleaseDragController();
807 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_); 825 target_tabstrip->GetWidget()->SetCapture(attached_tabstrip_);
808 #endif 826 #endif
809 // EndMoveLoop is going to snap the window back to its original location. 827 // EndMoveLoop is going to snap the window back to its original location.
810 // Hide it so users don't see this. 828 // Hide it so users don't see this.
811 browser_widget->Hide(); 829 browser_widget->Hide();
812 browser_widget->EndMoveLoop(); 830 browser_widget->EndMoveLoop();
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 return dock_info_; 1015 return dock_info_;
998 } 1016 }
999 1017
1000 gfx::NativeView dragged_view = view_->GetWidget()->GetNativeView(); 1018 gfx::NativeView dragged_view = view_->GetWidget()->GetNativeView();
1001 dock_windows_.insert(dragged_view); 1019 dock_windows_.insert(dragged_view);
1002 DockInfo info = DockInfo::GetDockInfoAtPoint(point_in_screen, dock_windows_); 1020 DockInfo info = DockInfo::GetDockInfoAtPoint(point_in_screen, dock_windows_);
1003 dock_windows_.erase(dragged_view); 1021 dock_windows_.erase(dragged_view);
1004 return info; 1022 return info;
1005 } 1023 }
1006 1024
1007 TabStrip* TabDragController::GetTabStripForPoint( 1025 TabStrip* TabDragController::GetTargetTabStripForPoint(
1008 const gfx::Point& point_in_screen) { 1026 const gfx::Point& point_in_screen) {
1027 if (move_only() && attached_tabstrip_) {
1028 DCHECK_EQ(DETACHABLE, detach_behavior_);
1029 // move_only() is intended for touch, in which case we only want to detach
1030 // if the touch point moves significantly in the vertical distance.
1031 gfx::Rect tabstrip_bounds = GetViewScreenBounds(attached_tabstrip_);
1032 if (DoesRectContainVerticalPointExpanded(tabstrip_bounds,
1033 kTouchVerticalDetachMagnetism,
1034 point_in_screen.y()))
1035 return attached_tabstrip_;
1036 }
1009 gfx::NativeView dragged_view = NULL; 1037 gfx::NativeView dragged_view = NULL;
1010 if (view_.get()) 1038 if (view_.get())
1011 dragged_view = view_->GetWidget()->GetNativeView(); 1039 dragged_view = view_->GetWidget()->GetNativeView();
1012 else if (is_dragging_window_) 1040 else if (is_dragging_window_)
1013 dragged_view = attached_tabstrip_->GetWidget()->GetNativeView(); 1041 dragged_view = attached_tabstrip_->GetWidget()->GetNativeView();
1014 if (dragged_view) 1042 if (dragged_view)
1015 dock_windows_.insert(dragged_view); 1043 dock_windows_.insert(dragged_view);
1016 gfx::NativeWindow local_window = 1044 gfx::NativeWindow local_window =
1017 DockInfo::GetLocalProcessWindowAtPoint(point_in_screen, dock_windows_); 1045 DockInfo::GetLocalProcessWindowAtPoint(point_in_screen, dock_windows_);
1018 if (dragged_view) 1046 if (dragged_view)
(...skipping 20 matching lines...) Expand all
1039 attached_tabstrip_ ? attached_tabstrip_ : source_tabstrip_; 1067 attached_tabstrip_ ? attached_tabstrip_ : source_tabstrip_;
1040 DCHECK(tab_strip); 1068 DCHECK(tab_strip);
1041 1069
1042 return other_tabstrip->controller()->IsCompatibleWith(tab_strip) ? 1070 return other_tabstrip->controller()->IsCompatibleWith(tab_strip) ?
1043 other_tabstrip : NULL; 1071 other_tabstrip : NULL;
1044 } 1072 }
1045 1073
1046 bool TabDragController::DoesTabStripContain( 1074 bool TabDragController::DoesTabStripContain(
1047 TabStrip* tabstrip, 1075 TabStrip* tabstrip,
1048 const gfx::Point& point_in_screen) const { 1076 const gfx::Point& point_in_screen) const {
1049 static const int kVerticalDetachMagnetism = 15;
1050 // Make sure the specified screen point is actually within the bounds of the 1077 // Make sure the specified screen point is actually within the bounds of the
1051 // specified tabstrip... 1078 // specified tabstrip...
1052 gfx::Rect tabstrip_bounds = GetViewScreenBounds(tabstrip); 1079 gfx::Rect tabstrip_bounds = GetViewScreenBounds(tabstrip);
1053 if (point_in_screen.x() < tabstrip_bounds.right() && 1080 return point_in_screen.x() < tabstrip_bounds.right() &&
1054 point_in_screen.x() >= tabstrip_bounds.x()) { 1081 point_in_screen.x() >= tabstrip_bounds.x() &&
1055 // TODO(beng): make this be relative to the start position of the mouse 1082 DoesRectContainVerticalPointExpanded(tabstrip_bounds,
1056 // for the source TabStrip. 1083 kVerticalDetachMagnetism,
1057 int upper_threshold = tabstrip_bounds.bottom() + kVerticalDetachMagnetism; 1084 point_in_screen.y());
1058 int lower_threshold = tabstrip_bounds.y() - kVerticalDetachMagnetism;
1059 return point_in_screen.y() >= lower_threshold &&
1060 point_in_screen.y() <= upper_threshold;
1061 }
1062 return false;
1063 } 1085 }
1064 1086
1065 void TabDragController::Attach(TabStrip* attached_tabstrip, 1087 void TabDragController::Attach(TabStrip* attached_tabstrip,
1066 const gfx::Point& point_in_screen) { 1088 const gfx::Point& point_in_screen) {
1067 DCHECK(!attached_tabstrip_); // We should already have detached by the time 1089 DCHECK(!attached_tabstrip_); // We should already have detached by the time
1068 // we get here. 1090 // we get here.
1069 1091
1070 attached_tabstrip_ = attached_tabstrip; 1092 attached_tabstrip_ = attached_tabstrip;
1071 1093
1072 // And we don't need the dragged view. 1094 // And we don't need the dragged view.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 // Redirect all mouse events to the TabStrip so that the tab that originated 1176 // Redirect all mouse events to the TabStrip so that the tab that originated
1155 // the drag can safely be deleted. 1177 // the drag can safely be deleted.
1156 if (detach_into_browser_ || attached_tabstrip_ == source_tabstrip_) { 1178 if (detach_into_browser_ || attached_tabstrip_ == source_tabstrip_) {
1157 static_cast<views::internal::RootView*>( 1179 static_cast<views::internal::RootView*>(
1158 attached_tabstrip_->GetWidget()->GetRootView())->SetMouseHandler( 1180 attached_tabstrip_->GetWidget()->GetRootView())->SetMouseHandler(
1159 attached_tabstrip_); 1181 attached_tabstrip_);
1160 } 1182 }
1161 } 1183 }
1162 1184
1163 void TabDragController::Detach(ReleaseCapture release_capture) { 1185 void TabDragController::Detach(ReleaseCapture release_capture) {
1186 // When the user detaches we assume they want to reorder.
1187 move_behavior_ = REORDER;
1188
1164 // Release ownership of the drag controller and mouse capture. When we 1189 // Release ownership of the drag controller and mouse capture. When we
1165 // reattach ownership is transfered. 1190 // reattach ownership is transfered.
1166 if (detach_into_browser_) { 1191 if (detach_into_browser_) {
1167 attached_tabstrip_->ReleaseDragController(); 1192 attached_tabstrip_->ReleaseDragController();
1168 if (release_capture == RELEASE_CAPTURE) 1193 if (release_capture == RELEASE_CAPTURE)
1169 attached_tabstrip_->GetWidget()->ReleaseCapture(); 1194 attached_tabstrip_->GetWidget()->ReleaseCapture();
1170 } 1195 }
1171 1196
1172 mouse_move_direction_ = kMovedMouseLeft | kMovedMouseRight; 1197 mouse_move_direction_ = kMovedMouseLeft | kMovedMouseRight;
1173 1198
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds); 1291 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds);
1267 1292
1268 browser->window()->Show(); 1293 browser->window()->Show();
1269 browser->window()->Activate(); 1294 browser->window()->Activate();
1270 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( 1295 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled(
1271 true); 1296 true);
1272 RunMoveLoop(); 1297 RunMoveLoop();
1273 } 1298 }
1274 1299
1275 void TabDragController::RunMoveLoop() { 1300 void TabDragController::RunMoveLoop() {
1301 // If the user drags the whole window we'll assume they are going to attach to
1302 // another window and therefor want to reorder.
1303 move_behavior_ = REORDER;
1304
1276 move_loop_widget_ = GetAttachedBrowserWidget(); 1305 move_loop_widget_ = GetAttachedBrowserWidget();
1277 DCHECK(move_loop_widget_); 1306 DCHECK(move_loop_widget_);
1278 move_loop_widget_->AddObserver(this); 1307 move_loop_widget_->AddObserver(this);
1279 is_dragging_window_ = true; 1308 is_dragging_window_ = true;
1280 bool destroyed = false; 1309 bool destroyed = false;
1281 destroyed_ = &destroyed; 1310 destroyed_ = &destroyed;
1282 // Running the move loop releases mouse capture on windows, which triggers 1311 #if !defined(USE_ASH)
1312 // Running the move loop releases mouse capture on Windows, which triggers
1283 // destroying the drag loop. Release mouse capture ourself before this while 1313 // destroying the drag loop. Release mouse capture ourself before this while
1284 // the DragController isn't owned by the TabStrip. 1314 // the DragController isn't owned by the TabStrip.
1285 attached_tabstrip_->ReleaseDragController(); 1315 attached_tabstrip_->ReleaseDragController();
1286 attached_tabstrip_->GetWidget()->ReleaseCapture(); 1316 attached_tabstrip_->GetWidget()->ReleaseCapture();
1287 attached_tabstrip_->OwnDragController(this); 1317 attached_tabstrip_->OwnDragController(this);
1318 #endif
1288 views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop(); 1319 views::Widget::MoveLoopResult result = move_loop_widget_->RunMoveLoop();
1289 content::NotificationService::current()->Notify( 1320 content::NotificationService::current()->Notify(
1290 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE, 1321 chrome::NOTIFICATION_TAB_DRAG_LOOP_DONE,
1291 content::NotificationService::AllBrowserContextsAndSources(), 1322 content::NotificationService::AllBrowserContextsAndSources(),
1292 content::NotificationService::NoDetails()); 1323 content::NotificationService::NoDetails());
1293 1324
1294 if (destroyed) 1325 if (destroyed)
1295 return; 1326 return;
1296 destroyed_ = NULL; 1327 destroyed_ = NULL;
1297 // Under chromeos we immediately set the |move_loop_widget_| to NULL. 1328 // Under chromeos we immediately set the |move_loop_widget_| to NULL.
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
1926 gfx::Point touch_point; 1957 gfx::Point touch_point;
1927 bool got_touch_point = widget_window->GetRootWindow()-> 1958 bool got_touch_point = widget_window->GetRootWindow()->
1928 gesture_recognizer()->GetLastTouchPointForTarget(widget_window, 1959 gesture_recognizer()->GetLastTouchPointForTarget(widget_window,
1929 &touch_point); 1960 &touch_point);
1930 DCHECK(got_touch_point); 1961 DCHECK(got_touch_point);
1931 return touch_point; 1962 return touch_point;
1932 } 1963 }
1933 #endif 1964 #endif
1934 return gfx::Screen::GetCursorScreenPoint(); 1965 return gfx::Screen::GetCursorScreenPoint();
1935 } 1966 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698