OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 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 "ui/touch_selection/touch_selection_controller_aura.h" | |
6 | |
7 #include "ui/aura/client/cursor_client.h" | |
8 #include "ui/aura/client/screen_position_client.h" | |
9 #include "ui/aura/env.h" | |
10 #include "ui/aura/window.h" | |
11 #include "ui/events/event.h" | |
12 #include "ui/events/gesture_detection/gesture_configuration.h" | |
13 #include "ui/events/gestures/motion_event_aura.h" | |
14 #include "ui/touch_selection/touch_handle_drawable_aura.h" | |
15 | |
16 namespace ui { | |
17 namespace { | |
18 | |
19 gfx::Rect ConvertRectToScreen(aura::Window* window, const gfx::Rect& rect) { | |
20 gfx::Point origin = rect.origin(); | |
21 gfx::Point end = gfx::Point(rect.right(), rect.bottom()); | |
22 | |
23 aura::Window* root_window = window->GetRootWindow(); | |
24 if (!root_window) | |
25 return rect; | |
26 aura::client::ScreenPositionClient* screen_position_client = | |
27 aura::client::GetScreenPositionClient(root_window); | |
28 if (!screen_position_client) | |
29 return rect; | |
30 screen_position_client->ConvertPointToScreen(window, &origin); | |
31 screen_position_client->ConvertPointToScreen(window, &end); | |
32 return gfx::Rect(origin.x(), origin.y(), end.x() - origin.x(), | |
33 end.y() - origin.y()); | |
34 } | |
35 | |
36 void ClipPoint(gfx::PointF* point, const gfx::Rect& clip_rect) { | |
37 point->SetToMax(clip_rect.origin()); | |
38 point->SetToMin(clip_rect.bottom_right()); | |
39 } | |
40 | |
41 void ClipSelectionBound(SelectionBound* bound, const gfx::Rect& clip_rect) { | |
42 gfx::PointF edge_top = bound->edge_top(); | |
43 gfx::PointF edge_bottom = bound->edge_bottom(); | |
44 ClipPoint(&edge_top, clip_rect); | |
45 ClipPoint(&edge_bottom, clip_rect); | |
46 bound->SetEdge(edge_top, edge_bottom); | |
47 } | |
48 | |
49 } // namespace | |
50 | |
51 TouchSelectionControllerAura::TouchSelectionControllerAura( | |
52 TouchSelectionControllerAuraClient* client) | |
53 : client_(client), | |
54 motion_event_(new MotionEventAura), | |
55 scroll_in_progress_(false), | |
56 overscroll_in_progress_(false), | |
57 handle_drag_in_progress_(false), | |
58 selection_editable_(false) { | |
59 int tap_timeout_ms = | |
60 GestureConfiguration::GetInstance()->show_press_delay_in_ms(); | |
61 int touch_slop = | |
62 GestureConfiguration::GetInstance()->max_touch_move_in_pixels_for_click(); | |
63 bool show_on_tap_for_empty_editable = true; | |
64 controller_.reset(new TouchSelectionController( | |
65 this, | |
66 base::TimeDelta::FromMilliseconds(tap_timeout_ms), | |
67 touch_slop, | |
68 show_on_tap_for_empty_editable)); | |
69 } | |
70 | |
71 TouchSelectionControllerAura::~TouchSelectionControllerAura() { | |
72 } | |
73 | |
74 void TouchSelectionControllerAura::OnSelectionEditable(bool editable) { | |
75 selection_editable_ = editable; | |
76 controller_->OnSelectionEditable(editable); | |
77 UpdateQuickMenu(); | |
78 } | |
79 | |
80 void TouchSelectionControllerAura::OnSelectionEmpty(bool empty) { | |
81 controller_->OnSelectionEmpty(empty); | |
82 UpdateQuickMenu(); | |
83 } | |
84 | |
85 | |
86 void TouchSelectionControllerAura::OnSelectionBoundsUpdated( | |
87 const SelectionBound& start, | |
88 const SelectionBound& end) { | |
89 if (controller_->OnSelectionBoundsUpdated(start, end)) | |
90 UpdateQuickMenu(); | |
91 } | |
92 | |
93 void TouchSelectionControllerAura::HandleGestureEvent(GestureEvent* event) { | |
94 switch (event->type()) { | |
95 case ET_GESTURE_LONG_PRESS: | |
jdduke (slow)
2015/02/27 18:36:46
Who is most familiar with the previous version of
mohsen
2015/02/27 18:50:41
Previously, mostly sadrul@ and sky@ were reviewing
| |
96 controller_->OnLongPressEvent(); | |
97 break; | |
98 case ET_GESTURE_TAP: | |
99 if (RectBetweenSelectionBounds( | |
100 controller_->start(), | |
101 controller_->end()).Contains(event->x(), event->y())) { | |
102 if (!controller_->is_insertion_active() && | |
103 !controller_->is_selection_active()) { | |
104 controller_->AllowShowingFromCurrentSelection(); | |
105 event->SetHandled(); | |
106 } else if (!selection_editable_) { | |
107 event->SetHandled(); | |
108 } | |
109 } | |
110 if (!event->handled()) | |
111 controller_->OnTapEvent(); | |
112 break; | |
113 case ET_GESTURE_SCROLL_BEGIN: | |
114 scroll_in_progress_ = true; | |
115 UpdateQuickMenu(); | |
116 break; | |
117 case ET_GESTURE_SCROLL_END: | |
118 scroll_in_progress_ = false; | |
119 UpdateQuickMenu(); | |
120 break; | |
121 default: | |
122 break; | |
123 } | |
124 } | |
125 | |
126 void TouchSelectionControllerAura::HandleTouchEvent(TouchEvent* event) { | |
127 const int index = motion_event_->FindPointerIndexOfId(event->touch_id()); | |
128 const bool pointer_id_is_active = index != -1; | |
129 | |
130 if (event->type() != ET_TOUCH_PRESSED && !pointer_id_is_active) | |
131 return; | |
132 | |
133 if (event->type() == ET_TOUCH_PRESSED && pointer_id_is_active) | |
134 motion_event_.reset(new MotionEventAura); | |
135 | |
136 motion_event_->OnTouch(*event); | |
137 if (controller_->WillHandleTouchEvent(*motion_event_)) | |
138 event->SetHandled(); | |
139 motion_event_->CleanupRemovedTouchPoints(*event); | |
140 } | |
141 | |
142 void TouchSelectionControllerAura::HideAndDisallowShowingAutomatically() { | |
143 controller_->HideAndDisallowShowingAutomatically(); | |
144 UpdateQuickMenu(); | |
145 } | |
146 | |
147 void TouchSelectionControllerAura::OnWindowMoved() { | |
148 UpdateQuickMenu(); | |
149 } | |
150 | |
151 void TouchSelectionControllerAura::OnOverscrollStarted() { | |
152 overscroll_in_progress_ = true; | |
153 UpdateQuickMenu(); | |
154 } | |
155 | |
156 void TouchSelectionControllerAura::OnOverscrollCompleted() { | |
157 overscroll_in_progress_ = false; | |
158 UpdateQuickMenu(); | |
159 } | |
160 | |
161 void TouchSelectionControllerAura::OnFlingCompleted() { | |
162 scroll_in_progress_ = false; | |
163 UpdateQuickMenu(); | |
164 } | |
165 | |
166 bool TouchSelectionControllerAura::SupportsAnimation() const { | |
167 return false; | |
168 } | |
169 | |
170 void TouchSelectionControllerAura::SetNeedsAnimate() { | |
171 NOTREACHED(); | |
172 } | |
173 | |
174 void TouchSelectionControllerAura::MoveCaret(const gfx::PointF& position) { | |
175 client_->MoveCaret(position); | |
176 } | |
177 | |
178 void TouchSelectionControllerAura::MoveRangeSelectionExtent( | |
179 const gfx::PointF& extent) { | |
180 client_->MoveRangeSelectionExtent(extent); | |
181 } | |
182 | |
183 void TouchSelectionControllerAura::SelectBetweenCoordinates( | |
184 const gfx::PointF& base, | |
185 const gfx::PointF& extent) { | |
186 client_->SelectBetweenCoordinates(base, extent); | |
187 } | |
188 | |
189 void TouchSelectionControllerAura::OnSelectionEvent( | |
190 SelectionEventType event, | |
191 const gfx::PointF& position) { | |
192 switch (event) { | |
193 case SELECTION_SHOWN: | |
194 UpdateQuickMenu(); | |
195 aura::Env::GetInstance()->RemovePreTargetHandler(this); | |
196 aura::Env::GetInstance()->AddPreTargetHandler(this); | |
197 break; | |
198 case SELECTION_CLEARED: | |
199 aura::Env::GetInstance()->RemovePreTargetHandler(this); | |
200 UpdateQuickMenu(); | |
201 break; | |
202 case SELECTION_DRAG_STARTED: | |
203 handle_drag_in_progress_ = true; | |
204 UpdateQuickMenu(); | |
205 break; | |
206 case SELECTION_DRAG_STOPPED: | |
207 handle_drag_in_progress_ = false; | |
208 UpdateQuickMenu(); | |
209 break; | |
210 case INSERTION_SHOWN: | |
211 UpdateQuickMenu(); | |
212 aura::Env::GetInstance()->RemovePreTargetHandler(this); | |
213 aura::Env::GetInstance()->AddPreTargetHandler(this); | |
214 break; | |
215 case INSERTION_MOVED: | |
216 break; | |
217 case INSERTION_TAPPED: | |
218 //UpdateQuickMenu(); | |
219 break; | |
220 case INSERTION_CLEARED: | |
221 aura::Env::GetInstance()->RemovePreTargetHandler(this); | |
222 UpdateQuickMenu(); | |
223 break; | |
224 case INSERTION_DRAG_STARTED: | |
225 handle_drag_in_progress_ = true; | |
226 UpdateQuickMenu(); | |
227 break; | |
228 case INSERTION_DRAG_STOPPED: | |
229 handle_drag_in_progress_ = false; | |
230 UpdateQuickMenu(); | |
231 break; | |
232 }; | |
233 } | |
234 | |
235 scoped_ptr<TouchHandleDrawable> TouchSelectionControllerAura::CreateDrawable() { | |
236 return scoped_ptr<TouchHandleDrawable>( | |
237 new TouchHandleDrawableAura(client_->GetParentWindow())); | |
238 } | |
239 | |
240 gfx::Rect TouchSelectionControllerAura::GetMenuAnchorRect() const { | |
241 SelectionBound start = controller_->start(); | |
242 SelectionBound end = controller_->end(); | |
243 const gfx::Rect& client_bounds = client_->GetClientBounds(); | |
244 if (start.visible()) | |
245 ClipSelectionBound(&start, client_bounds); | |
246 if (end.visible()) | |
247 ClipSelectionBound(&end, client_bounds); | |
248 | |
249 if (start.visible() && end.visible()) | |
250 return RectBetweenSelectionBounds(start, end); | |
251 if (end.visible()) | |
252 return gfx::BoundingRect(end.edge_top_rounded(), end.edge_bottom_rounded()); | |
253 return gfx::BoundingRect(start.edge_top_rounded(), | |
254 start.edge_bottom_rounded()); | |
255 } | |
256 | |
257 void TouchSelectionControllerAura::ShowQuickMenu() { | |
258 DCHECK(controller_->is_insertion_active() || | |
259 controller_->is_selection_active()); | |
260 | |
261 if (!controller_->start().visible() && !controller_->end().visible()) | |
262 return; | |
263 | |
264 if (TouchSelectionMenuRunner::GetInstance()) { | |
265 aura::Window* parent = client_->GetParentWindow(); | |
266 TouchSelectionMenuRunner::GetInstance()->RunMenu( | |
267 this, | |
268 ConvertRectToScreen(parent, GetMenuAnchorRect()), | |
269 TouchHandleDrawableAura::GetMaxHandleImageSize(), | |
270 parent->GetToplevelWindow()); | |
271 } | |
272 } | |
273 | |
274 void TouchSelectionControllerAura::UpdateQuickMenu() { | |
275 // Hide quick menu if there is any. | |
276 if (TouchSelectionMenuRunner::GetInstance() && | |
277 TouchSelectionMenuRunner::GetInstance()->IsRunning()) { | |
278 TouchSelectionMenuRunner::GetInstance()->CloseMenu(); | |
279 } else { | |
280 quick_menu_timer_.Stop(); | |
281 } | |
282 | |
283 // Start timer to show quick menu if necessary. | |
284 if (!controller_->is_insertion_active() && | |
285 !controller_->is_selection_active()) | |
286 return; | |
287 | |
288 if (!IsQuickMenuAllowed()) | |
289 return; | |
290 | |
291 if (immediate_quick_menu_for_testing_) { | |
292 ShowQuickMenu(); | |
293 } else { | |
294 quick_menu_timer_.Start( | |
295 FROM_HERE, | |
296 base::TimeDelta::FromMilliseconds(100), | |
297 this, | |
298 &TouchSelectionControllerAura::ShowQuickMenu); | |
299 } | |
300 } | |
301 | |
302 bool TouchSelectionControllerAura::IsQuickMenuAllowed() const { | |
303 return !scroll_in_progress_ && !overscroll_in_progress_ && | |
304 !handle_drag_in_progress_; | |
305 } | |
306 | |
307 bool TouchSelectionControllerAura::IsCommandIdEnabled(int command_id) const { | |
308 return client_->IsCommandIdEnabled(command_id); | |
309 } | |
310 | |
311 void TouchSelectionControllerAura::ExecuteCommand(int command_id, | |
312 int event_flags) { | |
313 HideAndDisallowShowingAutomatically(); | |
314 client_->ExecuteCommand(command_id, event_flags); | |
315 } | |
316 | |
317 void TouchSelectionControllerAura::OpenContextMenu() { | |
318 HideAndDisallowShowingAutomatically(); | |
319 gfx::Rect anchor_rect = GetMenuAnchorRect(); | |
320 client_->OpenContextMenu(gfx::Point(anchor_rect.CenterPoint().x(), | |
321 anchor_rect.y())); | |
322 } | |
323 | |
324 void TouchSelectionControllerAura::OnKeyEvent(KeyEvent* event) { | |
325 DCHECK(controller_->is_insertion_active() || | |
326 controller_->is_selection_active()); | |
327 | |
328 HideAndDisallowShowingAutomatically(); | |
329 } | |
330 | |
331 void TouchSelectionControllerAura::OnMouseEvent(MouseEvent* event) { | |
332 DCHECK(controller_->is_insertion_active() || | |
333 controller_->is_selection_active()); | |
334 | |
335 aura::client::CursorClient* cursor_client = aura::client::GetCursorClient( | |
336 client_->GetParentWindow()->GetRootWindow()); | |
337 if (!cursor_client || cursor_client->IsMouseEventsEnabled()) | |
338 HideAndDisallowShowingAutomatically(); | |
339 } | |
340 | |
341 void TouchSelectionControllerAura::OnScrollEvent(ScrollEvent* event) { | |
342 DCHECK(controller_->is_insertion_active() || | |
343 controller_->is_selection_active()); | |
344 | |
345 HideAndDisallowShowingAutomatically(); | |
346 } | |
347 | |
348 } // namespace ui | |
OLD | NEW |