Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / ui / events / event.h
1 // Copyright (c) 2012 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 #ifndef UI_EVENTS_EVENT_H_
6 #define UI_EVENTS_EVENT_H_
7
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/event_types.h"
11 #include "base/logging.h"
12 #include "base/time/time.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/events/gestures/gesture_types.h"
15 #include "ui/events/keycodes/keyboard_codes.h"
16 #include "ui/events/latency_info.h"
17 #include "ui/gfx/point.h"
18 #include "ui/gfx/point_conversions.h"
19
20 namespace gfx {
21 class Transform;
22 }
23
24 namespace ui {
25 class EventTarget;
26
27 class EVENTS_EXPORT Event {
28  public:
29   virtual ~Event();
30
31   class DispatcherApi {
32    public:
33     explicit DispatcherApi(Event* event) : event_(event) {}
34
35     void set_target(EventTarget* target) {
36       event_->target_ = target;
37     }
38
39     void set_phase(EventPhase phase) { event_->phase_ = phase; }
40     void set_result(int result) {
41       event_->result_ = static_cast<EventResult>(result);
42     }
43
44    private:
45     DispatcherApi();
46     Event* event_;
47
48     DISALLOW_COPY_AND_ASSIGN(DispatcherApi);
49   };
50
51   const base::NativeEvent& native_event() const { return native_event_; }
52   EventType type() const { return type_; }
53   const std::string& name() const { return name_; }
54   // time_stamp represents time since machine was booted.
55   const base::TimeDelta& time_stamp() const { return time_stamp_; }
56   int flags() const { return flags_; }
57
58   // This is only intended to be used externally by classes that are modifying
59   // events in EventFilter::PreHandleKeyEvent().
60   void set_flags(int flags) { flags_ = flags; }
61
62   EventTarget* target() const { return target_; }
63   EventPhase phase() const { return phase_; }
64   EventResult result() const { return result_; }
65
66   LatencyInfo* latency() { return &latency_; }
67   const LatencyInfo* latency() const { return &latency_; }
68   void set_latency(const LatencyInfo& latency) { latency_ = latency; }
69
70   // By default, events are "cancelable", this means any default processing that
71   // the containing abstraction layer may perform can be prevented by calling
72   // SetHandled(). SetHandled() or StopPropagation() must not be called for
73   // events that are not cancelable.
74   bool cancelable() const { return cancelable_; }
75
76   // The following methods return true if the respective keys were pressed at
77   // the time the event was created.
78   bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
79   bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
80   bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
81   bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
82   bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
83
84   bool IsKeyEvent() const {
85     return type_ == ET_KEY_PRESSED ||
86            type_ == ET_KEY_RELEASED ||
87            type_ == ET_TRANSLATED_KEY_PRESS ||
88            type_ == ET_TRANSLATED_KEY_RELEASE;
89   }
90
91   bool IsMouseEvent() const {
92     return type_ == ET_MOUSE_PRESSED ||
93            type_ == ET_MOUSE_DRAGGED ||
94            type_ == ET_MOUSE_RELEASED ||
95            type_ == ET_MOUSE_MOVED ||
96            type_ == ET_MOUSE_ENTERED ||
97            type_ == ET_MOUSE_EXITED ||
98            type_ == ET_MOUSEWHEEL ||
99            type_ == ET_MOUSE_CAPTURE_CHANGED;
100   }
101
102   bool IsTouchEvent() const {
103     return type_ == ET_TOUCH_RELEASED ||
104            type_ == ET_TOUCH_PRESSED ||
105            type_ == ET_TOUCH_MOVED ||
106            type_ == ET_TOUCH_STATIONARY ||
107            type_ == ET_TOUCH_CANCELLED;
108   }
109
110   bool IsGestureEvent() const {
111     switch (type_) {
112       case ET_GESTURE_SCROLL_BEGIN:
113       case ET_GESTURE_SCROLL_END:
114       case ET_GESTURE_SCROLL_UPDATE:
115       case ET_GESTURE_TAP:
116       case ET_GESTURE_TAP_CANCEL:
117       case ET_GESTURE_TAP_DOWN:
118       case ET_GESTURE_BEGIN:
119       case ET_GESTURE_END:
120       case ET_GESTURE_TWO_FINGER_TAP:
121       case ET_GESTURE_PINCH_BEGIN:
122       case ET_GESTURE_PINCH_END:
123       case ET_GESTURE_PINCH_UPDATE:
124       case ET_GESTURE_LONG_PRESS:
125       case ET_GESTURE_LONG_TAP:
126       case ET_GESTURE_MULTIFINGER_SWIPE:
127       case ET_GESTURE_SHOW_PRESS:
128         // When adding a gesture event which is paired with an event which
129         // occurs earlier, add the event to |IsEndingEvent|.
130         return true;
131
132       case ET_SCROLL_FLING_CANCEL:
133       case ET_SCROLL_FLING_START:
134         // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
135         // Gesture or Scroll events.
136         return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;
137
138       default:
139         break;
140     }
141     return false;
142   }
143
144   // An ending event is paired with the event which started it. Setting capture
145   // should not prevent ending events from getting to their initial target.
146   bool IsEndingEvent() const {
147     switch(type_) {
148       case ui::ET_TOUCH_CANCELLED:
149       case ui::ET_GESTURE_TAP_CANCEL:
150       case ui::ET_GESTURE_END:
151       case ui::ET_GESTURE_SCROLL_END:
152       case ui::ET_GESTURE_PINCH_END:
153         return true;
154       default:
155         return false;
156     }
157   }
158
159   bool IsScrollEvent() const {
160     // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
161     // Gesture or Scroll events.
162     return type_ == ET_SCROLL ||
163            ((type_ == ET_SCROLL_FLING_START ||
164            type_ == ET_SCROLL_FLING_CANCEL) &&
165            !(flags() & EF_FROM_TOUCH));
166   }
167
168   bool IsScrollGestureEvent() const {
169     return type_ == ET_GESTURE_SCROLL_BEGIN ||
170            type_ == ET_GESTURE_SCROLL_UPDATE ||
171            type_ == ET_GESTURE_SCROLL_END;
172   }
173
174   bool IsFlingScrollEvent() const {
175     return type_ == ET_SCROLL_FLING_CANCEL ||
176            type_ == ET_SCROLL_FLING_START;
177   }
178
179   bool IsMouseWheelEvent() const {
180     return type_ == ET_MOUSEWHEEL;
181   }
182
183   // Returns true if the event has a valid |native_event_|.
184   bool HasNativeEvent() const;
185
186   // Immediately stops the propagation of the event. This must be called only
187   // from an EventHandler during an event-dispatch. Any event handler that may
188   // be in the list will not receive the event after this is called.
189   // Note that StopPropagation() can be called only for cancelable events.
190   void StopPropagation();
191   bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }
192
193   // Marks the event as having been handled. A handled event does not reach the
194   // next event phase. For example, if an event is handled during the pre-target
195   // phase, then the event is dispatched to all pre-target handlers, but not to
196   // the target or post-target handlers.
197   // Note that SetHandled() can be called only for cancelable events.
198   void SetHandled();
199   bool handled() const { return result_ != ER_UNHANDLED; }
200
201  protected:
202   Event(EventType type, base::TimeDelta time_stamp, int flags);
203   Event(const base::NativeEvent& native_event, EventType type, int flags);
204   Event(const Event& copy);
205   void SetType(EventType type);
206   void set_delete_native_event(bool delete_native_event) {
207     delete_native_event_ = delete_native_event;
208   }
209   void set_cancelable(bool cancelable) { cancelable_ = cancelable; }
210
211   void set_time_stamp(const base::TimeDelta& time_stamp) {
212     time_stamp_ = time_stamp;
213   }
214
215   void set_name(const std::string& name) { name_ = name; }
216
217  private:
218   friend class EventTestApi;
219
220   // Safely initializes the native event members of this class.
221   void Init();
222   void InitWithNativeEvent(const base::NativeEvent& native_event);
223
224   EventType type_;
225   std::string name_;
226   base::TimeDelta time_stamp_;
227   LatencyInfo latency_;
228   int flags_;
229   base::NativeEvent native_event_;
230   bool delete_native_event_;
231   bool cancelable_;
232   EventTarget* target_;
233   EventPhase phase_;
234   EventResult result_;
235 };
236
237 class EVENTS_EXPORT CancelModeEvent : public Event {
238  public:
239   CancelModeEvent();
240   virtual ~CancelModeEvent();
241 };
242
243 class EVENTS_EXPORT LocatedEvent : public Event {
244  public:
245   virtual ~LocatedEvent();
246
247   float x() const { return location_.x(); }
248   float y() const { return location_.y(); }
249   void set_location(const gfx::PointF& location) { location_ = location; }
250   // TODO(tdresser): Always return floating point location. See
251   // crbug.com/337824.
252   gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
253   gfx::PointF location_f() const { return location_; }
254   void set_root_location(const gfx::PointF& root_location) {
255     root_location_ = root_location;
256   }
257   gfx::Point root_location() const {
258     return gfx::ToFlooredPoint(root_location_);
259   }
260
261   // Transform the locations using |inverted_root_transform|.
262   // This is applied to both |location_| and |root_location_|.
263   virtual void UpdateForRootTransform(
264       const gfx::Transform& inverted_root_transform);
265
266   template <class T> void ConvertLocationToTarget(T* source, T* target) {
267     if (!target || target == source)
268       return;
269     // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See
270     // crbug.com/337824.
271     gfx::Point offset = gfx::ToFlooredPoint(location_);
272     T::ConvertPointToTarget(source, target, &offset);
273     gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset;
274     location_= location_ - diff;
275   }
276
277  protected:
278   friend class LocatedEventTestApi;
279   explicit LocatedEvent(const base::NativeEvent& native_event);
280
281   // Create a new LocatedEvent which is identical to the provided model.
282   // If source / target windows are provided, the model location will be
283   // converted from |source| coordinate system to |target| coordinate system.
284   template <class T>
285   LocatedEvent(const LocatedEvent& model, T* source, T* target)
286       : Event(model),
287         location_(model.location_),
288         root_location_(model.root_location_) {
289     ConvertLocationToTarget(source, target);
290   }
291
292   // Used for synthetic events in testing.
293   LocatedEvent(EventType type,
294                const gfx::PointF& location,
295                const gfx::PointF& root_location,
296                base::TimeDelta time_stamp,
297                int flags);
298
299   gfx::PointF location_;
300
301   // |location_| multiplied by an optional transformation matrix for
302   // rotations, animations and skews.
303   gfx::PointF root_location_;
304 };
305
306 class EVENTS_EXPORT MouseEvent : public LocatedEvent {
307  public:
308   explicit MouseEvent(const base::NativeEvent& native_event);
309
310   // Create a new MouseEvent based on the provided model.
311   // Uses the provided |type| and |flags| for the new event.
312   // If source / target windows are provided, the model location will be
313   // converted from |source| coordinate system to |target| coordinate system.
314   template <class T>
315   MouseEvent(const MouseEvent& model, T* source, T* target)
316       : LocatedEvent(model, source, target),
317         changed_button_flags_(model.changed_button_flags_) {
318   }
319
320   template <class T>
321   MouseEvent(const MouseEvent& model,
322              T* source,
323              T* target,
324              EventType type,
325              int flags)
326       : LocatedEvent(model, source, target),
327         changed_button_flags_(model.changed_button_flags_) {
328     SetType(type);
329     set_flags(flags);
330   }
331
332   // Used for synthetic events in testing and by the gesture recognizer.
333   MouseEvent(EventType type,
334              const gfx::PointF& location,
335              const gfx::PointF& root_location,
336              int flags,
337              int changed_button_flags);
338
339   // Conveniences to quickly test what button is down
340   bool IsOnlyLeftMouseButton() const {
341     return (flags() & EF_LEFT_MOUSE_BUTTON) &&
342       !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
343   }
344
345   bool IsLeftMouseButton() const {
346     return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
347   }
348
349   bool IsOnlyMiddleMouseButton() const {
350     return (flags() & EF_MIDDLE_MOUSE_BUTTON) &&
351       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
352   }
353
354   bool IsMiddleMouseButton() const {
355     return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
356   }
357
358   bool IsOnlyRightMouseButton() const {
359     return (flags() & EF_RIGHT_MOUSE_BUTTON) &&
360       !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON));
361   }
362
363   bool IsRightMouseButton() const {
364     return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
365   }
366
367   bool IsAnyButton() const {
368     return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
369                        EF_RIGHT_MOUSE_BUTTON)) != 0;
370   }
371
372   // Compares two mouse down events and returns true if the second one should
373   // be considered a repeat of the first.
374   static bool IsRepeatedClickEvent(
375       const MouseEvent& event1,
376       const MouseEvent& event2);
377
378   // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
379   int GetClickCount() const;
380
381   // Set the click count for a mousedown message. Can be 1, 2 or 3.
382   void SetClickCount(int click_count);
383
384   // Identifies the button that changed. During a press this corresponds to the
385   // button that was pressed and during a release this corresponds to the button
386   // that was released.
387   // NOTE: during a press and release flags() contains the complete set of
388   // flags. Use this to determine the button that was pressed or released.
389   int changed_button_flags() const { return changed_button_flags_; }
390
391  private:
392   // Returns the repeat count based on the previous mouse click, if it is
393   // recent enough and within a small enough distance.
394   static int GetRepeatCount(const MouseEvent& click_event);
395
396   // See description above getter for details.
397   int changed_button_flags_;
398
399   static MouseEvent* last_click_event_;
400 };
401
402 class ScrollEvent;
403
404 class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
405  public:
406   // See |offset| for details.
407   static const int kWheelDelta;
408
409   explicit MouseWheelEvent(const base::NativeEvent& native_event);
410   explicit MouseWheelEvent(const ScrollEvent& scroll_event);
411   MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
412   MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event);
413
414   template <class T>
415   MouseWheelEvent(const MouseWheelEvent& model,
416                   T* source,
417                   T* target,
418                   EventType type,
419                   int flags)
420       : MouseEvent(model, source, target, type, flags),
421         offset_(model.x_offset(), model.y_offset()){
422   }
423
424   // The amount to scroll. This is in multiples of kWheelDelta.
425   // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
426   int x_offset() const { return offset_.x(); }
427   int y_offset() const { return offset_.y(); }
428   const gfx::Vector2d& offset() const { return offset_; }
429
430   // Overridden from LocatedEvent.
431   virtual void UpdateForRootTransform(
432       const gfx::Transform& inverted_root_transform) OVERRIDE;
433
434  private:
435   gfx::Vector2d offset_;
436 };
437
438 class EVENTS_EXPORT TouchEvent : public LocatedEvent {
439  public:
440   explicit TouchEvent(const base::NativeEvent& native_event);
441
442   // Create a new TouchEvent which is identical to the provided model.
443   // If source / target windows are provided, the model location will be
444   // converted from |source| coordinate system to |target| coordinate system.
445   template <class T>
446   TouchEvent(const TouchEvent& model, T* source, T* target)
447       : LocatedEvent(model, source, target),
448         touch_id_(model.touch_id_),
449         radius_x_(model.radius_x_),
450         radius_y_(model.radius_y_),
451         rotation_angle_(model.rotation_angle_),
452         force_(model.force_),
453         source_device_id_(model.source_device_id_) {
454   }
455
456   TouchEvent(EventType type,
457              const gfx::PointF& location,
458              int touch_id,
459              base::TimeDelta time_stamp);
460
461   TouchEvent(EventType type,
462              const gfx::PointF& location,
463              int flags,
464              int touch_id,
465              base::TimeDelta timestamp,
466              float radius_x,
467              float radius_y,
468              float angle,
469              float force);
470
471   virtual ~TouchEvent();
472
473   int touch_id() const { return touch_id_; }
474   float radius_x() const { return radius_x_; }
475   float radius_y() const { return radius_y_; }
476   float rotation_angle() const { return rotation_angle_; }
477   float force() const { return force_; }
478   int source_device_id() const { return source_device_id_; }
479
480   // Relocate the touch-point to a new |origin|.
481   // This is useful when touch event is in X Root Window coordinates,
482   // and it needs to be mapped into Aura Root Window coordinates.
483   void Relocate(const gfx::Point& origin);
484
485   // Used for unit tests.
486   void set_radius_x(const float r) { radius_x_ = r; }
487   void set_radius_y(const float r) { radius_y_ = r; }
488   void set_source_device_id(int source_device_id) {
489     source_device_id_ = source_device_id;
490   }
491
492   // Overridden from LocatedEvent.
493   virtual void UpdateForRootTransform(
494       const gfx::Transform& inverted_root_transform) OVERRIDE;
495
496  protected:
497   void set_radius(float radius_x, float radius_y) {
498     radius_x_ = radius_x;
499     radius_y_ = radius_y;
500   }
501
502   void set_rotation_angle(float rotation_angle) {
503     rotation_angle_ = rotation_angle;
504   }
505
506   void set_force(float force) { force_ = force; }
507
508  private:
509   // The identity (typically finger) of the touch starting at 0 and incrementing
510   // for each separable additional touch that the hardware can detect.
511   const int touch_id_;
512
513   // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
514   float radius_x_;
515
516   // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
517   float radius_y_;
518
519   // Angle of the major axis away from the X axis. Default 0.0.
520   float rotation_angle_;
521
522   // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
523   float force_;
524
525   // The device id of the screen the event came from. Default to be -1.
526   int source_device_id_;
527 };
528
529 class EVENTS_EXPORT KeyEvent : public Event {
530  public:
531   KeyEvent(const base::NativeEvent& native_event, bool is_char);
532
533   // Used for synthetic events.
534   KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char);
535
536   // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
537   // See also: ui/events/keycodes/dom4/keycode_converter_data.h
538   KeyEvent(EventType type, KeyboardCode key_code, const std::string& code,
539            int flags, bool is_char);
540
541   // This allows an I18N virtual keyboard to fabricate a keyboard event that
542   // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
543   // letter A with acute, U+0410 Cyrillic capital letter A).
544   void set_character(uint16 character) { character_ = character; }
545
546   // Gets the character generated by this key event. It only supports Unicode
547   // BMP characters.
548   uint16 GetCharacter() const;
549
550   KeyboardCode key_code() const { return key_code_; }
551   bool is_char() const { return is_char_; }
552
553   // This is only intended to be used externally by classes that are modifying
554   // events in EventFilter::PreHandleKeyEvent().  set_character() should also be
555   // called.
556   void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
557
558   // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
559   // TODO(msw): Additional work may be needed for analogues on other platforms.
560   bool IsUnicodeKeyCode() const;
561
562   std::string code() const { return code_; }
563
564   // Normalizes flags_ to make it Windows/Mac compatible. Since the way
565   // of setting modifier mask on X is very different than Windows/Mac as shown
566   // in http://crbug.com/127142#c8, the normalization is necessary.
567   void NormalizeFlags();
568
569  private:
570   KeyboardCode key_code_;
571
572   // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
573   // http://www.w3.org/TR/uievents/#keyboard-key-codes.
574   //
575   // This value represents the physical position in the keyboard and can be
576   // converted from / to keyboard scan code like XKB.
577   std::string code_;
578
579   // True if this is a translated character event (vs. a raw key down). Both
580   // share the same type: ET_KEY_PRESSED.
581   bool is_char_;
582
583   uint16 character_;
584 };
585
586 // A key event which is translated by an input method (IME).
587 // For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not
588 // consume the key, the IME usually generates and dispatches a
589 // TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and
590 // it does consume the event, it might dispatch a
591 // TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec.
592 class EVENTS_EXPORT TranslatedKeyEvent : public KeyEvent {
593  public:
594   TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char);
595
596   // Used for synthetic events such as a VKEY_PROCESSKEY key event.
597   TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags);
598
599   // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so
600   // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event.
601   void ConvertToKeyEvent();
602
603  private:
604   DISALLOW_COPY_AND_ASSIGN(TranslatedKeyEvent);
605 };
606
607 class EVENTS_EXPORT ScrollEvent : public MouseEvent {
608  public:
609   explicit ScrollEvent(const base::NativeEvent& native_event);
610   template <class T>
611   ScrollEvent(const ScrollEvent& model,
612               T* source,
613               T* target)
614       : MouseEvent(model, source, target),
615         x_offset_(model.x_offset_),
616         y_offset_(model.y_offset_),
617         x_offset_ordinal_(model.x_offset_ordinal_),
618         y_offset_ordinal_(model.y_offset_ordinal_),
619         finger_count_(model.finger_count_){
620   }
621
622   // Used for tests.
623   ScrollEvent(EventType type,
624               const gfx::PointF& location,
625               base::TimeDelta time_stamp,
626               int flags,
627               float x_offset,
628               float y_offset,
629               float x_offset_ordinal,
630               float y_offset_ordinal,
631               int finger_count);
632
633   // Scale the scroll event's offset value.
634   // This is useful in the multi-monitor setup where it needs to be scaled
635   // to provide a consistent user experience.
636   void Scale(const float factor);
637
638   float x_offset() const { return x_offset_; }
639   float y_offset() const { return y_offset_; }
640   float x_offset_ordinal() const { return x_offset_ordinal_; }
641   float y_offset_ordinal() const { return y_offset_ordinal_; }
642   int finger_count() const { return finger_count_; }
643
644  private:
645   // Potential accelerated offsets.
646   float x_offset_;
647   float y_offset_;
648   // Unaccelerated offsets.
649   float x_offset_ordinal_;
650   float y_offset_ordinal_;
651   // Number of fingers on the pad.
652   int finger_count_;
653 };
654
655 class EVENTS_EXPORT GestureEvent : public LocatedEvent {
656  public:
657   GestureEvent(EventType type,
658                float x,
659                float y,
660                int flags,
661                base::TimeDelta time_stamp,
662                const GestureEventDetails& details,
663                unsigned int touch_ids_bitfield);
664
665   // Create a new GestureEvent which is identical to the provided model.
666   // If source / target windows are provided, the model location will be
667   // converted from |source| coordinate system to |target| coordinate system.
668   template <typename T>
669   GestureEvent(const GestureEvent& model, T* source, T* target)
670       : LocatedEvent(model, source, target),
671         details_(model.details_),
672         touch_ids_bitfield_(model.touch_ids_bitfield_) {
673   }
674
675   virtual ~GestureEvent();
676
677   const GestureEventDetails& details() const { return details_; }
678
679   // Returns the lowest touch-id of any of the touches which make up this
680   // gesture. If there are no touches associated with this gesture, returns -1.
681   int GetLowestTouchId() const;
682
683  private:
684   GestureEventDetails details_;
685
686   // The set of indices of ones in the binary representation of
687   // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
688   // This value is stored as a bitfield because the number of touch ids varies,
689   // but we currently don't need more than 32 touches at a time.
690   const unsigned int touch_ids_bitfield_;
691 };
692
693 }  // namespace ui
694
695 #endif  // UI_EVENTS_EVENT_H_