summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/composited_touch_handle_drawable.cc16
-rw-r--r--content/browser/android/composited_touch_handle_drawable.h3
-rw-r--r--content/browser/android/popup_touch_handle_drawable.cc15
-rw-r--r--content/browser/android/popup_touch_handle_drawable.h2
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java27
-rw-r--r--ui/touch_selection/touch_handle.cc32
-rw-r--r--ui/touch_selection/touch_handle.h2
-rw-r--r--ui/touch_selection/touch_handle_unittest.cc21
-rw-r--r--ui/touch_selection/touch_selection_controller_unittest.cc5
9 files changed, 80 insertions, 43 deletions
diff --git a/content/browser/android/composited_touch_handle_drawable.cc b/content/browser/android/composited_touch_handle_drawable.cc
index ff734a1..27fd671 100644
--- a/content/browser/android/composited_touch_handle_drawable.cc
+++ b/content/browser/android/composited_touch_handle_drawable.cc
@@ -139,22 +139,18 @@ void CompositedTouchHandleDrawable::SetFocus(const gfx::PointF& position) {
layer_->SetPosition(focal_position_ - focal_offset_from_origin_);
}
-bool CompositedTouchHandleDrawable::IntersectsWith(
- const gfx::RectF& rect) const {
- return BoundingRect().Intersects(gfx::ScaleRect(rect, dpi_scale_));
+gfx::RectF CompositedTouchHandleDrawable::GetVisibleBounds() const {
+ return gfx::ScaleRect(gfx::RectF(layer_->position().x(),
+ layer_->position().y(),
+ layer_->bounds().width(),
+ layer_->bounds().height()),
+ 1.f / dpi_scale_);
}
void CompositedTouchHandleDrawable::Detach() {
layer_->RemoveFromParent();
}
-gfx::RectF CompositedTouchHandleDrawable::BoundingRect() const {
- return gfx::RectF(layer_->position().x(),
- layer_->position().y(),
- layer_->bounds().width(),
- layer_->bounds().height());
-}
-
// static
bool CompositedTouchHandleDrawable::RegisterHandleViewResources(JNIEnv* env) {
return RegisterNativesImpl(env);
diff --git a/content/browser/android/composited_touch_handle_drawable.h b/content/browser/android/composited_touch_handle_drawable.h
index 3f31d77..63370f7 100644
--- a/content/browser/android/composited_touch_handle_drawable.h
+++ b/content/browser/android/composited_touch_handle_drawable.h
@@ -25,13 +25,12 @@ class CompositedTouchHandleDrawable : public ui::TouchHandleDrawable {
virtual void SetOrientation(ui::TouchHandleOrientation orientation) override;
virtual void SetAlpha(float alpha) override;
virtual void SetFocus(const gfx::PointF& position) override;
- virtual bool IntersectsWith(const gfx::RectF& rect) const override;
+ virtual gfx::RectF GetVisibleBounds() const override;
static bool RegisterHandleViewResources(JNIEnv* env);
private:
void Detach();
- gfx::RectF BoundingRect() const;
const float dpi_scale_;
ui::TouchHandleOrientation orientation_;
diff --git a/content/browser/android/popup_touch_handle_drawable.cc b/content/browser/android/popup_touch_handle_drawable.cc
index 42b7d7a..0ab3935 100644
--- a/content/browser/android/popup_touch_handle_drawable.cc
+++ b/content/browser/android/popup_touch_handle_drawable.cc
@@ -64,15 +64,14 @@ void PopupTouchHandleDrawable::SetFocus(const gfx::PointF& position) {
env, drawable_.obj(), position_pix.x(), position_pix.y());
}
-bool PopupTouchHandleDrawable::IntersectsWith(const gfx::RectF& rect) const {
- const gfx::RectF rect_pix = gfx::ScaleRect(rect, dpi_scale_);
+gfx::RectF PopupTouchHandleDrawable::GetVisibleBounds() const {
JNIEnv* env = base::android::AttachCurrentThread();
- return Java_PopupTouchHandleDrawable_intersectsWith(env,
- drawable_.obj(),
- rect_pix.x(),
- rect_pix.y(),
- rect_pix.width(),
- rect_pix.height());
+ gfx::RectF unscaled_rect(
+ Java_PopupTouchHandleDrawable_getPositionX(env, drawable_.obj()),
+ Java_PopupTouchHandleDrawable_getPositionY(env, drawable_.obj()),
+ Java_PopupTouchHandleDrawable_getVisibleWidth(env, drawable_.obj()),
+ Java_PopupTouchHandleDrawable_getVisibleHeight(env, drawable_.obj()));
+ return gfx::ScaleRect(unscaled_rect, 1.f / dpi_scale_);
}
// static
diff --git a/content/browser/android/popup_touch_handle_drawable.h b/content/browser/android/popup_touch_handle_drawable.h
index a991cac..e7f46ca 100644
--- a/content/browser/android/popup_touch_handle_drawable.h
+++ b/content/browser/android/popup_touch_handle_drawable.h
@@ -23,7 +23,7 @@ class PopupTouchHandleDrawable : public ui::TouchHandleDrawable {
virtual void SetOrientation(ui::TouchHandleOrientation orientation) override;
virtual void SetAlpha(float alpha) override;
virtual void SetFocus(const gfx::PointF& position) override;
- virtual bool IntersectsWith(const gfx::RectF& rect) const override;
+ virtual gfx::RectF GetVisibleBounds() const override;
static bool RegisterPopupTouchHandleDrawable(JNIEnv* env);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
index 34565de..02fa6a1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/PopupTouchHandleDrawable.java
@@ -384,13 +384,24 @@ public class PopupTouchHandleDrawable extends View {
}
@CalledByNative
- private boolean intersectsWith(float x, float y, float width, float height) {
- if (mDrawable == null) return false;
- final int drawableWidth = mDrawable.getIntrinsicWidth();
- final int drawableHeight = mDrawable.getIntrinsicHeight();
- return !(x >= mPositionX + drawableWidth
- || y >= mPositionY + drawableHeight
- || x + width <= mPositionX
- || y + height <= mPositionY);
+ private int getPositionX() {
+ return mPositionX;
+ }
+
+ @CalledByNative
+ private int getPositionY() {
+ return mPositionX;
+ }
+
+ @CalledByNative
+ private int getVisibleWidth() {
+ if (mDrawable == null) return 0;
+ return mDrawable.getIntrinsicWidth();
+ }
+
+ @CalledByNative
+ private int getVisibleHeight() {
+ if (mDrawable == null) return 0;
+ return mDrawable.getIntrinsicHeight();
}
}
diff --git a/ui/touch_selection/touch_handle.cc b/ui/touch_selection/touch_handle.cc
index 91c2874..0680e6d 100644
--- a/ui/touch_selection/touch_handle.cc
+++ b/ui/touch_selection/touch_handle.cc
@@ -27,6 +27,21 @@ const float kMinTouchMajorForHitTesting = 1.f;
// breaking handle dragging behavior.
const float kMaxTouchMajorForHitTesting = 36.f;
+// Note that the intersection region is boundary *exclusive*.
+bool RectIntersectsCircle(const gfx::RectF& rect,
+ const gfx::PointF& circle_center,
+ float circle_radius) {
+ DCHECK_GT(circle_radius, 0.f);
+ // An intersection occurs if the closest point between the rect and the
+ // circle's center is less than the circle's radius.
+ gfx::PointF closest_point_in_rect(circle_center);
+ closest_point_in_rect.SetToMax(rect.origin());
+ closest_point_in_rect.SetToMin(rect.bottom_right());
+
+ gfx::Vector2dF distance = circle_center - closest_point_in_rect;
+ return distance.LengthSquared() < (circle_radius * circle_radius);
+}
+
} // namespace
// Responsible for rendering a selection or insertion handle for text editing.
@@ -124,16 +139,17 @@ bool TouchHandle::WillHandleTouchEvent(const MotionEvent& event) {
case MotionEvent::ACTION_DOWN: {
if (!is_visible_)
return false;
- const float touch_size = std::max(
+ const gfx::PointF touch_point(event.GetX(), event.GetY());
+ const float touch_radius = std::max(
kMinTouchMajorForHitTesting,
- std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor()));
- const gfx::RectF touch_rect(event.GetX() - touch_size * .5f,
- event.GetY() - touch_size * .5f,
- touch_size,
- touch_size);
- if (!drawable_->IntersectsWith(touch_rect))
+ std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor())) * 0.5f;
+ if (!RectIntersectsCircle(drawable_->GetVisibleBounds(),
+ touch_point,
+ touch_radius)) {
+ EndDrag();
return false;
- touch_down_position_ = gfx::PointF(event.GetX(), event.GetY());
+ }
+ touch_down_position_ = touch_point;
touch_to_focus_offset_ = position_ - touch_down_position_;
touch_down_time_ = event.GetEventTime();
BeginDrag();
diff --git a/ui/touch_selection/touch_handle.h b/ui/touch_selection/touch_handle.h
index 1998f8e..f6863a2 100644
--- a/ui/touch_selection/touch_handle.h
+++ b/ui/touch_selection/touch_handle.h
@@ -33,7 +33,7 @@ class UI_TOUCH_SELECTION_EXPORT TouchHandleDrawable {
virtual void SetOrientation(TouchHandleOrientation orientation) = 0;
virtual void SetAlpha(float alpha) = 0;
virtual void SetFocus(const gfx::PointF& position) = 0;
- virtual bool IntersectsWith(const gfx::RectF& rect) const = 0;
+ virtual gfx::RectF GetVisibleBounds() const = 0;
};
// Interface through which |TouchHandle| communicates handle manipulation and
diff --git a/ui/touch_selection/touch_handle_unittest.cc b/ui/touch_selection/touch_handle_unittest.cc
index fded0c5..b266fdb 100644
--- a/ui/touch_selection/touch_handle_unittest.cc
+++ b/ui/touch_selection/touch_handle_unittest.cc
@@ -52,8 +52,8 @@ class MockTouchHandleDrawable : public TouchHandleDrawable {
data_->rect.set_origin(position);
}
- bool IntersectsWith(const gfx::RectF& rect) const override {
- return data_->rect.Intersects(rect);
+ gfx::RectF GetVisibleBounds() const override {
+ return data_->rect;
}
private:
@@ -415,7 +415,7 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
const float kOffset = kDefaultDrawableSize + kTouchSize / 2.001f;
MockMotionEvent event(
- MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ MockMotionEvent::ACTION_DOWN, event_time, kOffset, 0);
event.SetTouchMajor(0.f);
EXPECT_FALSE(handle.WillHandleTouchEvent(event));
EXPECT_FALSE(IsDragging());
@@ -432,6 +432,21 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
+ // The touch hit test region should be circular.
+ event = MockMotionEvent(
+ MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ event.SetTouchMajor(kTouchSize);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+
+ event.SetTouchMajor(kTouchSize * std::sqrt(2.f) - 0.1f);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+
+ event.SetTouchMajor(kTouchSize * std::sqrt(2.f) + 0.1f);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(IsDragging());
+
// Ensure a touch size of 0 can still register a hit.
event = MockMotionEvent(MockMotionEvent::ACTION_DOWN,
event_time,
diff --git a/ui/touch_selection/touch_selection_controller_unittest.cc b/ui/touch_selection/touch_selection_controller_unittest.cc
index 5b1839a..7bfc6c2 100644
--- a/ui/touch_selection/touch_selection_controller_unittest.cc
+++ b/ui/touch_selection/touch_selection_controller_unittest.cc
@@ -24,8 +24,9 @@ class MockTouchHandleDrawable : public TouchHandleDrawable {
void SetOrientation(TouchHandleOrientation orientation) override {}
void SetAlpha(float alpha) override {}
void SetFocus(const gfx::PointF& position) override {}
- bool IntersectsWith(const gfx::RectF& rect) const override {
- return *intersects_rect_;
+ gfx::RectF GetVisibleBounds() const override {
+ return *intersects_rect_ ? gfx::RectF(-1000, -1000, 2000, 2000)
+ : gfx::RectF(-1000, -1000, 0, 0);
}
private: