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