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(const gfx::Point& location_in_screen) { | |
49 if (!did_move_ && | |
50 (std::abs(location_in_screen.x() - initial_event_location_.x()) < | |
51 kMinimiumDragOffset || | |
52 std::abs(location_in_screen.y() - initial_event_location_.y()) < | |
53 kMinimiumDragOffset)) { | |
54 return; | |
55 } | |
56 did_move_ = true; | |
57 | |
58 // Updates the dragged |item_|'s board accordingly. | |
varkha
2017/06/21 01:51:52
nit: Updates -> Update
nit: border? bounds?
xdai1
2017/06/22 21:46:33
oops. Done
| |
59 gfx::Rect bounds(item_->target_bounds()); | |
60 bounds.Offset(location_in_screen.x() - previous_event_location_.x(), | |
61 location_in_screen.y() - previous_event_location_.y()); | |
62 item_->SetBounds(bounds, OverviewAnimationType::OVERVIEW_ANIMATION_NONE); | |
63 previous_event_location_ = location_in_screen; | |
64 | |
65 // Then updates the phantom window if applicable. | |
varkha
2017/06/21 01:51:52
nit: updates -> update or consider removing this c
xdai1
2017/06/22 21:46:33
Done.
| |
66 UpdatePhantomWindow(location_in_screen); | |
67 } | |
68 | |
69 void OverviewWindowDragController::CompleteDrag() { | |
70 phantom_window_controller_.reset(); | |
71 | |
72 if (!did_move_) { | |
73 // If no drag was initiated (e.g., a click/tap on the overview window), | |
74 // activate the window. If the split view is active and has a left window, | |
75 // snap the current window to right. If the split view is active and has a | |
76 // right window, snap the current window to left. | |
77 SplitViewController::State split_state = split_view_controller_->state(); | |
78 if (split_state == SplitViewController::NOSNAP) | |
79 window_selector_->SelectWindow(item_); | |
80 else if (split_state == SplitViewController::LEFT_SNAPPED) | |
81 SnapToRight(); | |
82 else if (split_state == SplitViewController::RIGHT_SNAPPED) | |
varkha
2017/06/21 01:51:52
nit: maybe just else and DCHECK_EQ(split_state, Sp
xdai1
2017/06/22 21:46:33
Done.
| |
83 SnapToLeft(); | |
84 } else { | |
85 // If the window was dragged around but should not be snapped, move it back | |
86 // to overview window grid. | |
87 if (snap_type_ == SNAP_NONE) | |
88 window_selector_->PositionWindows(true /* animate */); | |
varkha
2017/06/21 01:51:52
Could you make sure that this scenario does not ch
xdai1
2017/06/22 21:46:33
Comfirmed it does change the stacking order. I mod
| |
89 else if (snap_type_ == SNAP_LEFT) | |
90 SnapToLeft(); | |
91 else | |
92 SnapToRight(); | |
93 did_move_ = false; | |
94 } | |
95 } | |
96 | |
97 void OverviewWindowDragController::UpdatePhantomWindow( | |
98 const gfx::Point& location_in_screen) { | |
99 SnapType last_snap_type = snap_type_; | |
100 snap_type_ = GetSnapType(location_in_screen); | |
101 if (snap_type_ == SNAP_NONE || snap_type_ != last_snap_type) { | |
102 phantom_window_controller_.reset(); | |
103 if (snap_type_ == SNAP_NONE) | |
104 return; | |
105 } | |
106 | |
107 const bool can_snap = snap_type_ != SNAP_NONE && | |
108 wm::GetWindowState(item_->GetWindow())->CanSnap(); | |
109 if (!can_snap) { | |
110 snap_type_ = SNAP_NONE; | |
111 phantom_window_controller_.reset(); | |
112 return; | |
113 } | |
114 | |
115 aura::Window* target_window = item_->GetWindow(); | |
116 SplitViewController::State snap_type = | |
117 (snap_type_ == SNAP_LEFT) ? SplitViewController::LEFT_SNAPPED | |
118 : SplitViewController::RIGHT_SNAPPED; | |
119 gfx::Rect phantom_bounds_in_screen = | |
120 Shell::Get()->split_view_controller()->GetSnappedWindowBoundsInScreen( | |
varkha
2017/06/21 01:51:52
Can you use |split_view_controller_| here?
xdai1
2017/06/22 21:46:33
Done.
| |
121 target_window, snap_type); | |
122 | |
123 if (!phantom_window_controller_) { | |
124 phantom_window_controller_ = | |
125 base::MakeUnique<PhantomWindowController>(target_window); | |
126 } | |
127 phantom_window_controller_->Show(phantom_bounds_in_screen); | |
128 } | |
129 | |
130 OverviewWindowDragController::SnapType | |
131 OverviewWindowDragController::GetSnapType( | |
132 const gfx::Point& location_in_screen) { | |
133 gfx::Rect area( | |
134 ScreenUtil::GetDisplayWorkAreaBoundsInParent(item_->GetWindow())); | |
135 ::wm::ConvertRectToScreen(item_->GetWindow()->GetRootWindow(), &area); | |
136 area.Inset(kScreenEdgeInsetForDrag, 0, kScreenEdgeInsetForDrag, 0); | |
varkha
2017/06/21 01:51:52
nit: area.Inset(kScreenEdgeInsetForDrag, 0) should
varkha
2017/06/21 01:51:52
I think it would be much easier to snap when dragg
xdai1
2017/06/22 21:46:33
Done.
xdai1
2017/06/22 21:46:33
For the first window, it requires the user to drag
| |
137 | |
138 if (location_in_screen.x() <= area.x()) | |
139 return SNAP_LEFT; | |
140 if (location_in_screen.x() >= area.right() - 1) | |
141 return SNAP_RIGHT; | |
142 return SNAP_NONE; | |
143 } | |
144 | |
145 void OverviewWindowDragController::SnapToLeft() { | |
146 item_->EnsureVisible(); | |
147 item_->RestoreWindow(); | |
148 | |
149 // |item_| will be deleted after RemoveWindowSelectorItem(). | |
150 aura::Window* left_window = item_->GetWindow(); | |
151 window_selector_->RemoveWindowSelectorItem(item_); | |
152 split_view_controller_->SetLeftWindow(left_window); | |
153 item_ = nullptr; | |
154 } | |
155 | |
156 void OverviewWindowDragController::SnapToRight() { | |
varkha
2017/06/21 01:51:52
Seems like those 2 methods could be merged since t
xdai1
2017/06/22 21:46:32
Merged them together to SnapWindow(..) function.
| |
157 item_->EnsureVisible(); | |
158 item_->RestoreWindow(); | |
159 | |
160 // |item_| will be deleted after RemoveWindowSelectorItem(). | |
161 aura::Window* right_window = item_->GetWindow(); | |
162 window_selector_->RemoveWindowSelectorItem(item_); | |
163 split_view_controller_->SetRightWindow(right_window); | |
164 item_ = nullptr; | |
165 } | |
166 | |
167 } // namespace ash | |
OLD | NEW |