OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ash/wm/overview/overview_window_drag_controller.h" |
| 6 |
| 7 #include "ash/screen_util.h" |
| 8 #include "ash/shell.h" |
| 9 #include "ash/wm/overview/scoped_transform_overview_window.h" |
| 10 #include "ash/wm/overview/window_selector.h" |
| 11 #include "ash/wm/overview/window_selector_item.h" |
| 12 #include "ash/wm/splitview/split_view_controller.h" |
| 13 #include "ash/wm/window_positioning_utils.h" |
| 14 #include "ash/wm/window_state.h" |
| 15 #include "ash/wm/wm_event.h" |
| 16 #include "ash/wm/workspace/phantom_window_controller.h" |
| 17 #include "ui/aura/window.h" |
| 18 #include "ui/wm/core/coordinate_conversion.h" |
| 19 |
| 20 namespace ash { |
| 21 |
| 22 namespace { |
| 23 |
| 24 // The minimum offset that will be considered as a drag event. |
| 25 const int kMinimiumDragOffset = 5; |
| 26 |
| 27 // Snapping distance between the dragged window with the screen edge. It's |
| 28 // useful especially for touch events. |
| 29 const int kScreenEdgeInsetForDrag = 200; |
| 30 |
| 31 } // namespace |
| 32 |
| 33 OverviewWindowDragController::OverviewWindowDragController( |
| 34 WindowSelector* window_selector) |
| 35 : window_selector_(window_selector), |
| 36 split_view_controller_(Shell::Get()->split_view_controller()) {} |
| 37 |
| 38 OverviewWindowDragController::~OverviewWindowDragController() {} |
| 39 |
| 40 void OverviewWindowDragController::InitiateDrag( |
| 41 WindowSelectorItem* item, |
| 42 const gfx::Point& location_in_screen) { |
| 43 previous_event_location_ = location_in_screen; |
| 44 item_ = item; |
| 45 } |
| 46 |
| 47 void OverviewWindowDragController::Drag(const gfx::Point& location_in_screen) { |
| 48 if (!did_move_ && |
| 49 (std::abs(location_in_screen.x() - previous_event_location_.x()) < |
| 50 kMinimiumDragOffset || |
| 51 std::abs(location_in_screen.y() - previous_event_location_.y()) < |
| 52 kMinimiumDragOffset)) { |
| 53 return; |
| 54 } |
| 55 did_move_ = true; |
| 56 |
| 57 // Updates the dragged |item_|'s bounds accordingly. |
| 58 gfx::Rect bounds(item_->target_bounds()); |
| 59 bounds.Offset(location_in_screen.x() - previous_event_location_.x(), |
| 60 location_in_screen.y() - previous_event_location_.y()); |
| 61 item_->SetBounds(bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); |
| 62 previous_event_location_ = location_in_screen; |
| 63 |
| 64 UpdatePhantomWindow(location_in_screen); |
| 65 } |
| 66 |
| 67 void OverviewWindowDragController::CompleteDrag() { |
| 68 phantom_window_controller_.reset(); |
| 69 |
| 70 if (!did_move_) { |
| 71 // If no drag was initiated (e.g., a click/tap on the overview window), |
| 72 // activate the window. If the split view is active and has a left window, |
| 73 // snap the current window to right. If the split view is active and has a |
| 74 // right window, snap the current window to left. |
| 75 SplitViewController::State split_state = split_view_controller_->state(); |
| 76 if (split_state == SplitViewController::NOSNAP) |
| 77 window_selector_->SelectWindow(item_); |
| 78 else if (split_state == SplitViewController::LEFT_SNAPPED) |
| 79 SnapWindow(SNAP_RIGHT); |
| 80 else |
| 81 SnapWindow(SNAP_LEFT); |
| 82 } else { |
| 83 // If the window was dragged around but should not be snapped, move it back |
| 84 // to overview window grid. |
| 85 if (snap_type_ == SNAP_NONE) |
| 86 window_selector_->PositionWindows(true /* animate */); |
| 87 else if (snap_type_ == SNAP_LEFT) |
| 88 SnapWindow(SNAP_LEFT); |
| 89 else |
| 90 SnapWindow(SNAP_RIGHT); |
| 91 did_move_ = false; |
| 92 } |
| 93 } |
| 94 |
| 95 void OverviewWindowDragController::UpdatePhantomWindow( |
| 96 const gfx::Point& location_in_screen) { |
| 97 SnapType last_snap_type = snap_type_; |
| 98 snap_type_ = GetSnapType(location_in_screen); |
| 99 if (snap_type_ == SNAP_NONE || snap_type_ != last_snap_type) { |
| 100 phantom_window_controller_.reset(); |
| 101 if (snap_type_ == SNAP_NONE) |
| 102 return; |
| 103 } |
| 104 |
| 105 const bool can_snap = snap_type_ != SNAP_NONE && |
| 106 wm::GetWindowState(item_->GetWindow())->CanSnap(); |
| 107 if (!can_snap) { |
| 108 snap_type_ = SNAP_NONE; |
| 109 phantom_window_controller_.reset(); |
| 110 return; |
| 111 } |
| 112 |
| 113 aura::Window* target_window = item_->GetWindow(); |
| 114 SplitViewController::State snap_type = |
| 115 (snap_type_ == SNAP_LEFT) ? SplitViewController::LEFT_SNAPPED |
| 116 : SplitViewController::RIGHT_SNAPPED; |
| 117 gfx::Rect phantom_bounds_in_screen = |
| 118 split_view_controller_->GetSnappedWindowBoundsInScreen(target_window, |
| 119 snap_type); |
| 120 |
| 121 if (!phantom_window_controller_) { |
| 122 phantom_window_controller_ = |
| 123 base::MakeUnique<PhantomWindowController>(target_window); |
| 124 } |
| 125 phantom_window_controller_->Show(phantom_bounds_in_screen); |
| 126 } |
| 127 |
| 128 OverviewWindowDragController::SnapType |
| 129 OverviewWindowDragController::GetSnapType( |
| 130 const gfx::Point& location_in_screen) { |
| 131 gfx::Rect area( |
| 132 ScreenUtil::GetDisplayWorkAreaBoundsInParent(item_->GetWindow())); |
| 133 ::wm::ConvertRectToScreen(item_->GetWindow()->GetRootWindow(), &area); |
| 134 area.Inset(kScreenEdgeInsetForDrag, 0); |
| 135 |
| 136 if (location_in_screen.x() <= area.x()) |
| 137 return SNAP_LEFT; |
| 138 if (location_in_screen.x() >= area.right() - 1) |
| 139 return SNAP_RIGHT; |
| 140 return SNAP_NONE; |
| 141 } |
| 142 |
| 143 void OverviewWindowDragController::SnapWindow(SnapType snap_type) { |
| 144 DCHECK_NE(snap_type, SNAP_NONE); |
| 145 |
| 146 item_->EnsureVisible(); |
| 147 item_->RestoreWindow(); |
| 148 |
| 149 // |item_| will be deleted after RemoveWindowSelectorItem(). |
| 150 aura::Window* window = item_->GetWindow(); |
| 151 window_selector_->RemoveWindowSelectorItem(item_); |
| 152 (snap_type == SNAP_LEFT) ? split_view_controller_->SetLeftWindow(window) |
| 153 : split_view_controller_->SetRightWindow(window); |
| 154 item_ = nullptr; |
| 155 } |
| 156 |
| 157 } // namespace ash |
OLD | NEW |