Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: ui/touch_selection/touch_selection_controller_aura.cc

Issue 698253004: Reland: Implement Aura side of unified touch text selection for contents (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Improved tap-on-selection tests Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW
« no previous file with comments | « ui/touch_selection/touch_selection_controller_aura.h ('k') | ui/touch_selection/touch_selection_controller_aura_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698