| 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/callback.h" | 10 #include "base/callback.h" |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 const std::vector<BaseTab*>& tabs, | 382 const std::vector<BaseTab*>& tabs, |
| 383 const gfx::Point& mouse_offset, | 383 const gfx::Point& mouse_offset, |
| 384 int source_tab_offset, | 384 int source_tab_offset, |
| 385 const TabStripSelectionModel& initial_selection_model, | 385 const TabStripSelectionModel& initial_selection_model, |
| 386 DetachBehavior detach_behavior, | 386 DetachBehavior detach_behavior, |
| 387 MoveBehavior move_behavior) { | 387 MoveBehavior move_behavior) { |
| 388 DCHECK(!tabs.empty()); | 388 DCHECK(!tabs.empty()); |
| 389 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); | 389 DCHECK(std::find(tabs.begin(), tabs.end(), source_tab) != tabs.end()); |
| 390 source_tabstrip_ = source_tabstrip; | 390 source_tabstrip_ = source_tabstrip; |
| 391 source_tab_offset_ = source_tab_offset; | 391 source_tab_offset_ = source_tab_offset; |
| 392 start_screen_point_ = GetCursorScreenPoint(); | 392 // TODO: make sure this works with RTL. |
| 393 start_screen_point_ = gfx::Point(source_tab_offset, mouse_offset.y()); |
| 394 views::View::ConvertPointToScreen(source_tab, &start_screen_point_); |
| 393 mouse_offset_ = mouse_offset; | 395 mouse_offset_ = mouse_offset; |
| 394 detach_behavior_ = detach_behavior; | 396 detach_behavior_ = detach_behavior; |
| 395 move_behavior_ = move_behavior; | 397 move_behavior_ = move_behavior; |
| 396 last_screen_point_ = start_screen_point_; | 398 last_screen_point_ = start_screen_point_; |
| 397 if (move_only()) { | 399 if (move_only()) { |
| 398 last_move_screen_loc_ = start_screen_point_.x(); | 400 last_move_screen_loc_ = start_screen_point_.x(); |
| 399 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); | 401 initial_tab_positions_ = source_tabstrip->GetTabXCoordinates(); |
| 400 } | 402 } |
| 401 if (detach_into_browser_) | 403 if (detach_into_browser_) |
| 402 GetModel(source_tabstrip_)->AddObserver(this); | 404 GetModel(source_tabstrip_)->AddObserver(this); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 422 bool TabDragController::IsAttachedTo(TabStrip* tab_strip) { | 424 bool TabDragController::IsAttachedTo(TabStrip* tab_strip) { |
| 423 return (instance_ && instance_->active() && | 425 return (instance_ && instance_->active() && |
| 424 instance_->attached_tabstrip() == tab_strip); | 426 instance_->attached_tabstrip() == tab_strip); |
| 425 } | 427 } |
| 426 | 428 |
| 427 // static | 429 // static |
| 428 bool TabDragController::IsActive() { | 430 bool TabDragController::IsActive() { |
| 429 return instance_ && instance_->active(); | 431 return instance_ && instance_->active(); |
| 430 } | 432 } |
| 431 | 433 |
| 432 void TabDragController::Drag() { | 434 void TabDragController::Drag(const gfx::Point& screen_point) { |
| 433 bring_to_front_timer_.Stop(); | 435 bring_to_front_timer_.Stop(); |
| 434 move_stacked_timer_.Stop(); | 436 move_stacked_timer_.Stop(); |
| 435 | 437 |
| 436 if (waiting_for_run_loop_to_exit_) | 438 if (waiting_for_run_loop_to_exit_) |
| 437 return; | 439 return; |
| 438 | 440 |
| 439 if (!started_drag_) { | 441 if (!started_drag_) { |
| 440 if (!CanStartDrag()) | 442 if (!CanStartDrag(screen_point)) |
| 441 return; // User hasn't dragged far enough yet. | 443 return; // User hasn't dragged far enough yet. |
| 442 | 444 |
| 443 started_drag_ = true; | 445 started_drag_ = true; |
| 444 SaveFocus(); | 446 SaveFocus(); |
| 445 Attach(source_tabstrip_, gfx::Point()); | 447 Attach(source_tabstrip_, gfx::Point()); |
| 446 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == | 448 if (detach_into_browser_ && static_cast<int>(drag_data_.size()) == |
| 447 GetModel(source_tabstrip_)->count()) { | 449 GetModel(source_tabstrip_)->count()) { |
| 448 RunMoveLoop(); // Runs a nested loop, returning when done. | 450 RunMoveLoop(); // Runs a nested loop, returning when done. |
| 449 return; | 451 return; |
| 450 } | 452 } |
| 451 } | 453 } |
| 452 | 454 |
| 453 ContinueDragging(); | 455 ContinueDragging(screen_point); |
| 454 } | 456 } |
| 455 | 457 |
| 456 void TabDragController::EndDrag(bool canceled) { | 458 void TabDragController::EndDrag(bool canceled) { |
| 457 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL); | 459 EndDragImpl(canceled && source_tabstrip_ ? CANCELED : NORMAL); |
| 458 } | 460 } |
| 459 | 461 |
| 460 void TabDragController::InitTabDragData(BaseTab* tab, | 462 void TabDragController::InitTabDragData(BaseTab* tab, |
| 461 TabDragData* drag_data) { | 463 TabDragData* drag_data) { |
| 462 drag_data->source_model_index = | 464 drag_data->source_model_index = |
| 463 source_tabstrip_->GetModelIndexOfBaseTab(tab); | 465 source_tabstrip_->GetModelIndexOfBaseTab(tab); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 // to the way they were. This is the most reliable way to do this since no | 587 // to the way they were. This is the most reliable way to do this since no |
| 586 // single view or window reliably receives events throughout all the various | 588 // single view or window reliably receives events throughout all the various |
| 587 // kinds of tab dragging. | 589 // kinds of tab dragging. |
| 588 if (ui::EventTypeFromNative(event) == ui::ET_KEY_PRESSED && | 590 if (ui::EventTypeFromNative(event) == ui::ET_KEY_PRESSED && |
| 589 ui::KeyboardCodeFromNative(event) == ui::VKEY_ESCAPE) { | 591 ui::KeyboardCodeFromNative(event) == ui::VKEY_ESCAPE) { |
| 590 EndDrag(true); | 592 EndDrag(true); |
| 591 } | 593 } |
| 592 } | 594 } |
| 593 | 595 |
| 594 void TabDragController::OnWidgetMoved(views::Widget* widget) { | 596 void TabDragController::OnWidgetMoved(views::Widget* widget) { |
| 595 Drag(); | 597 // TODO: this needs to query event. |
| 598 Drag(gfx::Screen::GetCursorScreenPoint()); |
| 596 } | 599 } |
| 597 | 600 |
| 598 void TabDragController::TabStripEmpty() { | 601 void TabDragController::TabStripEmpty() { |
| 599 DCHECK(detach_into_browser_); | 602 DCHECK(detach_into_browser_); |
| 600 GetModel(source_tabstrip_)->RemoveObserver(this); | 603 GetModel(source_tabstrip_)->RemoveObserver(this); |
| 601 // NULL out source_tabstrip_ so that we don't attempt to add back to it (in | 604 // NULL out source_tabstrip_ so that we don't attempt to add back to it (in |
| 602 // the case of a revert). | 605 // the case of a revert). |
| 603 source_tabstrip_ = NULL; | 606 source_tabstrip_ = NULL; |
| 604 } | 607 } |
| 605 | 608 |
| 606 /////////////////////////////////////////////////////////////////////////////// | 609 /////////////////////////////////////////////////////////////////////////////// |
| 607 // TabDragController, private: | 610 // TabDragController, private: |
| 608 | 611 |
| 609 void TabDragController::InitWindowCreatePoint() { | 612 void TabDragController::InitWindowCreatePoint() { |
| 610 // window_create_point_ is only used in CompleteDrag() (through | 613 // window_create_point_ is only used in CompleteDrag() (through |
| 611 // GetWindowCreatePoint() to get the start point of the docked window) when | 614 // GetWindowCreatePoint() to get the start point of the docked window) when |
| 612 // the attached_tabstrip_ is NULL and all the window's related bound | 615 // the attached_tabstrip_ is NULL and all the window's related bound |
| 613 // information are obtained from source_tabstrip_. So, we need to get the | 616 // information are obtained from source_tabstrip_. So, we need to get the |
| 614 // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise, | 617 // first_tab based on source_tabstrip_, not attached_tabstrip_. Otherwise, |
| 615 // the window_create_point_ is not in the correct coordinate system. Please | 618 // the window_create_point_ is not in the correct coordinate system. Please |
| 616 // refer to http://crbug.com/6223 comment #15 for detailed information. | 619 // refer to http://crbug.com/6223 comment #15 for detailed information. |
| 617 views::View* first_tab = source_tabstrip_->tab_at(0); | 620 views::View* first_tab = source_tabstrip_->tab_at(0); |
| 618 views::View::ConvertPointToWidget(first_tab, &first_source_tab_point_); | 621 views::View::ConvertPointToWidget(first_tab, &first_source_tab_point_); |
| 619 window_create_point_ = first_source_tab_point_; | 622 window_create_point_ = first_source_tab_point_; |
| 620 window_create_point_.Offset(mouse_offset_.x(), mouse_offset_.y()); | 623 window_create_point_.Offset(mouse_offset_.x(), mouse_offset_.y()); |
| 621 } | 624 } |
| 622 | 625 |
| 623 gfx::Point TabDragController::GetWindowCreatePoint() const { | 626 gfx::Point TabDragController::GetWindowCreatePoint( |
| 624 gfx::Point cursor_point = GetCursorScreenPoint(); | 627 const gfx::Point& origin) const { |
| 625 if (dock_info_.type() != DockInfo::NONE && dock_info_.in_enable_area()) { | 628 if (dock_info_.type() != DockInfo::NONE && dock_info_.in_enable_area()) { |
| 626 // If we're going to dock, we need to return the exact coordinate, | 629 // If we're going to dock, we need to return the exact coordinate, |
| 627 // otherwise we may attempt to maximize on the wrong monitor. | 630 // otherwise we may attempt to maximize on the wrong monitor. |
| 628 return cursor_point; | 631 return origin; |
| 629 } | 632 } |
| 633 |
| 630 // If the cursor is outside the monitor area, move it inside. For example, | 634 // If the cursor is outside the monitor area, move it inside. For example, |
| 631 // dropping a tab onto the task bar on Windows produces this situation. | 635 // dropping a tab onto the task bar on Windows produces this situation. |
| 632 gfx::Rect work_area = gfx::Screen::GetMonitorNearestPoint( | 636 gfx::Rect work_area = gfx::Screen::GetMonitorNearestPoint(origin).work_area(); |
| 633 cursor_point).work_area(); | 637 gfx::Point create_point(origin); |
| 634 if (!work_area.IsEmpty()) { | 638 if (!work_area.IsEmpty()) { |
| 635 if (cursor_point.x() < work_area.x()) | 639 if (create_point.x() < work_area.x()) |
| 636 cursor_point.set_x(work_area.x()); | 640 create_point.set_x(work_area.x()); |
| 637 else if (cursor_point.x() > work_area.right()) | 641 else if (create_point.x() > work_area.right()) |
| 638 cursor_point.set_x(work_area.right()); | 642 create_point.set_x(work_area.right()); |
| 639 if (cursor_point.y() < work_area.y()) | 643 if (create_point.y() < work_area.y()) |
| 640 cursor_point.set_y(work_area.y()); | 644 create_point.set_y(work_area.y()); |
| 641 else if (cursor_point.y() > work_area.bottom()) | 645 else if (create_point.y() > work_area.bottom()) |
| 642 cursor_point.set_y(work_area.bottom()); | 646 create_point.set_y(work_area.bottom()); |
| 643 } | 647 } |
| 644 return gfx::Point(cursor_point.x() - window_create_point_.x(), | 648 return gfx::Point(create_point.x() - window_create_point_.x(), |
| 645 cursor_point.y() - window_create_point_.y()); | 649 create_point.y() - window_create_point_.y()); |
| 646 } | 650 } |
| 647 | 651 |
| 648 void TabDragController::UpdateDockInfo(const gfx::Point& screen_point) { | 652 void TabDragController::UpdateDockInfo(const gfx::Point& screen_point) { |
| 649 // Update the DockInfo for the current mouse coordinates. | 653 // Update the DockInfo for the current mouse coordinates. |
| 650 DockInfo dock_info = GetDockInfoAtPoint(screen_point); | 654 DockInfo dock_info = GetDockInfoAtPoint(screen_point); |
| 651 if (!dock_info.equals(dock_info_)) { | 655 if (!dock_info.equals(dock_info_)) { |
| 652 // DockInfo for current position differs. | 656 // DockInfo for current position differs. |
| 653 if (dock_info_.type() != DockInfo::NONE && | 657 if (dock_info_.type() != DockInfo::NONE && |
| 654 !dock_controllers_.empty()) { | 658 !dock_controllers_.empty()) { |
| 655 // Hide old visual indicator. | 659 // Hide old visual indicator. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 680 old_focused_view_ = source_tabstrip_->GetFocusManager()->GetFocusedView(); | 684 old_focused_view_ = source_tabstrip_->GetFocusManager()->GetFocusedView(); |
| 681 source_tabstrip_->GetFocusManager()->SetFocusedView(source_tabstrip_); | 685 source_tabstrip_->GetFocusManager()->SetFocusedView(source_tabstrip_); |
| 682 } | 686 } |
| 683 | 687 |
| 684 void TabDragController::RestoreFocus() { | 688 void TabDragController::RestoreFocus() { |
| 685 if (old_focused_view_ && attached_tabstrip_ == source_tabstrip_) | 689 if (old_focused_view_ && attached_tabstrip_ == source_tabstrip_) |
| 686 old_focused_view_->GetFocusManager()->SetFocusedView(old_focused_view_); | 690 old_focused_view_->GetFocusManager()->SetFocusedView(old_focused_view_); |
| 687 old_focused_view_ = NULL; | 691 old_focused_view_ = NULL; |
| 688 } | 692 } |
| 689 | 693 |
| 690 bool TabDragController::CanStartDrag() const { | 694 bool TabDragController::CanStartDrag(const gfx::Point& screen_point) const { |
| 691 // Determine if the mouse has moved beyond a minimum elasticity distance in | 695 // Determine if the mouse has moved beyond a minimum elasticity distance in |
| 692 // any direction from the starting point. | 696 // any direction from the starting point. |
| 693 static const int kMinimumDragDistance = 10; | 697 static const int kMinimumDragDistance = 10; |
| 694 gfx::Point screen_point = GetCursorScreenPoint(); | |
| 695 int x_offset = abs(screen_point.x() - start_screen_point_.x()); | 698 int x_offset = abs(screen_point.x() - start_screen_point_.x()); |
| 696 int y_offset = abs(screen_point.y() - start_screen_point_.y()); | 699 int y_offset = abs(screen_point.y() - start_screen_point_.y()); |
| 697 return sqrt(pow(static_cast<float>(x_offset), 2) + | 700 return sqrt(pow(static_cast<float>(x_offset), 2) + |
| 698 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; | 701 pow(static_cast<float>(y_offset), 2)) > kMinimumDragDistance; |
| 699 } | 702 } |
| 700 | 703 |
| 701 void TabDragController::ContinueDragging() { | 704 void TabDragController::ContinueDragging(const gfx::Point& screen_point) { |
| 702 DCHECK(!detach_into_browser_ || attached_tabstrip_); | 705 DCHECK(!detach_into_browser_ || attached_tabstrip_); |
| 703 | 706 |
| 704 // Note that the coordinates given to us by |drag_event| are basically | |
| 705 // useless, since they're in source_tab_ coordinates. On the surface, you'd | |
| 706 // think we could just convert them to screen coordinates, however in the | |
| 707 // situation where we're dragging the last tab in a window when multiple | |
| 708 // windows are open, the coordinates of |source_tab_| are way off in | |
| 709 // hyperspace since the window was moved there instead of being closed so | |
| 710 // that we'd keep receiving events. And our ConvertPointToScreen methods | |
| 711 // aren't really multi-screen aware. So really it's just safer to get the | |
| 712 // actual position of the mouse cursor directly from Windows here, which is | |
| 713 // guaranteed to be correct regardless of monitor config. | |
| 714 gfx::Point screen_point = GetCursorScreenPoint(); | |
| 715 | |
| 716 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? | 707 TabStrip* target_tabstrip = detach_behavior_ == DETACHABLE ? |
| 717 GetTabStripForPoint(screen_point) : source_tabstrip_; | 708 GetTabStripForPoint(screen_point) : source_tabstrip_; |
| 718 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_); | 709 bool tab_strip_changed = (target_tabstrip != attached_tabstrip_); |
| 719 | 710 |
| 711 if (attached_tabstrip_) { |
| 712 int move_delta = screen_point.x() - last_screen_point_.x(); |
| 713 if (move_delta > 0) |
| 714 mouse_move_direction_ |= kMovedMouseRight; |
| 715 else if (move_delta < 0) |
| 716 mouse_move_direction_ |= kMovedMouseLeft; |
| 717 } |
| 718 last_screen_point_ = screen_point; |
| 719 |
| 720 if (tab_strip_changed) { | 720 if (tab_strip_changed) { |
| 721 if (detach_into_browser_ && | 721 if (detach_into_browser_ && |
| 722 DragBrowserToNewTabStrip(target_tabstrip, screen_point) == | 722 DragBrowserToNewTabStrip(target_tabstrip, screen_point) == |
| 723 DRAG_BROWSER_RESULT_STOP) { | 723 DRAG_BROWSER_RESULT_STOP) { |
| 724 return; | 724 return; |
| 725 } else if (!detach_into_browser_) { | 725 } else if (!detach_into_browser_) { |
| 726 if (attached_tabstrip_) | 726 if (attached_tabstrip_) |
| 727 Detach(); | 727 Detach(); |
| 728 if (target_tabstrip) | 728 if (target_tabstrip) |
| 729 Attach(target_tabstrip, screen_point); | 729 Attach(target_tabstrip, screen_point); |
| 730 } | 730 } |
| 731 } | 731 } |
| 732 if (view_.get() || is_dragging_window_) { | 732 if (view_.get() || is_dragging_window_) { |
| 733 bring_to_front_timer_.Start(FROM_HERE, | 733 static_cast<base::Timer*>(&bring_to_front_timer_)->Start(FROM_HERE, |
| 734 base::TimeDelta::FromMilliseconds(kBringToFrontDelay), this, | 734 base::TimeDelta::FromMilliseconds(kBringToFrontDelay), |
| 735 &TabDragController::BringWindowUnderMouseToFront); | 735 base::Bind(&TabDragController::BringWindowUnderPointToFront, |
| 736 base::Unretained(this), screen_point)); |
| 736 } | 737 } |
| 737 | 738 |
| 738 UpdateDockInfo(screen_point); | 739 UpdateDockInfo(screen_point); |
| 739 | 740 |
| 740 if (!is_dragging_window_) { | 741 if (!is_dragging_window_) { |
| 741 if (attached_tabstrip_) { | 742 if (attached_tabstrip_) { |
| 742 if (move_only()) { | 743 if (move_only()) { |
| 743 DragActiveTabStacked(screen_point); | 744 DragActiveTabStacked(screen_point); |
| 744 } else { | 745 } else { |
| 745 MoveAttached(screen_point); | 746 MoveAttached(screen_point); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 browser_widget->EndMoveLoop(); | 786 browser_widget->EndMoveLoop(); |
| 786 | 787 |
| 787 // Ideally we would always swap the tabs now, but on windows it seems that | 788 // Ideally we would always swap the tabs now, but on windows it seems that |
| 788 // running the move loop implicitly activates the window when done, leading | 789 // running the move loop implicitly activates the window when done, leading |
| 789 // to all sorts of flicker. So, on windows, instead we process the move | 790 // to all sorts of flicker. So, on windows, instead we process the move |
| 790 // after the loop completes. But on chromeos, we can do tab swapping now to | 791 // after the loop completes. But on chromeos, we can do tab swapping now to |
| 791 // avoid the tab flashing issue(crbug.com/116329). | 792 // avoid the tab flashing issue(crbug.com/116329). |
| 792 #if defined(USE_ASH) | 793 #if defined(USE_ASH) |
| 793 is_dragging_window_ = false; | 794 is_dragging_window_ = false; |
| 794 Detach(); | 795 Detach(); |
| 795 gfx::Point screen_point(GetCursorScreenPoint()); | |
| 796 Attach(target_tabstrip, screen_point); | 796 Attach(target_tabstrip, screen_point); |
| 797 // Move the tabs into position. | 797 // Move the tabs into position. |
| 798 MoveAttached(screen_point); | 798 MoveAttached(screen_point); |
| 799 attached_tabstrip_->GetWidget()->Activate(); | 799 attached_tabstrip_->GetWidget()->Activate(); |
| 800 #else | 800 #else |
| 801 tab_strip_to_attach_to_after_exit_ = target_tabstrip; | 801 tab_strip_to_attach_to_after_exit_ = target_tabstrip; |
| 802 #endif | 802 #endif |
| 803 | 803 |
| 804 waiting_for_run_loop_to_exit_ = true; | 804 waiting_for_run_loop_to_exit_ = true; |
| 805 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING; | 805 end_run_loop_behavior_ = END_RUN_LOOP_CONTINUE_DRAGGING; |
| 806 return DRAG_BROWSER_RESULT_STOP; | 806 return DRAG_BROWSER_RESULT_STOP; |
| 807 } | 807 } |
| 808 Detach(); | 808 Detach(); |
| 809 Attach(target_tabstrip, screen_point); | 809 Attach(target_tabstrip, screen_point); |
| 810 return DRAG_BROWSER_RESULT_CONTINUE; | 810 return DRAG_BROWSER_RESULT_CONTINUE; |
| 811 } | 811 } |
| 812 | 812 |
| 813 void TabDragController::DragActiveTabStacked( | 813 void TabDragController::DragActiveTabStacked( |
| 814 const gfx::Point& screen_point) { | 814 const gfx::Point& screen_point) { |
| 815 if (attached_tabstrip_->tab_count() != | 815 if (attached_tabstrip_->tab_count() != |
| 816 static_cast<int>(initial_tab_positions_.size())) | 816 static_cast<int>(initial_tab_positions_.size())) |
| 817 return; // TODO: should cancel drag if this happens. | 817 return; // TODO: should cancel drag if this happens. |
| 818 | 818 |
| 819 int delta = screen_point.x() - start_screen_point_.x(); | 819 int delta = screen_point.x() - start_screen_point_.x(); |
| 820 attached_tabstrip_->DragActiveTab(initial_tab_positions_, delta); | 820 attached_tabstrip_->DragActiveTab(initial_tab_positions_, delta); |
| 821 } | 821 } |
| 822 | 822 |
| 823 void TabDragController::MoveAttachedToNextStackedIndex() { | 823 void TabDragController::MoveAttachedToNextStackedIndex( |
| 824 const gfx::Point& screen_point) { |
| 824 int index = attached_tabstrip_->touch_layout_->active_index(); | 825 int index = attached_tabstrip_->touch_layout_->active_index(); |
| 825 if (index + 1 >= attached_tabstrip_->tab_count()) | 826 if (index + 1 >= attached_tabstrip_->tab_count()) |
| 826 return; | 827 return; |
| 827 | 828 |
| 828 GetModel(attached_tabstrip_)->MoveSelectedTabsTo(index + 1); | 829 GetModel(attached_tabstrip_)->MoveSelectedTabsTo(index + 1); |
| 829 StartMoveStackedTimerIfNecessary(kMoveAttachedSubsequentDelay); | 830 StartMoveStackedTimerIfNecessary(screen_point, kMoveAttachedSubsequentDelay); |
| 830 } | 831 } |
| 831 | 832 |
| 832 void TabDragController::MoveAttachedToPreviousStackedIndex() { | 833 void TabDragController::MoveAttachedToPreviousStackedIndex( |
| 834 const gfx::Point& screen_point) { |
| 833 int index = attached_tabstrip_->touch_layout_->active_index(); | 835 int index = attached_tabstrip_->touch_layout_->active_index(); |
| 834 if (index <= attached_tabstrip_->GetMiniTabCount()) | 836 if (index <= attached_tabstrip_->GetMiniTabCount()) |
| 835 return; | 837 return; |
| 836 | 838 |
| 837 GetModel(attached_tabstrip_)->MoveSelectedTabsTo(index - 1); | 839 GetModel(attached_tabstrip_)->MoveSelectedTabsTo(index - 1); |
| 838 StartMoveStackedTimerIfNecessary(kMoveAttachedSubsequentDelay); | 840 StartMoveStackedTimerIfNecessary(screen_point, kMoveAttachedSubsequentDelay); |
| 839 } | 841 } |
| 840 | 842 |
| 841 void TabDragController::MoveAttached(const gfx::Point& screen_point) { | 843 void TabDragController::MoveAttached(const gfx::Point& screen_point) { |
| 842 DCHECK(attached_tabstrip_); | 844 DCHECK(attached_tabstrip_); |
| 843 DCHECK(!view_.get()); | 845 DCHECK(!view_.get()); |
| 844 DCHECK(!is_dragging_window_); | 846 DCHECK(!is_dragging_window_); |
| 845 | 847 |
| 846 int move_delta = screen_point.x() - last_screen_point_.x(); | |
| 847 if (move_delta > 0) | |
| 848 mouse_move_direction_ |= kMovedMouseRight; | |
| 849 else if (move_delta < 0) | |
| 850 mouse_move_direction_ |= kMovedMouseLeft; | |
| 851 last_screen_point_ = screen_point; | |
| 852 | |
| 853 gfx::Point dragged_view_point = GetAttachedDragPoint(screen_point); | 848 gfx::Point dragged_view_point = GetAttachedDragPoint(screen_point); |
| 854 | 849 |
| 855 // Determine the horizontal move threshold. This is dependent on the width | 850 // Determine the horizontal move threshold. This is dependent on the width |
| 856 // of tabs. The smaller the tabs compared to the standard size, the smaller | 851 // of tabs. The smaller the tabs compared to the standard size, the smaller |
| 857 // the threshold. | 852 // the threshold. |
| 858 int threshold = kHorizontalMoveThreshold; | 853 int threshold = kHorizontalMoveThreshold; |
| 859 if (!attached_tabstrip_->touch_layout_.get()) { | 854 if (!attached_tabstrip_->touch_layout_.get()) { |
| 860 double unselected, selected; | 855 double unselected, selected; |
| 861 attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected); | 856 attached_tabstrip_->GetCurrentTabWidths(&unselected, &selected); |
| 862 double ratio = unselected / Tab::GetStandardSize().width(); | 857 double ratio = unselected / Tab::GetStandardSize().width(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 last_move_screen_loc_ = screen_point.x(); | 895 last_move_screen_loc_ = screen_point.x(); |
| 901 } | 896 } |
| 902 } | 897 } |
| 903 | 898 |
| 904 if (!did_layout) { | 899 if (!did_layout) { |
| 905 attached_tabstrip_->LayoutDraggedTabsAt( | 900 attached_tabstrip_->LayoutDraggedTabsAt( |
| 906 tabs, source_tab_drag_data()->attached_tab, dragged_view_point, | 901 tabs, source_tab_drag_data()->attached_tab, dragged_view_point, |
| 907 initial_move_); | 902 initial_move_); |
| 908 } | 903 } |
| 909 | 904 |
| 910 StartMoveStackedTimerIfNecessary(kMoveAttachedInitialDelay); | 905 StartMoveStackedTimerIfNecessary(screen_point, kMoveAttachedInitialDelay); |
| 911 | 906 |
| 912 initial_move_ = false; | 907 initial_move_ = false; |
| 913 } | 908 } |
| 914 | 909 |
| 915 void TabDragController::MoveDetached(const gfx::Point& screen_point) { | 910 void TabDragController::MoveDetached(const gfx::Point& screen_point) { |
| 916 DCHECK(!attached_tabstrip_); | 911 DCHECK(!attached_tabstrip_); |
| 917 DCHECK(view_.get()); | 912 DCHECK(view_.get()); |
| 918 DCHECK(!is_dragging_window_); | 913 DCHECK(!is_dragging_window_); |
| 919 | 914 |
| 920 // Move the View. There are no changes to the model if we're detached. | 915 // Move the View. There are no changes to the model if we're detached. |
| 921 view_->MoveTo(screen_point); | 916 view_->MoveTo(screen_point); |
| 922 } | 917 } |
| 923 | 918 |
| 924 void TabDragController::StartMoveStackedTimerIfNecessary(int delay_ms) { | 919 void TabDragController::StartMoveStackedTimerIfNecessary( |
| 920 const gfx::Point& screen_point, |
| 921 int delay_ms) { |
| 925 DCHECK(attached_tabstrip_); | 922 DCHECK(attached_tabstrip_); |
| 926 | 923 |
| 927 TouchTabStripLayout* touch_layout = attached_tabstrip_->touch_layout_.get(); | 924 TouchTabStripLayout* touch_layout = attached_tabstrip_->touch_layout_.get(); |
| 928 if (!touch_layout) | 925 if (!touch_layout) |
| 929 return; | 926 return; |
| 930 | 927 |
| 931 gfx::Point screen_point = GetCursorScreenPoint(); | |
| 932 gfx::Point dragged_view_point = GetAttachedDragPoint(screen_point); | 928 gfx::Point dragged_view_point = GetAttachedDragPoint(screen_point); |
| 933 gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_point); | 929 gfx::Rect bounds = GetDraggedViewTabStripBounds(dragged_view_point); |
| 934 int index = touch_layout->active_index(); | 930 int index = touch_layout->active_index(); |
| 935 if (ShouldDragToNextStackedTab(bounds, index)) { | 931 if (ShouldDragToNextStackedTab(bounds, index)) { |
| 936 move_stacked_timer_.Start( | 932 static_cast<base::Timer*>(&move_stacked_timer_)->Start( |
| 937 FROM_HERE, | 933 FROM_HERE, |
| 938 base::TimeDelta::FromMilliseconds(delay_ms), this, | 934 base::TimeDelta::FromMilliseconds(delay_ms), |
| 939 &TabDragController::MoveAttachedToNextStackedIndex); | 935 base::Bind(&TabDragController::MoveAttachedToNextStackedIndex, |
| 936 base::Unretained(this), screen_point)); |
| 940 } else if (ShouldDragToPreviousStackedTab(bounds, index)) { | 937 } else if (ShouldDragToPreviousStackedTab(bounds, index)) { |
| 941 move_stacked_timer_.Start( | 938 static_cast<base::Timer*>(&move_stacked_timer_)->Start( |
| 942 FROM_HERE, | 939 FROM_HERE, |
| 943 base::TimeDelta::FromMilliseconds(delay_ms), this, | 940 base::TimeDelta::FromMilliseconds(delay_ms), |
| 944 &TabDragController::MoveAttachedToPreviousStackedIndex); | 941 base::Bind(&TabDragController::MoveAttachedToPreviousStackedIndex, |
| 942 base::Unretained(this), screen_point)); |
| 945 } | 943 } |
| 946 } | 944 } |
| 947 | 945 |
| 948 TabDragController::DetachPosition TabDragController::GetDetachPosition( | 946 TabDragController::DetachPosition TabDragController::GetDetachPosition( |
| 949 const gfx::Point& screen_point) { | 947 const gfx::Point& screen_point) { |
| 950 DCHECK(attached_tabstrip_); | 948 DCHECK(attached_tabstrip_); |
| 951 gfx::Point attached_point(screen_point); | 949 gfx::Point attached_point(screen_point); |
| 952 views::View::ConvertPointToView(NULL, attached_tabstrip_, &attached_point); | 950 views::View::ConvertPointToView(NULL, attached_tabstrip_, &attached_point); |
| 953 if (attached_point.x() < 0) | 951 if (attached_point.x() < 0) |
| 954 return DETACH_BEFORE; | 952 return DETACH_BEFORE; |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 if (move_loop_widget_) { | 1269 if (move_loop_widget_) { |
| 1272 move_loop_widget_->RemoveObserver(this); | 1270 move_loop_widget_->RemoveObserver(this); |
| 1273 move_loop_widget_ = NULL; | 1271 move_loop_widget_ = NULL; |
| 1274 } | 1272 } |
| 1275 is_dragging_window_ = false; | 1273 is_dragging_window_ = false; |
| 1276 waiting_for_run_loop_to_exit_ = false; | 1274 waiting_for_run_loop_to_exit_ = false; |
| 1277 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { | 1275 if (end_run_loop_behavior_ == END_RUN_LOOP_CONTINUE_DRAGGING) { |
| 1278 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; | 1276 end_run_loop_behavior_ = END_RUN_LOOP_STOP_DRAGGING; |
| 1279 if (tab_strip_to_attach_to_after_exit_) { | 1277 if (tab_strip_to_attach_to_after_exit_) { |
| 1280 Detach(); | 1278 Detach(); |
| 1281 gfx::Point screen_point(GetCursorScreenPoint()); | 1279 // TODO: this needs to query the event. |
| 1280 gfx::Point screen_point(gfx::Screen::GetCursorScreenPoint()); |
| 1282 Attach(tab_strip_to_attach_to_after_exit_, screen_point); | 1281 Attach(tab_strip_to_attach_to_after_exit_, screen_point); |
| 1283 // Move the tabs into position. | 1282 // Move the tabs into position. |
| 1284 MoveAttached(screen_point); | 1283 MoveAttached(screen_point); |
| 1285 attached_tabstrip_->GetWidget()->Activate(); | 1284 attached_tabstrip_->GetWidget()->Activate(); |
| 1286 tab_strip_to_attach_to_after_exit_ = NULL; | 1285 tab_strip_to_attach_to_after_exit_ = NULL; |
| 1287 } | 1286 } |
| 1288 DCHECK(attached_tabstrip_); | 1287 DCHECK(attached_tabstrip_); |
| 1289 attached_tabstrip_->GetWidget()->SetMouseCapture(attached_tabstrip_); | 1288 attached_tabstrip_->GetWidget()->SetMouseCapture(attached_tabstrip_); |
| 1290 } else if (active_) { | 1289 } else if (active_) { |
| 1291 EndDrag(result == views::Widget::MOVE_LOOP_CANCELED); | 1290 EndDrag(result == views::Widget::MOVE_LOOP_CANCELED); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 break; | 1662 break; |
| 1664 | 1663 |
| 1665 default: | 1664 default: |
| 1666 NOTREACHED(); | 1665 NOTREACHED(); |
| 1667 break; | 1666 break; |
| 1668 } | 1667 } |
| 1669 } | 1668 } |
| 1670 // Compel the model to construct a new window for the detached WebContents. | 1669 // Compel the model to construct a new window for the detached WebContents. |
| 1671 views::Widget* widget = source_tabstrip_->GetWidget(); | 1670 views::Widget* widget = source_tabstrip_->GetWidget(); |
| 1672 gfx::Rect window_bounds(widget->GetRestoredBounds()); | 1671 gfx::Rect window_bounds(widget->GetRestoredBounds()); |
| 1673 window_bounds.set_origin(GetWindowCreatePoint()); | 1672 window_bounds.set_origin(GetWindowCreatePoint(last_screen_point_)); |
| 1674 // When modifying the following if statement, please make sure not to | 1673 // When modifying the following if statement, please make sure not to |
| 1675 // introduce issue listed in http://crbug.com/6223 comment #11. | 1674 // introduce issue listed in http://crbug.com/6223 comment #11. |
| 1676 bool rtl_ui = base::i18n::IsRTL(); | 1675 bool rtl_ui = base::i18n::IsRTL(); |
| 1677 bool has_dock_position = (dock_info_.type() != DockInfo::NONE); | 1676 bool has_dock_position = (dock_info_.type() != DockInfo::NONE); |
| 1678 if (rtl_ui && has_dock_position) { | 1677 if (rtl_ui && has_dock_position) { |
| 1679 // Mirror X axis so the docked tab is aligned using the mouse click as | 1678 // Mirror X axis so the docked tab is aligned using the mouse click as |
| 1680 // the top-right corner. | 1679 // the top-right corner. |
| 1681 window_bounds.set_x(window_bounds.x() - window_bounds.width()); | 1680 window_bounds.set_x(window_bounds.x() - window_bounds.width()); |
| 1682 } | 1681 } |
| 1683 Browser* new_browser = | 1682 Browser* new_browser = |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1738 } | 1737 } |
| 1739 // DraggedTabView takes ownership of the renderers. | 1738 // DraggedTabView takes ownership of the renderers. |
| 1740 view_.reset(new DraggedTabView(renderers, renderer_bounds, mouse_offset_, | 1739 view_.reset(new DraggedTabView(renderers, renderer_bounds, mouse_offset_, |
| 1741 content_bounds.size(), photobooth)); | 1740 content_bounds.size(), photobooth)); |
| 1742 #else | 1741 #else |
| 1743 // Aura always hits the |detach_into_browser_| path. | 1742 // Aura always hits the |detach_into_browser_| path. |
| 1744 NOTREACHED(); | 1743 NOTREACHED(); |
| 1745 #endif | 1744 #endif |
| 1746 } | 1745 } |
| 1747 | 1746 |
| 1748 gfx::Point TabDragController::GetCursorScreenPoint() const { | |
| 1749 // TODO(sky): see if we can convert to using Screen every where. | |
| 1750 #if defined(OS_WIN) && !defined(USE_AURA) | |
| 1751 DWORD pos = GetMessagePos(); | |
| 1752 return gfx::Point(pos); | |
| 1753 #else | |
| 1754 return gfx::Screen::GetCursorScreenPoint(); | |
| 1755 #endif | |
| 1756 } | |
| 1757 | |
| 1758 gfx::Rect TabDragController::GetViewScreenBounds( | 1747 gfx::Rect TabDragController::GetViewScreenBounds( |
| 1759 views::View* view) const { | 1748 views::View* view) const { |
| 1760 gfx::Point view_topleft; | 1749 gfx::Point view_topleft; |
| 1761 views::View::ConvertPointToScreen(view, &view_topleft); | 1750 views::View::ConvertPointToScreen(view, &view_topleft); |
| 1762 gfx::Rect view_screen_bounds = view->GetLocalBounds(); | 1751 gfx::Rect view_screen_bounds = view->GetLocalBounds(); |
| 1763 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); | 1752 view_screen_bounds.Offset(view_topleft.x(), view_topleft.y()); |
| 1764 return view_screen_bounds; | 1753 return view_screen_bounds; |
| 1765 } | 1754 } |
| 1766 | 1755 |
| 1767 void TabDragController::HideFrame() { | 1756 void TabDragController::HideFrame() { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1801 | 1790 |
| 1802 std::vector<DockDisplayer*>::iterator i = | 1791 std::vector<DockDisplayer*>::iterator i = |
| 1803 std::find(dock_controllers_.begin(), dock_controllers_.end(), | 1792 std::find(dock_controllers_.begin(), dock_controllers_.end(), |
| 1804 controller); | 1793 controller); |
| 1805 if (i != dock_controllers_.end()) | 1794 if (i != dock_controllers_.end()) |
| 1806 dock_controllers_.erase(i); | 1795 dock_controllers_.erase(i); |
| 1807 else | 1796 else |
| 1808 NOTREACHED(); | 1797 NOTREACHED(); |
| 1809 } | 1798 } |
| 1810 | 1799 |
| 1811 void TabDragController::BringWindowUnderMouseToFront() { | 1800 void TabDragController::BringWindowUnderPointToFront( |
| 1801 const gfx::Point& screen_point) { |
| 1812 // If we're going to dock to another window, bring it to the front. | 1802 // If we're going to dock to another window, bring it to the front. |
| 1813 gfx::NativeWindow window = dock_info_.window(); | 1803 gfx::NativeWindow window = dock_info_.window(); |
| 1814 if (!window) { | 1804 if (!window) { |
| 1815 views::View* dragged_view; | 1805 views::View* dragged_view; |
| 1816 if (view_.get()) | 1806 if (view_.get()) |
| 1817 dragged_view = view_.get(); | 1807 dragged_view = view_.get(); |
| 1818 else | 1808 else |
| 1819 dragged_view = attached_tabstrip_; | 1809 dragged_view = attached_tabstrip_; |
| 1820 gfx::NativeView dragged_native_view = | 1810 gfx::NativeView dragged_native_view = |
| 1821 dragged_view->GetWidget()->GetNativeView(); | 1811 dragged_view->GetWidget()->GetNativeView(); |
| 1822 dock_windows_.insert(dragged_native_view); | 1812 dock_windows_.insert(dragged_native_view); |
| 1823 window = DockInfo::GetLocalProcessWindowAtPoint(GetCursorScreenPoint(), | 1813 window = |
| 1824 dock_windows_); | 1814 DockInfo::GetLocalProcessWindowAtPoint(screen_point, dock_windows_); |
| 1825 dock_windows_.erase(dragged_native_view); | 1815 dock_windows_.erase(dragged_native_view); |
| 1826 } | 1816 } |
| 1827 if (window) { | 1817 if (window) { |
| 1828 views::Widget* widget_window = views::Widget::GetWidgetForNativeView( | 1818 views::Widget* widget_window = views::Widget::GetWidgetForNativeView( |
| 1829 window); | 1819 window); |
| 1830 if (widget_window) | 1820 if (widget_window) |
| 1831 widget_window->StackAtTop(); | 1821 widget_window->StackAtTop(); |
| 1832 else | 1822 else |
| 1833 return; | 1823 return; |
| 1834 | 1824 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1888 } | 1878 } |
| 1889 | 1879 |
| 1890 default: | 1880 default: |
| 1891 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. | 1881 break; // Nothing to do for DETACH_ABOVE_OR_BELOW. |
| 1892 } | 1882 } |
| 1893 | 1883 |
| 1894 SetTrackedByWorkspace(browser->window()->GetNativeHandle(), false); | 1884 SetTrackedByWorkspace(browser->window()->GetNativeHandle(), false); |
| 1895 browser->window()->SetBounds(new_bounds); | 1885 browser->window()->SetBounds(new_bounds); |
| 1896 return browser; | 1886 return browser; |
| 1897 } | 1887 } |
| OLD | NEW |