Chromium Code Reviews| 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 initial_event_location_ = location_in_screen; | |
| 44 previous_event_location_ = location_in_screen; | |
| 45 item_ = item; | |
| 46 } | |
| 47 | |
| 48 void OverviewWindowDragController::Drag(WindowSelectorItem* item, | |
| 49 const gfx::Point& location_in_screen) { | |
| 50 DCHECK(item_ == item); | |
|
oshima
2017/06/14 00:19:26
DCHECK_EQ
If it should be always same, why we're
xdai1
2017/06/15 22:11:41
Theoretically it should be always same. But I was
oshima
2017/06/16 01:20:57
If that's the case, can you move the DCHECK to cal
xdai1
2017/06/16 18:49:52
Done.
| |
| 51 | |
| 52 if (!did_move_ && | |
| 53 (std::abs(location_in_screen.x() - initial_event_location_.x()) < | |
| 54 kMinimiumDragOffset || | |
| 55 std::abs(location_in_screen.y() - initial_event_location_.y()) < | |
| 56 kMinimiumDragOffset)) { | |
| 57 return; | |
| 58 } | |
| 59 did_move_ = true; | |
| 60 | |
| 61 // Updates the dragged |item_|'s board accordingly. | |
| 62 gfx::Rect bounds(item_->target_bounds()); | |
| 63 bounds.set_x(bounds.x() + location_in_screen.x() - | |
| 64 previous_event_location_.x()); | |
|
oshima
2017/06/14 00:19:26
Rect::Offset()
xdai1
2017/06/15 22:11:41
Done.
| |
| 65 bounds.set_y(bounds.y() + location_in_screen.y() - | |
| 66 previous_event_location_.y()); | |
| 67 item_->SetBounds(bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | |
| 68 previous_event_location_ = location_in_screen; | |
| 69 | |
| 70 // Then updates the phantom window if applicable. | |
| 71 UpdatePhantomWindow(location_in_screen); | |
| 72 } | |
| 73 | |
| 74 void OverviewWindowDragController::CompleteDrag(WindowSelectorItem* item) { | |
| 75 DCHECK(item_ == item); | |
| 76 | |
| 77 phantom_window_controller_.reset(); | |
| 78 | |
| 79 if (!did_move_) { | |
| 80 // If no drag was initiated (e.g., a click/tap on the overview window), | |
| 81 // activate the window. If the split view is active and has a left window, | |
| 82 // snap the current window to right. If the split view is active and has a | |
| 83 // right window, snap the current window to left. | |
| 84 SplitViewController::State split_state = split_view_controller_->state(); | |
| 85 if (split_state == SplitViewController::NOSNAP) | |
| 86 window_selector_->SelectWindow(item); | |
| 87 else if (split_state == SplitViewController::LEFT_SNAPPED) | |
| 88 SnapToRight(); | |
| 89 else if (split_state == SplitViewController::RIGHT_SNAPPED) | |
| 90 SnapToLeft(); | |
| 91 } else { | |
| 92 // If the window was dragged around but should not be snapped, move it back | |
| 93 // to overview window grid. | |
| 94 if (snap_type_ == SNAP_NONE) | |
| 95 window_selector_->PositionWindows(true /* animate */); | |
| 96 else if (snap_type_ == SNAP_LEFT) | |
| 97 SnapToLeft(); | |
| 98 else | |
| 99 SnapToRight(); | |
| 100 did_move_ = false; | |
| 101 } | |
| 102 } | |
| 103 | |
| 104 void OverviewWindowDragController::UpdatePhantomWindow( | |
| 105 const gfx::Point& location_in_screen) { | |
| 106 SnapType last_snap_type = snap_type_; | |
| 107 snap_type_ = GetSnapType(location_in_screen); | |
| 108 if (snap_type_ == SNAP_NONE || snap_type_ != last_snap_type) { | |
| 109 phantom_window_controller_.reset(); | |
| 110 if (snap_type_ == SNAP_NONE) | |
| 111 return; | |
| 112 } | |
| 113 | |
| 114 const bool can_snap = snap_type_ != SNAP_NONE && | |
| 115 wm::GetWindowState(item_->GetWindow())->CanSnap(); | |
| 116 if (!can_snap) { | |
| 117 snap_type_ = SNAP_NONE; | |
| 118 phantom_window_controller_.reset(); | |
| 119 return; | |
| 120 } | |
| 121 | |
| 122 aura::Window* target_window = item_->GetWindow(); | |
| 123 gfx::Rect phantom_bounds_in_screen = | |
| 124 (snap_type_ == SNAP_LEFT) | |
| 125 ? Shell::Get()->split_view_controller()->GetLeftWindowBoundsInScreen( | |
| 126 target_window) | |
| 127 : Shell::Get()->split_view_controller()->GetRightWindowBoundsInScreen( | |
| 128 target_window); | |
| 129 | |
| 130 if (!phantom_window_controller_) { | |
| 131 phantom_window_controller_.reset( | |
| 132 new PhantomWindowController(target_window)); | |
|
oshima
2017/06/14 00:19:27
base::MakeUnique
xdai1
2017/06/15 22:11:41
Done.
| |
| 133 } | |
| 134 phantom_window_controller_->Show(phantom_bounds_in_screen); | |
| 135 } | |
| 136 | |
| 137 OverviewWindowDragController::SnapType | |
| 138 OverviewWindowDragController::GetSnapType( | |
| 139 const gfx::Point& location_in_screen) { | |
| 140 gfx::Rect area( | |
| 141 ScreenUtil::GetDisplayWorkAreaBoundsInParent(item_->GetWindow())); | |
| 142 ::wm::ConvertRectToScreen(item_->GetWindow()->GetRootWindow(), &area); | |
| 143 area.Inset(kScreenEdgeInsetForDrag, 0, kScreenEdgeInsetForDrag, 0); | |
| 144 | |
| 145 if (location_in_screen.x() <= area.x()) | |
| 146 return SNAP_LEFT; | |
| 147 if (location_in_screen.x() >= area.right() - 1) | |
| 148 return SNAP_RIGHT; | |
| 149 return SNAP_NONE; | |
| 150 } | |
| 151 | |
| 152 void OverviewWindowDragController::SnapToLeft() { | |
| 153 item_->EnsureVisible(); | |
| 154 item_->RestoreWindow(); | |
| 155 | |
| 156 // |item_| will be deleted after RemoveWindowSelectorItem(). | |
| 157 aura::Window* left_window = item_->GetWindow(); | |
| 158 window_selector_->RemoveWindowSelectorItem(item_); | |
| 159 split_view_controller_->SetLeftWindow(left_window); | |
| 160 item_ = nullptr; | |
| 161 } | |
| 162 | |
| 163 void OverviewWindowDragController::SnapToRight() { | |
| 164 item_->EnsureVisible(); | |
| 165 item_->RestoreWindow(); | |
| 166 | |
| 167 // |item_| will be deleted after RemoveWindowSelectorItem(). | |
| 168 aura::Window* right_window = item_->GetWindow(); | |
| 169 window_selector_->RemoveWindowSelectorItem(item_); | |
| 170 split_view_controller_->SetRightWindow(right_window); | |
| 171 item_ = nullptr; | |
| 172 } | |
| 173 | |
| 174 } // namespace ash | |
| OLD | NEW |