Chromium Code Reviews| Index: components/exo/touch.cc |
| diff --git a/components/exo/touch.cc b/components/exo/touch.cc |
| index f0db59594419a36274fe3312914d6f254223ff90..9885bae318627049d344a040a705decf9003fe8b 100644 |
| --- a/components/exo/touch.cc |
| +++ b/components/exo/touch.cc |
| @@ -4,6 +4,10 @@ |
| #include "components/exo/touch.h" |
| +#include <algorithm> |
| +#include <cmath> |
| +#include <limits> |
| + |
| #include "components/exo/surface.h" |
| #include "components/exo/touch_delegate.h" |
| #include "components/exo/wm_helper.h" |
| @@ -12,22 +16,13 @@ |
| namespace exo { |
| namespace { |
| - |
| -// Helper function that returns an iterator to the first item in |vector| |
| -// with |value|. |
| -template <typename T, typename U> |
| -typename T::iterator FindVectorItem(T& vector, U value) { |
| - return std::find(vector.begin(), vector.end(), value); |
| +template <typename T> |
| +static bool AlmostEqual(T x, T y) { |
|
reveman
2016/12/07 03:16:18
This would need some explaining and maybe a rename
denniskempin
2016/12/07 18:32:18
We don't really have to do this, but the protocol
reveman
2016/12/07 22:58:00
I don't think we'll break any clients by sending a
denniskempin
2016/12/07 23:40:54
sgtm. Let's go with always sending the update. It'
|
| + return std::abs(x - y) <= |
| + std::numeric_limits<T>::epsilon() * std::max(std::abs(x), std::abs(y)); |
| } |
| - |
| -// Helper function that returns true if |vector| contains an item with |value|. |
| -template <typename T, typename U> |
| -bool VectorContainsItem(T& vector, U value) { |
| - return FindVectorItem(vector, value) != vector.end(); |
| } |
| -} // namespace |
| - |
| //////////////////////////////////////////////////////////////////////////////// |
| // Touch, public: |
| @@ -46,6 +41,8 @@ Touch::~Touch() { |
| // ui::EventHandler overrides: |
| void Touch::OnTouchEvent(ui::TouchEvent* event) { |
| + auto touch_details_iter = FindTouch(event->touch_id()); |
| + |
| switch (event->type()) { |
| case ui::ET_TOUCH_PRESSED: { |
| // Early out if event doesn't contain a valid target for touch device. |
| @@ -61,8 +58,9 @@ void Touch::OnTouchEvent(ui::TouchEvent* event) { |
| focus_->AddSurfaceObserver(this); |
| } |
| - DCHECK(!VectorContainsItem(touch_points_, event->touch_id())); |
| - touch_points_.push_back(event->touch_id()); |
| + DCHECK(touch_details_iter == touch_points_.end()); |
| + touch_details_iter = |
| + touch_points_.insert(touch_details_iter, {event->touch_id(), 0, 0}); |
| // Convert location to focus surface coordinate space. |
| DCHECK(focus_); |
| @@ -76,9 +74,9 @@ void Touch::OnTouchEvent(ui::TouchEvent* event) { |
| location); |
| } break; |
| case ui::ET_TOUCH_RELEASED: { |
| - auto it = FindVectorItem(touch_points_, event->touch_id()); |
| - if (it != touch_points_.end()) { |
| - touch_points_.erase(it); |
| + if (touch_details_iter != touch_points_.end()) { |
| + touch_points_.erase(touch_details_iter); |
| + touch_details_iter = touch_points_.end(); |
| // Reset focus surface if this is the last touch point. |
| if (touch_points_.empty()) { |
| @@ -91,8 +89,7 @@ void Touch::OnTouchEvent(ui::TouchEvent* event) { |
| } |
| } break; |
| case ui::ET_TOUCH_MOVED: { |
| - auto it = FindVectorItem(touch_points_, event->touch_id()); |
| - if (it != touch_points_.end()) { |
| + if (touch_details_iter != touch_points_.end()) { |
| DCHECK(focus_); |
| // Convert location to focus surface coordinate space. |
| gfx::Point location = event->location(); |
| @@ -105,21 +102,34 @@ void Touch::OnTouchEvent(ui::TouchEvent* event) { |
| } |
| } break; |
| case ui::ET_TOUCH_CANCELLED: { |
| - auto it = FindVectorItem(touch_points_, event->touch_id()); |
| - if (it != touch_points_.end()) { |
| + if (touch_details_iter != touch_points_.end()) { |
| DCHECK(focus_); |
| focus_->RemoveSurfaceObserver(this); |
| focus_ = nullptr; |
| // Cancel the full set of touch sequences as soon as one is canceled. |
| touch_points_.clear(); |
| + touch_details_iter = touch_points_.end(); |
| delegate_->OnTouchCancel(); |
| } |
| } break; |
| default: |
| NOTREACHED(); |
| - break; |
| + return; |
| + } |
| + if (touch_details_iter != touch_points_.end()) { |
| + float major = event->pointer_details().radius_x; |
| + float minor = event->pointer_details().radius_y; |
| + if (!AlmostEqual(major, touch_details_iter->major) || |
| + !AlmostEqual(minor, touch_details_iter->minor)) { |
| + touch_details_iter->major = major; |
| + touch_details_iter->minor = minor; |
| + delegate_->OnTouchShape(event->touch_id(), major, minor); |
| + } |
| } |
| + // todo(denniskempin): Extend ui::TouchEvent to signal end of sequence of |
| + // touch events to send TouchFrame once after all touches have been updated. |
| + delegate_->OnTouchFrame(); |
| } |
| //////////////////////////////////////////////////////////////////////////////// |
| @@ -148,4 +158,9 @@ Surface* Touch::GetEffectiveTargetForEvent(ui::Event* event) const { |
| return delegate_->CanAcceptTouchEventsForSurface(target) ? target : nullptr; |
| } |
| +std::vector<Touch::TouchDetails>::iterator Touch::FindTouch(int id) { |
| + return std::find_if(touch_points_.begin(), touch_points_.end(), |
| + [id](TouchDetails touch) { return touch.id == id; }); |
| +} |
| + |
| } // namespace exo |