| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef UI_EVENTS_EVENT_H_ |
| #define UI_EVENTS_EVENT_H_ |
| |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| #include "base/event_types.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/logging.h" |
| #include "base/time/time.h" |
| #include "ui/events/event_constants.h" |
| #include "ui/events/gesture_event_details.h" |
| #include "ui/events/gestures/gesture_types.h" |
| #include "ui/events/keycodes/keyboard_codes.h" |
| #include "ui/events/latency_info.h" |
| #include "ui/gfx/point.h" |
| #include "ui/gfx/point_conversions.h" |
| |
| namespace gfx { |
| class Transform; |
| } |
| |
| namespace ui { |
| class EventTarget; |
| |
| class EVENTS_EXPORT Event { |
| public: |
| virtual ~Event(); |
| |
| class DispatcherApi { |
| public: |
| explicit DispatcherApi(Event* event) : event_(event) {} |
| |
| void set_target(EventTarget* target) { |
| event_->target_ = target; |
| } |
| |
| void set_phase(EventPhase phase) { event_->phase_ = phase; } |
| void set_result(int result) { |
| event_->result_ = static_cast<EventResult>(result); |
| } |
| |
| private: |
| DispatcherApi(); |
| Event* event_; |
| |
| DISALLOW_COPY_AND_ASSIGN(DispatcherApi); |
| }; |
| |
| const base::NativeEvent& native_event() const { return native_event_; } |
| EventType type() const { return type_; } |
| const std::string& name() const { return name_; } |
| // time_stamp represents time since machine was booted. |
| const base::TimeDelta& time_stamp() const { return time_stamp_; } |
| int flags() const { return flags_; } |
| |
| // This is only intended to be used externally by classes that are modifying |
| // events in EventFilter::PreHandleKeyEvent(). |
| void set_flags(int flags) { flags_ = flags; } |
| |
| EventTarget* target() const { return target_; } |
| EventPhase phase() const { return phase_; } |
| EventResult result() const { return result_; } |
| |
| LatencyInfo* latency() { return &latency_; } |
| const LatencyInfo* latency() const { return &latency_; } |
| void set_latency(const LatencyInfo& latency) { latency_ = latency; } |
| |
| // By default, events are "cancelable", this means any default processing that |
| // the containing abstraction layer may perform can be prevented by calling |
| // SetHandled(). SetHandled() or StopPropagation() must not be called for |
| // events that are not cancelable. |
| bool cancelable() const { return cancelable_; } |
| |
| // The following methods return true if the respective keys were pressed at |
| // the time the event was created. |
| bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; } |
| bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; } |
| bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; } |
| bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; } |
| bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; } |
| bool IsRepeat() const { return (flags_ & EF_IS_REPEAT) != 0; } |
| |
| bool IsKeyEvent() const { |
| return type_ == ET_KEY_PRESSED || |
| type_ == ET_KEY_RELEASED || |
| type_ == ET_TRANSLATED_KEY_PRESS || |
| type_ == ET_TRANSLATED_KEY_RELEASE; |
| } |
| |
| bool IsMouseEvent() const { |
| return type_ == ET_MOUSE_PRESSED || |
| type_ == ET_MOUSE_DRAGGED || |
| type_ == ET_MOUSE_RELEASED || |
| type_ == ET_MOUSE_MOVED || |
| type_ == ET_MOUSE_ENTERED || |
| type_ == ET_MOUSE_EXITED || |
| type_ == ET_MOUSEWHEEL || |
| type_ == ET_MOUSE_CAPTURE_CHANGED; |
| } |
| |
| bool IsTouchEvent() const { |
| return type_ == ET_TOUCH_RELEASED || |
| type_ == ET_TOUCH_PRESSED || |
| type_ == ET_TOUCH_MOVED || |
| type_ == ET_TOUCH_CANCELLED; |
| } |
| |
| bool IsGestureEvent() const { |
| switch (type_) { |
| case ET_GESTURE_SCROLL_BEGIN: |
| case ET_GESTURE_SCROLL_END: |
| case ET_GESTURE_SCROLL_UPDATE: |
| case ET_GESTURE_TAP: |
| case ET_GESTURE_TAP_CANCEL: |
| case ET_GESTURE_TAP_DOWN: |
| case ET_GESTURE_BEGIN: |
| case ET_GESTURE_END: |
| case ET_GESTURE_TWO_FINGER_TAP: |
| case ET_GESTURE_PINCH_BEGIN: |
| case ET_GESTURE_PINCH_END: |
| case ET_GESTURE_PINCH_UPDATE: |
| case ET_GESTURE_LONG_PRESS: |
| case ET_GESTURE_LONG_TAP: |
| case ET_GESTURE_SWIPE: |
| case ET_GESTURE_SHOW_PRESS: |
| case ET_GESTURE_WIN8_EDGE_SWIPE: |
| // When adding a gesture event which is paired with an event which |
| // occurs earlier, add the event to |IsEndingEvent|. |
| return true; |
| |
| case ET_SCROLL_FLING_CANCEL: |
| case ET_SCROLL_FLING_START: |
| // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're |
| // Gesture or Scroll events. |
| return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH; |
| |
| default: |
| break; |
| } |
| return false; |
| } |
| |
| // An ending event is paired with the event which started it. Setting capture |
| // should not prevent ending events from getting to their initial target. |
| bool IsEndingEvent() const { |
| switch(type_) { |
| case ui::ET_TOUCH_CANCELLED: |
| case ui::ET_GESTURE_TAP_CANCEL: |
| case ui::ET_GESTURE_END: |
| case ui::ET_GESTURE_SCROLL_END: |
| case ui::ET_GESTURE_PINCH_END: |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| bool IsScrollEvent() const { |
| // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're |
| // Gesture or Scroll events. |
| return type_ == ET_SCROLL || |
| ((type_ == ET_SCROLL_FLING_START || |
| type_ == ET_SCROLL_FLING_CANCEL) && |
| !(flags() & EF_FROM_TOUCH)); |
| } |
| |
| bool IsScrollGestureEvent() const { |
| return type_ == ET_GESTURE_SCROLL_BEGIN || |
| type_ == ET_GESTURE_SCROLL_UPDATE || |
| type_ == ET_GESTURE_SCROLL_END; |
| } |
| |
| bool IsFlingScrollEvent() const { |
| return type_ == ET_SCROLL_FLING_CANCEL || |
| type_ == ET_SCROLL_FLING_START; |
| } |
| |
| bool IsMouseWheelEvent() const { |
| return type_ == ET_MOUSEWHEEL; |
| } |
| |
| // Returns true if the event has a valid |native_event_|. |
| bool HasNativeEvent() const; |
| |
| // Immediately stops the propagation of the event. This must be called only |
| // from an EventHandler during an event-dispatch. Any event handler that may |
| // be in the list will not receive the event after this is called. |
| // Note that StopPropagation() can be called only for cancelable events. |
| void StopPropagation(); |
| bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); } |
| |
| // Marks the event as having been handled. A handled event does not reach the |
| // next event phase. For example, if an event is handled during the pre-target |
| // phase, then the event is dispatched to all pre-target handlers, but not to |
| // the target or post-target handlers. |
| // Note that SetHandled() can be called only for cancelable events. |
| void SetHandled(); |
| bool handled() const { return result_ != ER_UNHANDLED; } |
| |
| protected: |
| Event(EventType type, base::TimeDelta time_stamp, int flags); |
| Event(const base::NativeEvent& native_event, EventType type, int flags); |
| Event(const Event& copy); |
| void SetType(EventType type); |
| void set_delete_native_event(bool delete_native_event) { |
| delete_native_event_ = delete_native_event; |
| } |
| void set_cancelable(bool cancelable) { cancelable_ = cancelable; } |
| |
| void set_time_stamp(const base::TimeDelta& time_stamp) { |
| time_stamp_ = time_stamp; |
| } |
| |
| void set_name(const std::string& name) { name_ = name; } |
| |
| private: |
| friend class EventTestApi; |
| |
| EventType type_; |
| std::string name_; |
| base::TimeDelta time_stamp_; |
| LatencyInfo latency_; |
| int flags_; |
| base::NativeEvent native_event_; |
| bool delete_native_event_; |
| bool cancelable_; |
| EventTarget* target_; |
| EventPhase phase_; |
| EventResult result_; |
| }; |
| |
| class EVENTS_EXPORT CancelModeEvent : public Event { |
| public: |
| CancelModeEvent(); |
| virtual ~CancelModeEvent(); |
| }; |
| |
| class EVENTS_EXPORT LocatedEvent : public Event { |
| public: |
| virtual ~LocatedEvent(); |
| |
| float x() const { return location_.x(); } |
| float y() const { return location_.y(); } |
| void set_location(const gfx::PointF& location) { location_ = location; } |
| // TODO(tdresser): Always return floating point location. See |
| // crbug.com/337824. |
| gfx::Point location() const { return gfx::ToFlooredPoint(location_); } |
| const gfx::PointF& location_f() const { return location_; } |
| void set_root_location(const gfx::PointF& root_location) { |
| root_location_ = root_location; |
| } |
| gfx::Point root_location() const { |
| return gfx::ToFlooredPoint(root_location_); |
| } |
| const gfx::PointF& root_location_f() const { |
| return root_location_; |
| } |
| |
| // Transform the locations using |inverted_root_transform|. |
| // This is applied to both |location_| and |root_location_|. |
| virtual void UpdateForRootTransform( |
| const gfx::Transform& inverted_root_transform); |
| |
| template <class T> void ConvertLocationToTarget(T* source, T* target) { |
| if (!target || target == source) |
| return; |
| // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See |
| // crbug.com/337824. |
| gfx::Point offset = gfx::ToFlooredPoint(location_); |
| T::ConvertPointToTarget(source, target, &offset); |
| gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset; |
| location_= location_ - diff; |
| } |
| |
| protected: |
| friend class LocatedEventTestApi; |
| explicit LocatedEvent(const base::NativeEvent& native_event); |
| |
| // Create a new LocatedEvent which is identical to the provided model. |
| // If source / target windows are provided, the model location will be |
| // converted from |source| coordinate system to |target| coordinate system. |
| template <class T> |
| LocatedEvent(const LocatedEvent& model, T* source, T* target) |
| : Event(model), |
| location_(model.location_), |
| root_location_(model.root_location_) { |
| ConvertLocationToTarget(source, target); |
| } |
| |
| // Used for synthetic events in testing. |
| LocatedEvent(EventType type, |
| const gfx::PointF& location, |
| const gfx::PointF& root_location, |
| base::TimeDelta time_stamp, |
| int flags); |
| |
| gfx::PointF location_; |
| |
| // |location_| multiplied by an optional transformation matrix for |
| // rotations, animations and skews. |
| gfx::PointF root_location_; |
| }; |
| |
| class EVENTS_EXPORT MouseEvent : public LocatedEvent { |
| public: |
| explicit MouseEvent(const base::NativeEvent& native_event); |
| |
| // Create a new MouseEvent based on the provided model. |
| // Uses the provided |type| and |flags| for the new event. |
| // If source / target windows are provided, the model location will be |
| // converted from |source| coordinate system to |target| coordinate system. |
| template <class T> |
| MouseEvent(const MouseEvent& model, T* source, T* target) |
| : LocatedEvent(model, source, target), |
| changed_button_flags_(model.changed_button_flags_) { |
| } |
| |
| template <class T> |
| MouseEvent(const MouseEvent& model, |
| T* source, |
| T* target, |
| EventType type, |
| int flags) |
| : LocatedEvent(model, source, target), |
| changed_button_flags_(model.changed_button_flags_) { |
| SetType(type); |
| set_flags(flags); |
| } |
| |
| // Used for synthetic events in testing and by the gesture recognizer. |
| MouseEvent(EventType type, |
| const gfx::PointF& location, |
| const gfx::PointF& root_location, |
| int flags, |
| int changed_button_flags); |
| |
| // Conveniences to quickly test what button is down |
| bool IsOnlyLeftMouseButton() const { |
| return (flags() & EF_LEFT_MOUSE_BUTTON) && |
| !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON)); |
| } |
| |
| bool IsLeftMouseButton() const { |
| return (flags() & EF_LEFT_MOUSE_BUTTON) != 0; |
| } |
| |
| bool IsOnlyMiddleMouseButton() const { |
| return (flags() & EF_MIDDLE_MOUSE_BUTTON) && |
| !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON)); |
| } |
| |
| bool IsMiddleMouseButton() const { |
| return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0; |
| } |
| |
| bool IsOnlyRightMouseButton() const { |
| return (flags() & EF_RIGHT_MOUSE_BUTTON) && |
| !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON)); |
| } |
| |
| bool IsRightMouseButton() const { |
| return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0; |
| } |
| |
| bool IsAnyButton() const { |
| return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON | |
| EF_RIGHT_MOUSE_BUTTON)) != 0; |
| } |
| |
| // Compares two mouse down events and returns true if the second one should |
| // be considered a repeat of the first. |
| static bool IsRepeatedClickEvent( |
| const MouseEvent& event1, |
| const MouseEvent& event2); |
| |
| // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise. |
| int GetClickCount() const; |
| |
| // Set the click count for a mousedown message. Can be 1, 2 or 3. |
| void SetClickCount(int click_count); |
| |
| // Identifies the button that changed. During a press this corresponds to the |
| // button that was pressed and during a release this corresponds to the button |
| // that was released. |
| // NOTE: during a press and release flags() contains the complete set of |
| // flags. Use this to determine the button that was pressed or released. |
| int changed_button_flags() const { return changed_button_flags_; } |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresRelease); |
| FRIEND_TEST_ALL_PREFIXES(EventTest, SingleClickRightLeft); |
| |
| // Returns the repeat count based on the previous mouse click, if it is |
| // recent enough and within a small enough distance. |
| static int GetRepeatCount(const MouseEvent& click_event); |
| |
| // Resets the last_click_event_ for unit tests. |
| static void ResetLastClickForTest(); |
| |
| // See description above getter for details. |
| int changed_button_flags_; |
| |
| static MouseEvent* last_click_event_; |
| |
| // We can create a MouseEvent for a native event more than once. We set this |
| // to true when the next event either has a different timestamp or we see a |
| // release signalling that the press (click) event was completed. |
| static bool last_click_complete_; |
| }; |
| |
| class ScrollEvent; |
| |
| class EVENTS_EXPORT MouseWheelEvent : public MouseEvent { |
| public: |
| // See |offset| for details. |
| static const int kWheelDelta; |
| |
| explicit MouseWheelEvent(const base::NativeEvent& native_event); |
| explicit MouseWheelEvent(const ScrollEvent& scroll_event); |
| MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset); |
| MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event); |
| |
| template <class T> |
| MouseWheelEvent(const MouseWheelEvent& model, |
| T* source, |
| T* target) |
| : MouseEvent(model, source, target, model.type(), model.flags()), |
| offset_(model.x_offset(), model.y_offset()) { |
| } |
| |
| // The amount to scroll. This is in multiples of kWheelDelta. |
| // Note: x_offset() > 0/y_offset() > 0 means scroll left/up. |
| int x_offset() const { return offset_.x(); } |
| int y_offset() const { return offset_.y(); } |
| const gfx::Vector2d& offset() const { return offset_; } |
| |
| // Overridden from LocatedEvent. |
| virtual void UpdateForRootTransform( |
| const gfx::Transform& inverted_root_transform) OVERRIDE; |
| |
| private: |
| gfx::Vector2d offset_; |
| }; |
| |
| class EVENTS_EXPORT TouchEvent : public LocatedEvent { |
| public: |
| explicit TouchEvent(const base::NativeEvent& native_event); |
| |
| // Create a new TouchEvent which is identical to the provided model. |
| // If source / target windows are provided, the model location will be |
| // converted from |source| coordinate system to |target| coordinate system. |
| template <class T> |
| TouchEvent(const TouchEvent& model, T* source, T* target) |
| : LocatedEvent(model, source, target), |
| touch_id_(model.touch_id_), |
| radius_x_(model.radius_x_), |
| radius_y_(model.radius_y_), |
| rotation_angle_(model.rotation_angle_), |
| force_(model.force_), |
| source_device_id_(model.source_device_id_) { |
| } |
| |
| TouchEvent(EventType type, |
| const gfx::PointF& location, |
| int touch_id, |
| base::TimeDelta time_stamp); |
| |
| TouchEvent(EventType type, |
| const gfx::PointF& location, |
| int flags, |
| int touch_id, |
| base::TimeDelta timestamp, |
| float radius_x, |
| float radius_y, |
| float angle, |
| float force); |
| |
| virtual ~TouchEvent(); |
| |
| int touch_id() const { return touch_id_; } |
| float radius_x() const { return radius_x_; } |
| float radius_y() const { return radius_y_; } |
| float rotation_angle() const { return rotation_angle_; } |
| float force() const { return force_; } |
| int source_device_id() const { return source_device_id_; } |
| |
| // Used for unit tests. |
| void set_radius_x(const float r) { radius_x_ = r; } |
| void set_radius_y(const float r) { radius_y_ = r; } |
| void set_source_device_id(int source_device_id) { |
| source_device_id_ = source_device_id; |
| } |
| |
| // Overridden from LocatedEvent. |
| virtual void UpdateForRootTransform( |
| const gfx::Transform& inverted_root_transform) OVERRIDE; |
| |
| protected: |
| void set_radius(float radius_x, float radius_y) { |
| radius_x_ = radius_x; |
| radius_y_ = radius_y; |
| } |
| |
| void set_rotation_angle(float rotation_angle) { |
| rotation_angle_ = rotation_angle; |
| } |
| |
| void set_force(float force) { force_ = force; } |
| |
| private: |
| // The identity (typically finger) of the touch starting at 0 and incrementing |
| // for each separable additional touch that the hardware can detect. |
| const int touch_id_; |
| |
| // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown. |
| float radius_x_; |
| |
| // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown. |
| float radius_y_; |
| |
| // Angle of the major axis away from the X axis. Default 0.0. |
| float rotation_angle_; |
| |
| // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0. |
| float force_; |
| |
| // The device id of the screen the event came from. Default to be -1. |
| int source_device_id_; |
| }; |
| |
| class EVENTS_EXPORT KeyEvent : public Event { |
| public: |
| KeyEvent(const base::NativeEvent& native_event, bool is_char); |
| |
| // Used for synthetic events. |
| KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char); |
| |
| // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA') |
| // See also: ui/events/keycodes/dom4/keycode_converter_data.h |
| KeyEvent(EventType type, KeyboardCode key_code, const std::string& code, |
| int flags, bool is_char); |
| |
| // This allows an I18N virtual keyboard to fabricate a keyboard event that |
| // does not have a corresponding KeyboardCode (example: U+00E1 Latin small |
| // letter A with acute, U+0410 Cyrillic capital letter A). |
| void set_character(uint16 character) { character_ = character; } |
| |
| // Gets the character generated by this key event. It only supports Unicode |
| // BMP characters. |
| uint16 GetCharacter() const; |
| |
| // Gets the platform key code. For XKB, this is the xksym value. |
| uint32 platform_keycode() const { return platform_keycode_; } |
| KeyboardCode key_code() const { return key_code_; } |
| bool is_char() const { return is_char_; } |
| |
| // This is only intended to be used externally by classes that are modifying |
| // events in EventFilter::PreHandleKeyEvent(). set_character() should also be |
| // called. |
| void set_key_code(KeyboardCode key_code) { key_code_ = key_code; } |
| |
| // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win. |
| // TODO(msw): Additional work may be needed for analogues on other platforms. |
| bool IsUnicodeKeyCode() const; |
| |
| std::string code() const { return code_; } |
| |
| // Normalizes flags_ to make it Windows/Mac compatible. Since the way |
| // of setting modifier mask on X is very different than Windows/Mac as shown |
| // in http://crbug.com/127142#c8, the normalization is necessary. |
| void NormalizeFlags(); |
| |
| // Returns true if the key event has already been processed by an input method |
| // and there is no need to pass the key event to the input method again. |
| bool IsTranslated() const; |
| // Marks this key event as translated or not translated. |
| void SetTranslated(bool translated); |
| |
| protected: |
| // This allows a subclass TranslatedKeyEvent to be a non character event. |
| void set_is_char(bool is_char) { is_char_ = is_char; } |
| |
| private: |
| KeyboardCode key_code_; |
| |
| // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space') |
| // http://www.w3.org/TR/uievents/#keyboard-key-codes. |
| // |
| // This value represents the physical position in the keyboard and can be |
| // converted from / to keyboard scan code like XKB. |
| std::string code_; |
| |
| // True if this is a translated character event (vs. a raw key down). Both |
| // share the same type: ET_KEY_PRESSED. |
| bool is_char_; |
| |
| // The platform related keycode value. For XKB, it's keysym value. |
| // For now, this is used for CharacterComposer in ChromeOS. |
| uint32 platform_keycode_; |
| |
| // String of 'key' defined in DOM KeyboardEvent (e.g. 'a', 'รข') |
| // http://www.w3.org/TR/uievents/#keyboard-key-codes. |
| // |
| // This value represents the text that the key event will insert to input |
| // field. For key with modifier key, it may have specifial text. |
| // e.g. CTRL+A has '\x01'. |
| uint16 character_; |
| |
| static bool IsRepeated(const KeyEvent& event); |
| |
| static KeyEvent* last_key_event_; |
| }; |
| |
| class EVENTS_EXPORT ScrollEvent : public MouseEvent { |
| public: |
| explicit ScrollEvent(const base::NativeEvent& native_event); |
| template <class T> |
| ScrollEvent(const ScrollEvent& model, |
| T* source, |
| T* target) |
| : MouseEvent(model, source, target), |
| x_offset_(model.x_offset_), |
| y_offset_(model.y_offset_), |
| x_offset_ordinal_(model.x_offset_ordinal_), |
| y_offset_ordinal_(model.y_offset_ordinal_), |
| finger_count_(model.finger_count_){ |
| } |
| |
| // Used for tests. |
| ScrollEvent(EventType type, |
| const gfx::PointF& location, |
| base::TimeDelta time_stamp, |
| int flags, |
| float x_offset, |
| float y_offset, |
| float x_offset_ordinal, |
| float y_offset_ordinal, |
| int finger_count); |
| |
| // Scale the scroll event's offset value. |
| // This is useful in the multi-monitor setup where it needs to be scaled |
| // to provide a consistent user experience. |
| void Scale(const float factor); |
| |
| float x_offset() const { return x_offset_; } |
| float y_offset() const { return y_offset_; } |
| float x_offset_ordinal() const { return x_offset_ordinal_; } |
| float y_offset_ordinal() const { return y_offset_ordinal_; } |
| int finger_count() const { return finger_count_; } |
| |
| private: |
| // Potential accelerated offsets. |
| float x_offset_; |
| float y_offset_; |
| // Unaccelerated offsets. |
| float x_offset_ordinal_; |
| float y_offset_ordinal_; |
| // Number of fingers on the pad. |
| int finger_count_; |
| }; |
| |
| class EVENTS_EXPORT GestureEvent : public LocatedEvent { |
| public: |
| GestureEvent(EventType type, |
| float x, |
| float y, |
| int flags, |
| base::TimeDelta time_stamp, |
| const GestureEventDetails& details, |
| unsigned int touch_ids_bitfield); |
| |
| // Create a new GestureEvent which is identical to the provided model. |
| // If source / target windows are provided, the model location will be |
| // converted from |source| coordinate system to |target| coordinate system. |
| template <typename T> |
| GestureEvent(const GestureEvent& model, T* source, T* target) |
| : LocatedEvent(model, source, target), |
| details_(model.details_), |
| touch_ids_bitfield_(model.touch_ids_bitfield_) { |
| } |
| |
| virtual ~GestureEvent(); |
| |
| const GestureEventDetails& details() const { return details_; } |
| |
| // Returns the lowest touch-id of any of the touches which make up this |
| // gesture. If there are no touches associated with this gesture, returns -1. |
| int GetLowestTouchId() const; |
| |
| private: |
| GestureEventDetails details_; |
| |
| // The set of indices of ones in the binary representation of |
| // touch_ids_bitfield_ is the set of touch_ids associate with this gesture. |
| // This value is stored as a bitfield because the number of touch ids varies, |
| // but we currently don't need more than 32 touches at a time. |
| const unsigned int touch_ids_bitfield_; |
| }; |
| |
| } // namespace ui |
| |
| #endif // UI_EVENTS_EVENT_H_ |