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