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

Unified Diff: content/browser/renderer_host/input/touch_handle.cc

Issue 335943002: [Android] Composited selection handle rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@input_native_handles_final
Patch Set: Clean up paste popup interaction 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/input/touch_handle.cc
diff --git a/content/browser/renderer_host/input/touch_handle.cc b/content/browser/renderer_host/input/touch_handle.cc
new file mode 100644
index 0000000000000000000000000000000000000000..46aad50bf8a1375645bf1699aa47b1deee87f556
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_handle.cc
@@ -0,0 +1,191 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touch_handle.h"
+
+namespace content {
+
+namespace {
+
+// Maximum duration of a fade sequence.
+const double kFadeDurationMs = 200;
+
+// Maximum amount of travel for a fade sequence. This avoids handle "ghosting"
+// when the handle is moving rapidly while the fade is active.
+const double kFadeDistanceSquared = 20.f * 20.f;
+
+} // namespace
+
+// Responsible for rendering a selection or insertion handle for text editing.
+TouchHandle::TouchHandle(TouchHandleClient* client,
+ TouchHandleOrientation orientation)
+ : drawable_(client->CreateDrawable()),
+ client_(client),
+ orientation_(orientation),
+ deferred_orientation_(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
+ alpha_(0.f),
+ is_visible_(false),
+ is_dragging_(false) {
+ DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
+ drawable_->SetOrientation(orientation_);
cjhopman 2014/07/09 22:29:12 Should these initial values be arguments to client
jdduke (slow) 2014/07/10 02:08:39 I'll push through the position_ for completeness.
+ drawable_->SetAlpha(alpha_);
+ drawable_->SetVisible(is_visible_);
+}
+
+TouchHandle::~TouchHandle() {
+}
+
+void TouchHandle::SetVisible(bool visible, AnimationStyle animation_style) {
+ if (is_visible_ == visible)
+ return;
+ is_visible_ = visible;
+ if (animation_style == ANIMATION_NONE) {
+ drawable_->SetVisible(visible);
+ CancelFade();
+ } else {
+ // The fade will be rescheduled once dragging completes.
+ if (!is_dragging_)
+ ScheduleFade();
+ }
+}
+
+void TouchHandle::SetPosition(const gfx::PointF& position) {
+ if (position_ == position)
+ return;
+ position_ = position;
+ // Avoid positioning handles outside their visible bounds during a fade.
+ if (!fade_end_time_.is_null() && !is_visible_)
+ return;
+ drawable_->SetFocus(position_);
+}
+
+void TouchHandle::SetOrientation(TouchHandleOrientation orientation) {
+ DCHECK_NE(orientation, TOUCH_HANDLE_ORIENTATION_UNDEFINED);
+ if (is_dragging_) {
+ deferred_orientation_ = orientation;
+ return;
+ }
+
+ deferred_orientation_ = TOUCH_HANDLE_ORIENTATION_UNDEFINED;
+
+ if (orientation_ == orientation)
+ return;
+
+ orientation_ = orientation;
+ drawable_->SetOrientation(orientation);
+}
+
+void TouchHandle::Hide() {
+ SetVisible(false, ANIMATION_NONE);
+ CancelFade();
+ is_dragging_ = false;
+}
+
+bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
+ if (!is_dragging_ && event.GetAction() != ui::MotionEvent::ACTION_DOWN)
+ return false;
+
+ switch (event.GetAction()) {
+ case ui::MotionEvent::ACTION_DOWN: {
+ gfx::PointF touch_position = gfx::PointF(event.GetX(), event.GetY());
+ if (!is_visible_ || !drawable_->ContainsPoint(touch_position))
+ return false;
+ touch_down_position_ = touch_position;
+ touch_to_focus_offset_ = position_ - touch_down_position_;
+ touch_down_time_ = event.GetEventTime();
+ BeginDrag();
+ } break;
+
+ case ui::MotionEvent::ACTION_MOVE: {
+ gfx::PointF new_position =
+ gfx::PointF(event.GetX(), event.GetY()) + touch_to_focus_offset_;
+ client_->OnHandleDragUpdate(*this, new_position);
+ } break;
+
+ case ui::MotionEvent::ACTION_UP: {
+ base::TimeDelta delay = event.GetEventTime() - touch_down_time_;
+ if (delay < base::TimeDelta::FromMilliseconds(180))
+ client_->OnHandleTapped(*this);
+
+ EndDrag();
+ } break;
+
+ case ui::MotionEvent::ACTION_CANCEL:
+ EndDrag();
+ break;
+
+ default:
+ break;
+ };
+ return true;
+}
+
+bool TouchHandle::Animate(base::TimeTicks frame_time) {
+ if (fade_end_time_ == base::TimeTicks())
+ return false;
+
+ float time_u =
+ 1.f - (fade_end_time_ - frame_time).InMillisecondsF() / kFadeDurationMs;
+ float position_u =
+ (position_ - fade_start_position_).LengthSquared() / kFadeDistanceSquared;
+ float u = std::max(time_u, position_u);
+ SetAlpha(is_visible_ ? u : 1.f - u);
+
+ if (u >= 1.f) {
+ CancelFade();
+ return false;
+ }
+
+ return true;
+}
+
+void TouchHandle::BeginDrag() {
+ if (is_dragging_)
+ return;
+ is_dragging_ = true;
+ client_->OnHandleDragBegin(*this);
+}
+
+void TouchHandle::EndDrag() {
+ if (!is_dragging_)
+ return;
+
+ is_dragging_ = false;
+ client_->OnHandleDragEnd(*this);
+
+ if (deferred_orientation_ != TOUCH_HANDLE_ORIENTATION_UNDEFINED)
+ SetOrientation(deferred_orientation_);
+
+ ScheduleFade();
+}
+
+void TouchHandle::ScheduleFade() {
+ const float target_alpha = is_visible_ ? 1.f : 0.f;
+ if (target_alpha == alpha_)
+ return;
+
+ drawable_->SetVisible(true);
+ fade_end_time_ = base::TimeTicks::Now() +
+ base::TimeDelta::FromMillisecondsD(
+ kFadeDurationMs * std::abs(target_alpha - alpha_));
+ fade_start_position_ = position_;
+ client_->SetNeedsAnimate();
+}
+
+void TouchHandle::CancelFade() {
+ fade_end_time_ = base::TimeTicks();
+ SetAlpha(is_visible_ ? 1.f : 0.f);
+ drawable_->SetVisible(is_visible_);
+ drawable_->SetFocus(position_);
+}
+
+void TouchHandle::SetAlpha(float alpha) {
+ alpha = std::max(0.f, std::min(1.f, alpha));
+ if (alpha_ == alpha)
+ return;
+ alpha_ = alpha;
+ drawable_->SetAlpha(alpha);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698