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