OLD | NEW |
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/auto_reset.h" | 10 #include "base/auto_reset.h" |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 /////////////////////////////////////////////////////////////////////////////// | 370 /////////////////////////////////////////////////////////////////////////////// |
371 // TabDragController, public: | 371 // TabDragController, public: |
372 | 372 |
373 // static | 373 // static |
374 const int TabDragController::kTouchVerticalDetachMagnetism = 50; | 374 const int TabDragController::kTouchVerticalDetachMagnetism = 50; |
375 | 375 |
376 // static | 376 // static |
377 const int TabDragController::kVerticalDetachMagnetism = 15; | 377 const int TabDragController::kVerticalDetachMagnetism = 15; |
378 | 378 |
379 TabDragController::TabDragController() | 379 TabDragController::TabDragController() |
380 : detach_into_browser_(ShouldDetachIntoNewBrowser()), | 380 : detach_into_browser_(true), |
381 event_source_(EVENT_SOURCE_MOUSE), | 381 event_source_(EVENT_SOURCE_MOUSE), |
382 source_tabstrip_(NULL), | 382 source_tabstrip_(NULL), |
383 attached_tabstrip_(NULL), | 383 attached_tabstrip_(NULL), |
384 screen_(NULL), | 384 screen_(NULL), |
385 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), | 385 host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE), |
386 offset_to_width_ratio_(0), | 386 offset_to_width_ratio_(0), |
387 old_focused_view_id_( | 387 old_focused_view_id_( |
388 views::ViewStorage::GetInstance()->CreateStorageID()), | 388 views::ViewStorage::GetInstance()->CreateStorageID()), |
389 last_move_screen_loc_(0), | 389 last_move_screen_loc_(0), |
390 started_drag_(false), | 390 started_drag_(false), |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 bool TabDragController::IsAttachedTo(const TabStrip* tab_strip) { | 493 bool TabDragController::IsAttachedTo(const TabStrip* tab_strip) { |
494 return (instance_ && instance_->active() && | 494 return (instance_ && instance_->active() && |
495 instance_->attached_tabstrip() == tab_strip); | 495 instance_->attached_tabstrip() == tab_strip); |
496 } | 496 } |
497 | 497 |
498 // static | 498 // static |
499 bool TabDragController::IsActive() { | 499 bool TabDragController::IsActive() { |
500 return instance_ && instance_->active(); | 500 return instance_ && instance_->active(); |
501 } | 501 } |
502 | 502 |
503 // static | |
504 bool TabDragController::ShouldDetachIntoNewBrowser() { | |
505 #if defined(USE_AURA) | |
506 return true; | |
507 #else | |
508 return CommandLine::ForCurrentProcess()->HasSwitch( | |
509 switches::kTabBrowserDragging); | |
510 #endif | |
511 } | |
512 | |
513 void TabDragController::SetMoveBehavior(MoveBehavior behavior) { | 503 void TabDragController::SetMoveBehavior(MoveBehavior behavior) { |
514 if (started_drag()) | 504 if (started_drag()) |
515 return; | 505 return; |
516 | 506 |
517 move_behavior_ = behavior; | 507 move_behavior_ = behavior; |
518 } | 508 } |
519 | 509 |
520 void TabDragController::Drag(const gfx::Point& point_in_screen) { | 510 void TabDragController::Drag(const gfx::Point& point_in_screen) { |
521 TRACE_EVENT1("views", "TabDragController::Drag", | 511 TRACE_EVENT1("views", "TabDragController::Drag", |
522 "point_in_screen", point_in_screen.ToString()); | 512 "point_in_screen", point_in_screen.ToString()); |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1436 selection_model.Copy(initial_selection_model_); | 1426 selection_model.Copy(initial_selection_model_); |
1437 for (DragData::const_reverse_iterator i(drag_data_.rbegin()); | 1427 for (DragData::const_reverse_iterator i(drag_data_.rbegin()); |
1438 i != drag_data_.rend(); ++i) { | 1428 i != drag_data_.rend(); ++i) { |
1439 selection_model.DecrementFrom(i->source_model_index); | 1429 selection_model.DecrementFrom(i->source_model_index); |
1440 } | 1430 } |
1441 // We may have cleared out the selection model. Only reset it if it | 1431 // We may have cleared out the selection model. Only reset it if it |
1442 // contains something. | 1432 // contains something. |
1443 if (!selection_model.empty()) | 1433 if (!selection_model.empty()) |
1444 attached_model->SetSelectionFromModel(selection_model); | 1434 attached_model->SetSelectionFromModel(selection_model); |
1445 } | 1435 } |
1446 } else if (!detach_into_browser_) { | |
1447 HideFrame(); | |
1448 } | 1436 } |
1449 | 1437 |
1450 // Create the dragged view. | 1438 // Create the dragged view. |
1451 if (!detach_into_browser_) | 1439 if (!detach_into_browser_) |
1452 CreateDraggedView(tab_data, drag_bounds); | 1440 CreateDraggedView(tab_data, drag_bounds); |
1453 | 1441 |
1454 attached_tabstrip_->DraggedTabsDetached(); | 1442 attached_tabstrip_->DraggedTabsDetached(); |
1455 attached_tabstrip_ = NULL; | 1443 attached_tabstrip_ = NULL; |
1456 } | 1444 } |
1457 | 1445 |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2068 | 2056 |
2069 gfx::Rect TabDragController::GetViewScreenBounds( | 2057 gfx::Rect TabDragController::GetViewScreenBounds( |
2070 views::View* view) const { | 2058 views::View* view) const { |
2071 gfx::Point view_topleft; | 2059 gfx::Point view_topleft; |
2072 views::View::ConvertPointToScreen(view, &view_topleft); | 2060 views::View::ConvertPointToScreen(view, &view_topleft); |
2073 gfx::Rect view_screen_bounds = view->GetLocalBounds(); | 2061 gfx::Rect view_screen_bounds = view->GetLocalBounds(); |
2074 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); | 2062 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); |
2075 return view_screen_bounds; | 2063 return view_screen_bounds; |
2076 } | 2064 } |
2077 | 2065 |
2078 void TabDragController::HideFrame() { | |
2079 #if defined(OS_WIN) && !defined(USE_AURA) | |
2080 // We don't actually hide the window, rather we just move it way off-screen. | |
2081 // If we actually hide it, we stop receiving drag events. | |
2082 // | |
2083 // Windows coordinates are 16 bit values. Additionally mouse events are | |
2084 // relative, this means if we move this window to the max position it is easy | |
2085 // to trigger overflow. To avoid this we don't move to the max position, | |
2086 // rather some where reasonably large. This should avoid common overflow | |
2087 // problems. | |
2088 // An alternative approach is to query the mouse pointer and ignore the | |
2089 // location on the mouse (early versions did this). This proves problematic as | |
2090 // if we happen to get behind in event processing it is all to easy to process | |
2091 // a release in the wrong location, triggering either an unexpected move or an | |
2092 // unexpected detach. | |
2093 HWND frame_hwnd = source_tabstrip_->GetWidget()->GetNativeView(); | |
2094 RECT wr; | |
2095 GetWindowRect(frame_hwnd, &wr); | |
2096 MoveWindow(frame_hwnd, 0x3FFF, 0x3FFF, wr.right - wr.left, | |
2097 wr.bottom - wr.top, TRUE); | |
2098 | |
2099 // We also save the bounds of the window prior to it being moved, so that if | |
2100 // the drag session is aborted we can restore them. | |
2101 restore_bounds_ = gfx::Rect(wr); | |
2102 #else | |
2103 // Shouldn't hit as aura triggers the |detach_into_browser_| path. | |
2104 NOTREACHED(); | |
2105 #endif | |
2106 } | |
2107 | |
2108 void TabDragController::CleanUpHiddenFrame() { | 2066 void TabDragController::CleanUpHiddenFrame() { |
2109 // If the model we started dragging from is now empty, we must ask the | 2067 // If the model we started dragging from is now empty, we must ask the |
2110 // delegate to close the frame. | 2068 // delegate to close the frame. |
2111 if (!detach_into_browser_ && GetModel(source_tabstrip_)->empty()) | 2069 if (!detach_into_browser_ && GetModel(source_tabstrip_)->empty()) |
2112 GetModel(source_tabstrip_)->delegate()->CloseFrameAfterDragSession(); | 2070 GetModel(source_tabstrip_)->delegate()->CloseFrameAfterDragSession(); |
2113 } | 2071 } |
2114 | 2072 |
2115 void TabDragController::DockDisplayerDestroyed( | 2073 void TabDragController::DockDisplayerDestroyed( |
2116 DockDisplayer* controller) { | 2074 DockDisplayer* controller) { |
2117 DockWindows::iterator dock_i = | 2075 DockWindows::iterator dock_i = |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2354 gfx::Vector2d TabDragController::GetWindowOffset( | 2312 gfx::Vector2d TabDragController::GetWindowOffset( |
2355 const gfx::Point& point_in_screen) { | 2313 const gfx::Point& point_in_screen) { |
2356 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? | 2314 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? |
2357 attached_tabstrip_ : source_tabstrip_; | 2315 attached_tabstrip_ : source_tabstrip_; |
2358 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); | 2316 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); |
2359 | 2317 |
2360 gfx::Point point = point_in_screen; | 2318 gfx::Point point = point_in_screen; |
2361 views::View::ConvertPointFromScreen(toplevel_view, &point); | 2319 views::View::ConvertPointFromScreen(toplevel_view, &point); |
2362 return point.OffsetFromOrigin(); | 2320 return point.OffsetFromOrigin(); |
2363 } | 2321 } |
OLD | NEW |