Chromium Code Reviews| 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 105 | 105 |
| 106 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 106 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 107 | 107 |
| 108 gfx::ImageSkia* high_icon = rb.GetImageSkiaNamed(IDR_DOCK_HIGH); | 108 gfx::ImageSkia* high_icon = rb.GetImageSkiaNamed(IDR_DOCK_HIGH); |
| 109 gfx::ImageSkia* wide_icon = rb.GetImageSkiaNamed(IDR_DOCK_WIDE); | 109 gfx::ImageSkia* wide_icon = rb.GetImageSkiaNamed(IDR_DOCK_WIDE); |
| 110 | 110 |
| 111 canvas->Save(); | 111 canvas->Save(); |
| 112 bool rtl_ui = base::i18n::IsRTL(); | 112 bool rtl_ui = base::i18n::IsRTL(); |
| 113 if (rtl_ui) { | 113 if (rtl_ui) { |
| 114 // Flip canvas to draw the mirrored tab images for RTL UI. | 114 // Flip canvas to draw the mirrored tab images for RTL UI. |
| 115 canvas->Translate(gfx::Point(width(), 0)); | 115 canvas->Translate(gfx::Vector2d(width(), 0)); |
| 116 canvas->Scale(-1, 1); | 116 canvas->Scale(-1, 1); |
| 117 } | 117 } |
| 118 int x_of_active_tab = width() / 2 + kTabSpacing / 2; | 118 int x_of_active_tab = width() / 2 + kTabSpacing / 2; |
| 119 int x_of_inactive_tab = width() / 2 - high_icon->width() - kTabSpacing / 2; | 119 int x_of_inactive_tab = width() / 2 - high_icon->width() - kTabSpacing / 2; |
| 120 switch (type_) { | 120 switch (type_) { |
| 121 case DockInfo::LEFT_OF_WINDOW: | 121 case DockInfo::LEFT_OF_WINDOW: |
| 122 case DockInfo::LEFT_HALF: | 122 case DockInfo::LEFT_HALF: |
| 123 if (!rtl_ui) | 123 if (!rtl_ui) |
| 124 std::swap(x_of_active_tab, x_of_inactive_tab); | 124 std::swap(x_of_active_tab, x_of_inactive_tab); |
| 125 canvas->DrawImageInt(*high_icon, x_of_active_tab, | 125 canvas->DrawImageInt(*high_icon, x_of_active_tab, |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 495 | 495 |
| 496 if (!started_drag_) { | 496 if (!started_drag_) { |
| 497 if (!CanStartDrag(real_point_in_screen)) | 497 if (!CanStartDrag(real_point_in_screen)) |
| 498 return; // User hasn't dragged far enough yet. | 498 return; // User hasn't dragged far enough yet. |
| 499 | 499 |
| 500 started_drag_ = true; | 500 started_drag_ = true; |
| 501 SaveFocus(); | 501 SaveFocus(); |
| 502 Attach(source_tabstrip_, gfx::Point()); | 502 Attach(source_tabstrip_, gfx::Point()); |
| 503 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == | 503 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == |
| 504 GetModel(source_tabstrip_)->count()) { | 504 GetModel(source_tabstrip_)->count()) { |
| 505 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen); | 505 gfx::Vector2d dragged_view_offset = GetWindowOffset(point_in_screen); |
|
Peter Kasting
2012/10/30 01:14:14
Nit: Inline
| |
| 506 RunMoveLoop(dragged_view_point); | 506 RunMoveLoop(dragged_view_offset); |
| 507 return; | 507 return; |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 | 510 |
| 511 ContinueDragging(real_point_in_screen); | 511 ContinueDragging(real_point_in_screen); |
| 512 } | 512 } |
| 513 | 513 |
| 514 void TabDragController::EndDrag(EndDragReason reason) { | 514 void TabDragController::EndDrag(EndDragReason reason) { |
| 515 // If we're dragging a window ignore capture lost since it'll ultimately | 515 // If we're dragging a window ignore capture lost since it'll ultimately |
| 516 // trigger the move loop to end and we'll revert the drag when RunMoveLoop() | 516 // trigger the move loop to end and we'll revert the drag when RunMoveLoop() |
| (...skipping 773 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1290 attached_tabstrip_ = NULL; | 1290 attached_tabstrip_ = NULL; |
| 1291 } | 1291 } |
| 1292 | 1292 |
| 1293 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop( | 1293 void TabDragController::DetachIntoNewBrowserAndRunMoveLoop( |
| 1294 const gfx::Point& point_in_screen) { | 1294 const gfx::Point& point_in_screen) { |
| 1295 if (GetModel(attached_tabstrip_)->count() == | 1295 if (GetModel(attached_tabstrip_)->count() == |
| 1296 static_cast<int>(drag_data_.size())) { | 1296 static_cast<int>(drag_data_.size())) { |
| 1297 // All the tabs in a browser are being dragged but all the tabs weren't | 1297 // All the tabs in a browser are being dragged but all the tabs weren't |
| 1298 // initially being dragged. For this to happen the user would have to | 1298 // initially being dragged. For this to happen the user would have to |
| 1299 // start dragging a set of tabs, the other tabs close, then detach. | 1299 // start dragging a set of tabs, the other tabs close, then detach. |
| 1300 gfx::Point dragged_view_point = GetWindowOffset(point_in_screen); | 1300 gfx::Vector2d dragged_view_offset = GetWindowOffset(point_in_screen); |
|
Peter Kasting
2012/10/30 01:14:14
Nit: Inline
| |
| 1301 RunMoveLoop(dragged_view_point); | 1301 RunMoveLoop(dragged_view_offset); |
| 1302 return; | 1302 return; |
| 1303 } | 1303 } |
| 1304 | 1304 |
| 1305 // Create a new browser to house the dragged tabs and have the OS run a move | 1305 // Create a new browser to house the dragged tabs and have the OS run a move |
| 1306 // loop. | 1306 // loop. |
| 1307 | 1307 |
| 1308 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen); | 1308 gfx::Point attached_point = GetAttachedDragPoint(point_in_screen); |
| 1309 | 1309 |
| 1310 // Calculate the bounds for the tabs from the attached_tab_strip. We do this | 1310 // Calculate the bounds for the tabs from the attached_tab_strip. We do this |
| 1311 // so that the tabs don't change size when detached. | 1311 // so that the tabs don't change size when detached. |
| 1312 std::vector<gfx::Rect> drag_bounds = | 1312 std::vector<gfx::Rect> drag_bounds = |
| 1313 CalculateBoundsForDraggedTabs(attached_point.x()); | 1313 CalculateBoundsForDraggedTabs(attached_point.x()); |
| 1314 | 1314 |
| 1315 gfx::Point drag_offset; | 1315 gfx::Vector2d drag_offset; |
| 1316 Browser* browser = CreateBrowserForDrag( | 1316 Browser* browser = CreateBrowserForDrag( |
| 1317 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); | 1317 attached_tabstrip_, point_in_screen, &drag_offset, &drag_bounds); |
| 1318 Detach(DONT_RELEASE_CAPTURE); | 1318 Detach(DONT_RELEASE_CAPTURE); |
| 1319 BrowserView* dragged_browser_view = | 1319 BrowserView* dragged_browser_view = |
| 1320 BrowserView::GetBrowserViewForBrowser(browser); | 1320 BrowserView::GetBrowserViewForBrowser(browser); |
| 1321 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( | 1321 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( |
| 1322 false); | 1322 false); |
| 1323 Attach(dragged_browser_view->tabstrip(), gfx::Point()); | 1323 Attach(dragged_browser_view->tabstrip(), gfx::Point()); |
| 1324 // TODO: come up with a cleaner way to do this. | 1324 // TODO: come up with a cleaner way to do this. |
| 1325 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds); | 1325 attached_tabstrip_->SetTabBoundsForDrag(drag_bounds); |
| 1326 | 1326 |
| 1327 WindowPositionManagedUpdater updater; | 1327 WindowPositionManagedUpdater updater; |
| 1328 dragged_browser_view->GetWidget()->AddObserver(&updater); | 1328 dragged_browser_view->GetWidget()->AddObserver(&updater); |
| 1329 browser->window()->Show(); | 1329 browser->window()->Show(); |
| 1330 dragged_browser_view->GetWidget()->RemoveObserver(&updater); | 1330 dragged_browser_view->GetWidget()->RemoveObserver(&updater); |
| 1331 | 1331 |
| 1332 browser->window()->Activate(); | 1332 browser->window()->Activate(); |
| 1333 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( | 1333 dragged_browser_view->GetWidget()->SetVisibilityChangedAnimationsEnabled( |
| 1334 true); | 1334 true); |
| 1335 RunMoveLoop(drag_offset); | 1335 RunMoveLoop(drag_offset); |
| 1336 } | 1336 } |
| 1337 | 1337 |
| 1338 void TabDragController::RunMoveLoop(const gfx::Point& drag_offset) { | 1338 void TabDragController::RunMoveLoop(const gfx::Vector2d& drag_offset) { |
| 1339 // If the user drags the whole window we'll assume they are going to attach to | 1339 // If the user drags the whole window we'll assume they are going to attach to |
| 1340 // another window and therefor want to reorder. | 1340 // another window and therefor want to reorder. |
| 1341 move_behavior_ = REORDER; | 1341 move_behavior_ = REORDER; |
| 1342 | 1342 |
| 1343 move_loop_widget_ = GetAttachedBrowserWidget(); | 1343 move_loop_widget_ = GetAttachedBrowserWidget(); |
| 1344 DCHECK(move_loop_widget_); | 1344 DCHECK(move_loop_widget_); |
| 1345 move_loop_widget_->AddObserver(this); | 1345 move_loop_widget_->AddObserver(this); |
| 1346 is_dragging_window_ = true; | 1346 is_dragging_window_ = true; |
| 1347 bool destroyed = false; | 1347 bool destroyed = false; |
| 1348 destroyed_ = &destroyed; | 1348 destroyed_ = &destroyed; |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1962 drag_data_[i].source_model_index) { | 1962 drag_data_[i].source_model_index) { |
| 1963 return false; | 1963 return false; |
| 1964 } | 1964 } |
| 1965 } | 1965 } |
| 1966 return true; | 1966 return true; |
| 1967 } | 1967 } |
| 1968 | 1968 |
| 1969 Browser* TabDragController::CreateBrowserForDrag( | 1969 Browser* TabDragController::CreateBrowserForDrag( |
| 1970 TabStrip* source, | 1970 TabStrip* source, |
| 1971 const gfx::Point& point_in_screen, | 1971 const gfx::Point& point_in_screen, |
| 1972 gfx::Point* drag_offset, | 1972 gfx::Vector2d* drag_offset, |
| 1973 std::vector<gfx::Rect>* drag_bounds) { | 1973 std::vector<gfx::Rect>* drag_bounds) { |
| 1974 gfx::Point center(0, source->height() / 2); | 1974 gfx::Point center(0, source->height() / 2); |
| 1975 views::View::ConvertPointToWidget(source, ¢er); | 1975 views::View::ConvertPointToWidget(source, ¢er); |
| 1976 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen()); | 1976 gfx::Rect new_bounds(source->GetWidget()->GetWindowBoundsInScreen()); |
| 1977 new_bounds.set_y(point_in_screen.y() - center.y()); | 1977 new_bounds.set_y(point_in_screen.y() - center.y()); |
| 1978 switch (GetDetachPosition(point_in_screen)) { | 1978 switch (GetDetachPosition(point_in_screen)) { |
| 1979 case DETACH_BEFORE: | 1979 case DETACH_BEFORE: |
| 1980 new_bounds.set_x(point_in_screen.x() - center.x()); | 1980 new_bounds.set_x(point_in_screen.x() - center.x()); |
| 1981 new_bounds.Offset(-mouse_offset_.x(), 0); | 1981 new_bounds.Offset(-mouse_offset_.x(), 0); |
| 1982 break; | 1982 break; |
| 1983 | 1983 |
| 1984 case DETACH_AFTER: { | 1984 case DETACH_AFTER: { |
| 1985 gfx::Point right_edge(source->width(), 0); | 1985 gfx::Point right_edge(source->width(), 0); |
| 1986 views::View::ConvertPointToWidget(source, &right_edge); | 1986 views::View::ConvertPointToWidget(source, &right_edge); |
| 1987 new_bounds.set_x(point_in_screen.x() - right_edge.x()); | 1987 new_bounds.set_x(point_in_screen.x() - right_edge.x()); |
| 1988 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0); | 1988 new_bounds.Offset(drag_bounds->back().right() - mouse_offset_.x(), 0); |
| 1989 int delta = (*drag_bounds)[0].x(); | 1989 int delta = (*drag_bounds)[0].x(); |
| 1990 for (size_t i = 0; i < drag_bounds->size(); ++i) | 1990 for (size_t i = 0; i < drag_bounds->size(); ++i) |
| 1991 (*drag_bounds)[i].Offset(-delta, 0); | 1991 (*drag_bounds)[i].Offset(-delta, 0); |
| 1992 break; | 1992 break; |
| 1993 } | 1993 } |
| 1994 | 1994 |
| 1995 default: | 1995 default: |
| 1996 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. | 1996 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. |
| 1997 } | 1997 } |
| 1998 | 1998 |
| 1999 *drag_offset = point_in_screen.Subtract(new_bounds.origin()); | 1999 *drag_offset = point_in_screen - new_bounds.origin(); |
| 2000 | 2000 |
| 2001 Browser::CreateParams create_params(drag_data_[0].contents->profile()); | 2001 Browser::CreateParams create_params(drag_data_[0].contents->profile()); |
| 2002 create_params.initial_bounds = new_bounds; | 2002 create_params.initial_bounds = new_bounds; |
| 2003 Browser* browser = new Browser(create_params); | 2003 Browser* browser = new Browser(create_params); |
| 2004 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false); | 2004 SetTrackedByWorkspace(browser->window()->GetNativeWindow(), false); |
| 2005 SetWindowPositionManaged(browser->window()->GetNativeWindow(), false); | 2005 SetWindowPositionManaged(browser->window()->GetNativeWindow(), false); |
| 2006 // If the window is created maximized then the bounds we supplied are ignored. | 2006 // If the window is created maximized then the bounds we supplied are ignored. |
| 2007 // We need to reset them again so they are honored. | 2007 // We need to reset them again so they are honored. |
| 2008 browser->window()->SetBounds(new_bounds); | 2008 browser->window()->SetBounds(new_bounds); |
| 2009 return browser; | 2009 return browser; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2020 bool got_touch_point = widget_window->GetRootWindow()-> | 2020 bool got_touch_point = widget_window->GetRootWindow()-> |
| 2021 gesture_recognizer()->GetLastTouchPointForTarget(widget_window, | 2021 gesture_recognizer()->GetLastTouchPointForTarget(widget_window, |
| 2022 &touch_point); | 2022 &touch_point); |
| 2023 DCHECK(got_touch_point); | 2023 DCHECK(got_touch_point); |
| 2024 return touch_point; | 2024 return touch_point; |
| 2025 } | 2025 } |
| 2026 #endif | 2026 #endif |
| 2027 return screen_->GetCursorScreenPoint(); | 2027 return screen_->GetCursorScreenPoint(); |
| 2028 } | 2028 } |
| 2029 | 2029 |
| 2030 gfx::Point TabDragController::GetWindowOffset( | 2030 gfx::Vector2d TabDragController::GetWindowOffset( |
| 2031 const gfx::Point& point_in_screen) { | 2031 const gfx::Point& point_in_screen) { |
| 2032 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? | 2032 TabStrip* owning_tabstrip = (attached_tabstrip_ && detach_into_browser_) ? |
| 2033 attached_tabstrip_ : source_tabstrip_; | 2033 attached_tabstrip_ : source_tabstrip_; |
| 2034 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); | 2034 views::View* toplevel_view = owning_tabstrip->GetWidget()->GetContentsView(); |
| 2035 | 2035 |
| 2036 gfx::Point offset = point_in_screen; | 2036 gfx::Point point = point_in_screen; |
| 2037 views::View::ConvertPointFromScreen(toplevel_view, &offset); | 2037 views::View::ConvertPointFromScreen(toplevel_view, &point); |
| 2038 return offset; | 2038 return point.OffsetFromOrigin(); |
|
Peter Kasting
2012/10/30 01:14:14
I wonder if view.h should change from having all t
danakj
2012/10/30 19:21:21
That sounds pretty reasonable, and like it would r
Peter Kasting
2012/10/30 20:24:37
Should there be a bug for this, then, or are you k
danakj
2012/10/30 21:14:52
Ya, /me makes bug.
| |
| 2039 } | 2039 } |
| OLD | NEW |