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

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

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

Powered by Google App Engine
This is Rietveld 408576698