summaryrefslogtreecommitdiffstats
path: root/ui/base/gestures
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 05:27:25 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-07 05:27:25 +0000
commit60ea81cc5a42676c32505e5cce6fa80835726afd (patch)
tree4f8aa9e842fe5cac253440ed911a8079498802a2 /ui/base/gestures
parent1de7a0c58d965df1528f0005ec8d39c907d1b223 (diff)
downloadchromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.zip
chromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.tar.gz
chromium_src-60ea81cc5a42676c32505e5cce6fa80835726afd.tar.bz2
Changes SetCapture to transfer events rather then cancel all.
BUG=124277 TEST=covered by tests. R=sadrul@chromium.org Review URL: https://chromiumcodereview.appspot.com/10539037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base/gestures')
-rw-r--r--ui/base/gestures/gesture_recognizer.h9
-rw-r--r--ui/base/gestures/gesture_recognizer_impl.cc112
-rw-r--r--ui/base/gestures/gesture_recognizer_impl.h34
3 files changed, 90 insertions, 65 deletions
diff --git a/ui/base/gestures/gesture_recognizer.h b/ui/base/gestures/gesture_recognizer.h
index 84085e5..6a4392b 100644
--- a/ui/base/gestures/gesture_recognizer.h
+++ b/ui/base/gestures/gesture_recognizer.h
@@ -60,10 +60,11 @@ class UI_EXPORT GestureRecognizer {
// of |location|, returns the target of the nearest active touch.
virtual GestureConsumer* GetTargetForLocation(const gfx::Point& location) = 0;
- // For each touch on windows other than |capturer|, a cancel event
- // is fired. These touches are then ignored until they are released
- // and pressed again.
- virtual void CancelNonCapturedTouches(GestureConsumer* capturer) = 0;
+ // Makes |new_consumer| the target for events previously targetting
+ // |current_consumer|. All other targets are cancelled. If |new_consumer| is
+ // NULL, all targets are cancelled.
+ virtual void TransferEventsTo(GestureConsumer* current_consumer,
+ GestureConsumer* new_consumer) = 0;
};
} // namespace ui
diff --git a/ui/base/gestures/gesture_recognizer_impl.cc b/ui/base/gestures/gesture_recognizer_impl.cc
index d17606a..350488d 100644
--- a/ui/base/gestures/gesture_recognizer_impl.cc
+++ b/ui/base/gestures/gesture_recognizer_impl.cc
@@ -12,11 +12,14 @@
#include "ui/base/gestures/gesture_sequence.h"
#include "ui/base/gestures/gesture_types.h"
+namespace ui {
+
namespace {
+
// This is used to pop a std::queue when returning from a function.
class ScopedPop {
public:
- explicit ScopedPop(std::queue<ui::TouchEvent*>* queue) : queue_(queue) {
+ explicit ScopedPop(std::queue<TouchEvent*>* queue) : queue_(queue) {
}
~ScopedPop() {
@@ -25,14 +28,14 @@ class ScopedPop {
}
private:
- std::queue<ui::TouchEvent*>* queue_;
+ std::queue<TouchEvent*>* queue_;
DISALLOW_COPY_AND_ASSIGN(ScopedPop);
};
-// CancelledTouchEvent mirrors a ui::TouchEvent object.
-class MirroredTouchEvent : public ui::TouchEvent {
+// CancelledTouchEvent mirrors a TouchEvent object.
+class MirroredTouchEvent : public TouchEvent {
public:
- explicit MirroredTouchEvent(const ui::TouchEvent* real)
+ explicit MirroredTouchEvent(const TouchEvent* real)
: type_(real->GetEventType()),
location_(real->GetLocation()),
touch_id_(real->GetTouchId()),
@@ -47,8 +50,8 @@ class MirroredTouchEvent : public ui::TouchEvent {
virtual ~MirroredTouchEvent() {
}
- // Overridden from ui::TouchEvent.
- virtual ui::EventType GetEventType() const OVERRIDE {
+ // Overridden from TouchEvent.
+ virtual EventType GetEventType() const OVERRIDE {
return type_;
}
@@ -85,10 +88,10 @@ class MirroredTouchEvent : public ui::TouchEvent {
}
protected:
- void set_type(const ui::EventType type) { type_ = type; }
+ void set_type(const EventType type) { type_ = type; }
private:
- ui::EventType type_;
+ EventType type_;
gfx::Point location_;
int touch_id_;
int flags_;
@@ -104,9 +107,9 @@ class MirroredTouchEvent : public ui::TouchEvent {
// A mirrored event, except for the type, which is always ET_TOUCH_CANCELLED.
class CancelledTouchEvent : public MirroredTouchEvent {
public:
- explicit CancelledTouchEvent(const ui::TouchEvent* src)
+ explicit CancelledTouchEvent(const TouchEvent* src)
: MirroredTouchEvent(src) {
- set_type(ui::ET_TOUCH_CANCELLED);
+ set_type(ET_TOUCH_CANCELLED);
}
virtual ~CancelledTouchEvent() {}
@@ -117,16 +120,46 @@ class CancelledTouchEvent : public MirroredTouchEvent {
// Touches which are cancelled by a touch capture are routed to a
// GestureEventIgnorer, which ignores them.
-class GestureConsumerIgnorer : public ui::GestureConsumer {
+class GestureConsumerIgnorer : public GestureConsumer {
public:
GestureConsumerIgnorer()
: GestureConsumer(true) {
}
};
-} // namespace
+template <typename T>
+void TransferConsumer(GestureConsumer* current_consumer,
+ GestureConsumer* new_consumer,
+ std::map<GestureConsumer*, T>* map) {
+ if (map->count(current_consumer)) {
+ (*map)[new_consumer] = (*map)[current_consumer];
+ map->erase(current_consumer);
+ }
+}
-namespace ui {
+void RemoveConsumerFromMap(GestureConsumer* consumer,
+ GestureRecognizerImpl::TouchIdToConsumerMap* map) {
+ for (GestureRecognizerImpl::TouchIdToConsumerMap::iterator i = map->begin();
+ i != map->end();) {
+ if (i->second == consumer)
+ map->erase(i++);
+ else
+ ++i;
+ }
+}
+
+void TransferTouchIdToConsumerMap(
+ GestureConsumer* old_consumer,
+ GestureConsumer* new_consumer,
+ GestureRecognizerImpl::TouchIdToConsumerMap* map) {
+ for (GestureRecognizerImpl::TouchIdToConsumerMap::iterator i = map->begin();
+ i != map->end(); ++i) {
+ if (i->second == old_consumer)
+ i->second = new_consumer;
+ }
+}
+
+} // namespace
////////////////////////////////////////////////////////////////////////////////
// GestureRecognizerImpl, public:
@@ -139,6 +172,8 @@ GestureRecognizerImpl::GestureRecognizerImpl(GestureEventHelper* helper)
GestureRecognizerImpl::~GestureRecognizerImpl() {
}
+// Checks if this finger is already down, if so, returns the current target.
+// Otherwise, returns NULL.
GestureConsumer* GestureRecognizerImpl::GetTouchLockedTarget(
TouchEvent* event) {
return touch_id_target_[event->GetTouchId()];
@@ -181,21 +216,33 @@ GestureConsumer* GestureRecognizerImpl::GetTargetForLocation(
return NULL;
}
-void GestureRecognizerImpl::CancelNonCapturedTouches(
- GestureConsumer* capturer) {
- std::map<int, GestureConsumer*>::iterator i;
- // Fire touch cancels, and target touch_ids to gesture_consumer_ignorer.
- for (i = touch_id_target_.begin(); i != touch_id_target_.end(); ++i) {
- if (capturer != i->second &&
- touch_id_target_[i->first] != gesture_consumer_ignorer_.get()) {
+void GestureRecognizerImpl::TransferEventsTo(GestureConsumer* current_consumer,
+ GestureConsumer* new_consumer) {
+ // Send cancel to all those save |new_consumer| and |current_consumer|.
+ // Don't send a cancel to |current_consumer|, unless |new_consumer| is NULL.
+ for (TouchIdToConsumerMap::iterator i = touch_id_target_.begin();
+ i != touch_id_target_.end(); ++i) {
+ if (i->second != new_consumer &&
+ (i->second != current_consumer || new_consumer == NULL) &&
+ i->second != gesture_consumer_ignorer_.get()) {
scoped_ptr<TouchEvent> touch_event(helper_->CreateTouchEvent(
ui::ET_TOUCH_CANCELLED, gfx::Point(0, 0),
i->first,
base::Time::NowFromSystemTime() - base::Time()));
helper_->DispatchCancelTouchEvent(touch_event.get());
- touch_id_target_[i->first] = gesture_consumer_ignorer_.get();
+ i->second = gesture_consumer_ignorer_.get();
}
}
+
+ // Transer events from |current_consumer| to |new_consumer|.
+ if (current_consumer && new_consumer) {
+ TransferTouchIdToConsumerMap(current_consumer, new_consumer,
+ &touch_id_target_);
+ TransferTouchIdToConsumerMap(current_consumer, new_consumer,
+ &touch_id_target_for_gestures_);
+ TransferConsumer(current_consumer, new_consumer, &event_queue_);
+ TransferConsumer(current_consumer, new_consumer, &consumer_sequence_);
+ }
}
////////////////////////////////////////////////////////////////////////////////
@@ -280,25 +327,8 @@ void GestureRecognizerImpl::FlushTouchQueue(GestureConsumer* consumer) {
event_queue_.erase(consumer);
}
- int touch_id = -1;
- std::map<int, GestureConsumer*>::iterator i;
- for (i = touch_id_target_.begin(); i != touch_id_target_.end(); ++i) {
- if (i->second == consumer)
- touch_id = i->first;
- }
-
- if (touch_id_target_.count(touch_id))
- touch_id_target_.erase(touch_id);
-
- for (i = touch_id_target_for_gestures_.begin();
- i != touch_id_target_for_gestures_.end();
- ++i) {
- if (i->second == consumer)
- touch_id = i->first;
- }
-
- if (touch_id_target_for_gestures_.count(touch_id))
- touch_id_target_for_gestures_.erase(touch_id);
+ RemoveConsumerFromMap(consumer, &touch_id_target_);
+ RemoveConsumerFromMap(consumer, &touch_id_target_for_gestures_);
}
// GestureRecognizer, static
diff --git a/ui/base/gestures/gesture_recognizer_impl.h b/ui/base/gestures/gesture_recognizer_impl.h
index 9c659eb..18030b7 100644
--- a/ui/base/gestures/gesture_recognizer_impl.h
+++ b/ui/base/gestures/gesture_recognizer_impl.h
@@ -18,32 +18,27 @@
#include "ui/gfx/point.h"
namespace ui {
-class TouchEvent;
-class GestureEvent;
-class GestureSequence;
class GestureConsumer;
+class GestureEvent;
class GestureEventHelper;
+class GestureSequence;
+class TouchEvent;
class UI_EXPORT GestureRecognizerImpl : public GestureRecognizer {
public:
+ typedef std::map<int, GestureConsumer*> TouchIdToConsumerMap;
+
explicit GestureRecognizerImpl(GestureEventHelper* helper);
virtual ~GestureRecognizerImpl();
- // Checks if this finger is already down, if so, returns the current target.
- // Otherwise, returns NULL.
+ // Overridden from GestureRecognizer
virtual GestureConsumer* GetTouchLockedTarget(TouchEvent* event) OVERRIDE;
-
- // Returns the target of the touches the gesture is composed of.
virtual GestureConsumer* GetTargetForGestureEvent(
GestureEvent* event) OVERRIDE;
-
virtual GestureConsumer* GetTargetForLocation(
const gfx::Point& location) OVERRIDE;
-
- // Each touch which isn't targeted to capturer results in a touch
- // cancel event. These touches are then targeted to
- // gesture_consumer_ignorer.
- virtual void CancelNonCapturedTouches(GestureConsumer* capturer) OVERRIDE;
+ virtual void TransferEventsTo(GestureConsumer* current_consumer,
+ GestureConsumer* new_consumer) OVERRIDE;
protected:
virtual GestureSequence* CreateSequence(GestureEventHelper* helper);
@@ -65,13 +60,12 @@ class UI_EXPORT GestureRecognizerImpl : public GestureRecognizer {
std::map<GestureConsumer*, TouchEventQueue*> event_queue_;
std::map<GestureConsumer*, GestureSequence*> consumer_sequence_;
- // Both touch_id_target_ and touch_id_target_for_gestures_
- // map a touch-id to its target window.
- // touch_ids are removed from touch_id_target_ on ET_TOUCH_RELEASE
- // and ET_TOUCH_CANCEL. touch_id_target_for_gestures_ never has touch_ids
- // removed.
- std::map<int, GestureConsumer*> touch_id_target_;
- std::map<int, GestureConsumer*> touch_id_target_for_gestures_;
+ // Both |touch_id_target_| and |touch_id_target_for_gestures_| map a touch-id
+ // to its target window. touch-ids are removed from |touch_id_target_| on
+ // ET_TOUCH_RELEASE and ET_TOUCH_CANCEL. |touch_id_target_for_gestures_| are
+ // removed in FlushTouchQueue().
+ TouchIdToConsumerMap touch_id_target_;
+ TouchIdToConsumerMap touch_id_target_for_gestures_;
// Touches cancelled by touch capture are routed to the
// gesture_consumer_ignorer_.