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

Side by Side Diff: content/browser/renderer_host/input/touch_selection_controller.cc

Issue 335943002: [Android] Composited selection handle rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@input_native_handles_final
Patch Set: Test and comments Created 6 years, 5 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 2014 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 "content/browser/renderer_host/input/touch_selection_controller.h"
6
7 #include "base/logging.h"
8
9 namespace content {
10
11 TouchSelectionController::TouchSelectionController(
12 TouchSelectionControllerClient* client)
13 : client_(client),
14 anchor_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
15 anchor_visible_(false),
16 focus_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
17 focus_visible_(false),
18 is_insertion_active_(false),
19 allow_automatic_insertion_activation_(false),
20 is_selection_active_(false),
21 allow_automatic_selection_activation_(false),
22 selection_editable_(false),
23 selection_editable_for_last_update_(false) {
24 DCHECK(client_);
25 HideAndDisallowAutomaticShowing();
26 }
27
28 TouchSelectionController::~TouchSelectionController() {
29 }
30
31 void TouchSelectionController::OnSelectionBoundsChanged(
32 const gfx::RectF& anchor_rect,
33 TouchHandleOrientation anchor_orientation,
34 bool anchor_visible,
35 const gfx::RectF& focus_rect,
36 TouchHandleOrientation focus_orientation,
37 bool focus_visible) {
38 if (!allow_automatic_selection_activation_ &&
39 !allow_automatic_insertion_activation_)
40 return;
41
42 if (anchor_rect_ == anchor_rect && focus_rect_ == focus_rect &&
43 anchor_orientation_ == anchor_orientation &&
44 focus_orientation_ == focus_orientation &&
45 anchor_visible_ == anchor_visible && focus_visible_ == focus_visible &&
46 selection_editable_ == selection_editable_for_last_update_)
47 return;
48
49 anchor_rect_ = anchor_rect;
50 anchor_orientation_ = anchor_orientation;
51 anchor_visible_ = anchor_visible;
52 focus_rect_ = focus_rect;
53 focus_orientation_ = focus_orientation;
54 focus_visible_ = focus_visible;
55 selection_editable_for_last_update_ = selection_editable_;
56
57 const gfx::PointF anchor = GetAnchorPosition();
58 const gfx::PointF focus = GetFocusPosition();
59 if (anchor.x() != focus.x() || anchor.y() != focus.y() ||
cjhopman 2014/07/07 22:13:41 anchor != focus
jdduke (slow) 2014/07/08 00:54:44 Done.
60 (start_selection_handle_ && start_selection_handle_->is_dragging()) ||
cjhopman 2014/07/07 22:13:41 Can this just use is_selection_active_ rather than
jdduke (slow) 2014/07/08 00:54:44 Done.
61 (end_selection_handle_ && end_selection_handle_->is_dragging())) {
62 // It's possible that the bounds temporarily overlap while a handle is
63 // being dragged, incorrectly reporting a CENTER orientation.
64 if (anchor_orientation_ == TOUCH_HANDLE_CENTER && start_selection_handle_)
cjhopman 2014/07/07 22:13:41 AIUI, if anchor_orientation_ == TOUCH_HANDLE_CENTE
jdduke (slow) 2014/07/08 00:54:44 It's definitely better, good call.
65 anchor_orientation_ = start_selection_handle_->orientation();
66 if (focus_orientation_ == TOUCH_HANDLE_CENTER && end_selection_handle_)
67 focus_orientation_ = end_selection_handle_->orientation();
68
69 OnSelectionChanged();
70 return;
71 }
72
73 if (anchor_orientation_ == TOUCH_HANDLE_CENTER) {
74 OnInsertionChanged();
75 return;
76 }
77
78 HideAndDisallowAutomaticShowing();
79 }
80
81 bool TouchSelectionController::WillHandleTouchEvent(
82 const ui::MotionEvent& event) {
83 if (is_insertion_active_) {
84 DCHECK(insertion_handle_);
85 return insertion_handle_->WillHandleTouchEvent(event);
86 }
87
88 if (is_selection_active_) {
89 DCHECK(start_selection_handle_);
90 DCHECK(end_selection_handle_);
91 return start_selection_handle_->WillHandleTouchEvent(event) ||
92 end_selection_handle_->WillHandleTouchEvent(event);
93 }
94
95 return false;
96 }
97
98 void TouchSelectionController::AllowAutomaticInsertionShowing() {
99 if (allow_automatic_insertion_activation_)
100 return;
101 allow_automatic_insertion_activation_ = true;
102 if (!is_insertion_active_ && !is_selection_active_)
103 ResetCachedValues();
104 }
105
106 void TouchSelectionController::AllowAutomaticSelectionShowing() {
107 if (allow_automatic_selection_activation_)
108 return;
109 allow_automatic_selection_activation_ = true;
110 if (!is_insertion_active_ && !is_selection_active_)
111 ResetCachedValues();
112 }
113
114 void TouchSelectionController::HideAndDisallowAutomaticShowing() {
115 DeactivateInsertion();
116 DeactivateSelection();
117 allow_automatic_insertion_activation_ = false;
118 allow_automatic_selection_activation_ = false;
119 }
120
121 void TouchSelectionController::OnSelectionEditable(bool editable) {
122 if (selection_editable_ == editable)
123 return;
124 selection_editable_ = editable;
125 if (!selection_editable_)
126 DeactivateInsertion();
127 }
128
129 bool TouchSelectionController::Animate(base::TimeTicks frame_time) {
130 if (is_insertion_active_)
131 return insertion_handle_->Animate(frame_time);
132
133 if (is_selection_active_) {
134 bool needs_animate = start_selection_handle_->Animate(frame_time);
135 needs_animate |= end_selection_handle_->Animate(frame_time);
136 return needs_animate;
137 }
138
139 return false;
140 }
141
142 void TouchSelectionController::OnHandleDragBegin(const TouchHandle& handle) {
143 if (&handle == insertion_handle_.get())
144 return;
145
146 if (&handle == start_selection_handle_.get()) {
147 fixed_handle_position_ = end_selection_handle_->position() -
148 gfx::Vector2dF(0, GetFocusLineHeight() / 2.f);
149 } else {
150 fixed_handle_position_ = start_selection_handle_->position() -
151 gfx::Vector2dF(0, GetAnchorLineHeight() / 2.f);
152 }
153 }
154
155 void TouchSelectionController::OnHandleDragUpdate(const TouchHandle& handle,
156 const gfx::PointF& position) {
157 // As the position corresponds to the bottom left point of the selection
158 // bound, offset it by half the corresponding line height.
159 float half_line_height = &handle == end_selection_handle_.get()
160 ? GetFocusLineHeight() / 2.f
161 : GetAnchorLineHeight() / 2.f;
162 gfx::PointF line_position = position - gfx::Vector2dF(0, half_line_height);
163 if (&handle == insertion_handle_.get()) {
164 client_->MoveCaret(line_position);
165 } else {
166 client_->SelectBetweenCoordinates(fixed_handle_position_, line_position);
167 }
168 }
169
170 void TouchSelectionController::OnHandleDragEnd(const TouchHandle& handle) {
171 }
172
173 void TouchSelectionController::OnHandleTapped(const TouchHandle& handle) {
174 if (insertion_handle_ && &handle == insertion_handle_.get())
175 client_->OnSelectionEvent(INSERTION_TAPPED, GetAnchorPosition());
176 }
177
178 void TouchSelectionController::SetNeedsAnimate() {
179 client_->SetNeedsAnimate();
180 }
181
182 scoped_ptr<TouchHandleDrawable> TouchSelectionController::CreateDrawable() {
183 return client_->CreateDrawable();
184 }
185
186 void TouchSelectionController::OnInsertionChanged() {
187 DeactivateSelection();
188
189 if (!allow_automatic_insertion_activation_ || !selection_editable_)
190 return;
191
192 bool was_active = is_insertion_active_;
193 gfx::PointF position = GetAnchorPosition();
194 if (!was_active)
195 ActivateInsertion();
196 else
197 client_->OnSelectionEvent(INSERTION_MOVED, position);
198
199 if (was_active)
200 insertion_handle_->SetVisibleAnimated(anchor_visible_);
201 else
202 insertion_handle_->SetVisible(anchor_visible_);
203
204 insertion_handle_->SetPosition(position);
205 }
206
207 void TouchSelectionController::OnSelectionChanged() {
208 DeactivateInsertion();
209
210 if (!allow_automatic_selection_activation_)
211 return;
212
213 const bool was_active = is_selection_active_;
214 ActivateSelection();
215 if (was_active) {
216 start_selection_handle_->SetVisibleAnimated(anchor_visible_);
217 end_selection_handle_->SetVisibleAnimated(focus_visible_);
218 } else {
219 start_selection_handle_->SetVisible(anchor_visible_);
220 end_selection_handle_->SetVisible(focus_visible_);
221 }
222 start_selection_handle_->SetPosition(GetAnchorPosition());
223 end_selection_handle_->SetPosition(GetFocusPosition());
224 }
225
226 void TouchSelectionController::ActivateInsertion() {
227 DCHECK(!is_selection_active_);
228
229 if (!insertion_handle_)
230 insertion_handle_.reset(new TouchHandle(this, TOUCH_HANDLE_CENTER));
231
232 if (!is_insertion_active_) {
233 is_insertion_active_ = true;
234 client_->OnSelectionEvent(INSERTION_SHOWN, GetAnchorPosition());
235 }
236 }
237
238 void TouchSelectionController::DeactivateInsertion() {
239 if (!is_insertion_active_)
240 return;
241 DCHECK(insertion_handle_);
242 insertion_handle_->Hide();
243 is_insertion_active_ = false;
244 client_->OnSelectionEvent(INSERTION_CLEARED, gfx::PointF());
245 }
246
247 void TouchSelectionController::ActivateSelection() {
248 DCHECK(!is_insertion_active_);
249
250 if (!start_selection_handle_)
251 start_selection_handle_.reset(new TouchHandle(this, anchor_orientation_));
252 else
253 start_selection_handle_->SetOrientation(anchor_orientation_);
254
255 if (!end_selection_handle_)
256 end_selection_handle_.reset(new TouchHandle(this, focus_orientation_));
257 else
258 end_selection_handle_->SetOrientation(focus_orientation_);
259
260 if (!is_selection_active_) {
261 is_selection_active_ = true;
262 client_->OnSelectionEvent(SELECTION_SHOWN, GetAnchorPosition());
263 }
264 }
265
266 void TouchSelectionController::DeactivateSelection() {
267 if (!is_selection_active_)
268 return;
269 DCHECK(start_selection_handle_);
270 DCHECK(end_selection_handle_);
271 start_selection_handle_->Hide();
272 end_selection_handle_->Hide();
273 is_selection_active_ = false;
274 client_->OnSelectionEvent(SELECTION_CLEARED, gfx::PointF());
275 }
276
277 void TouchSelectionController::ResetCachedValues() {
278 anchor_rect_ = gfx::RectF();
279 focus_rect_ = gfx::RectF();
280 anchor_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
281 focus_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
282 anchor_visible_ = false;
283 focus_visible_ = false;
284 selection_editable_for_last_update_ = false;
285 }
286
287 gfx::PointF TouchSelectionController::GetAnchorPosition() const {
288 return anchor_rect_.bottom_left();
289 }
290
291 gfx::PointF TouchSelectionController::GetFocusPosition() const {
292 return focus_rect_.bottom_left();
293 }
294
295 float TouchSelectionController::GetAnchorLineHeight() const {
296 return anchor_rect_.height();
297 }
298
299 float TouchSelectionController::GetFocusLineHeight() const {
300 return focus_rect_.height();
301 }
302
303 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698