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.
5 #ifndef UI_EVENTS_EVENT_H_
6 #define UI_EVENTS_EVENT_H_
8 #include "base/basictypes.h"
9 #include "base/compiler_specific.h"
10 #include "base/event_types.h"
11 #include "base/logging.h"
12 #include "base/time/time.h"
13 #include "ui/events/event_constants.h"
14 #include "ui/events/gestures/gesture_types.h"
15 #include "ui/events/keycodes/keyboard_codes.h"
16 #include "ui/events/latency_info.h"
17 #include "ui/gfx/point.h"
18 #include "ui/gfx/point_conversions.h"
27 class EVENTS_EXPORT Event {
33 explicit DispatcherApi(Event* event) : event_(event) {}
35 void set_target(EventTarget* target) {
36 event_->target_ = target;
39 void set_phase(EventPhase phase) { event_->phase_ = phase; }
40 void set_result(int result) {
41 event_->result_ = static_cast<EventResult>(result);
48 DISALLOW_COPY_AND_ASSIGN(DispatcherApi);
51 const base::NativeEvent& native_event() const { return native_event_; }
52 EventType type() const { return type_; }
53 const std::string& name() const { return name_; }
54 // time_stamp represents time since machine was booted.
55 const base::TimeDelta& time_stamp() const { return time_stamp_; }
56 int flags() const { return flags_; }
58 // This is only intended to be used externally by classes that are modifying
59 // events in EventFilter::PreHandleKeyEvent().
60 void set_flags(int flags) { flags_ = flags; }
62 EventTarget* target() const { return target_; }
63 EventPhase phase() const { return phase_; }
64 EventResult result() const { return result_; }
66 LatencyInfo* latency() { return &latency_; }
67 const LatencyInfo* latency() const { return &latency_; }
68 void set_latency(const LatencyInfo& latency) { latency_ = latency; }
70 // By default, events are "cancelable", this means any default processing that
71 // the containing abstraction layer may perform can be prevented by calling
72 // SetHandled(). SetHandled() or StopPropagation() must not be called for
73 // events that are not cancelable.
74 bool cancelable() const { return cancelable_; }
76 // The following methods return true if the respective keys were pressed at
77 // the time the event was created.
78 bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
79 bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
80 bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
81 bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
82 bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
84 bool IsKeyEvent() const {
85 return type_ == ET_KEY_PRESSED ||
86 type_ == ET_KEY_RELEASED ||
87 type_ == ET_TRANSLATED_KEY_PRESS ||
88 type_ == ET_TRANSLATED_KEY_RELEASE;
91 bool IsMouseEvent() const {
92 return type_ == ET_MOUSE_PRESSED ||
93 type_ == ET_MOUSE_DRAGGED ||
94 type_ == ET_MOUSE_RELEASED ||
95 type_ == ET_MOUSE_MOVED ||
96 type_ == ET_MOUSE_ENTERED ||
97 type_ == ET_MOUSE_EXITED ||
98 type_ == ET_MOUSEWHEEL ||
99 type_ == ET_MOUSE_CAPTURE_CHANGED;
102 bool IsTouchEvent() const {
103 return type_ == ET_TOUCH_RELEASED ||
104 type_ == ET_TOUCH_PRESSED ||
105 type_ == ET_TOUCH_MOVED ||
106 type_ == ET_TOUCH_STATIONARY ||
107 type_ == ET_TOUCH_CANCELLED;
110 bool IsGestureEvent() const {
112 case ET_GESTURE_SCROLL_BEGIN:
113 case ET_GESTURE_SCROLL_END:
114 case ET_GESTURE_SCROLL_UPDATE:
116 case ET_GESTURE_TAP_CANCEL:
117 case ET_GESTURE_TAP_DOWN:
118 case ET_GESTURE_BEGIN:
120 case ET_GESTURE_TWO_FINGER_TAP:
121 case ET_GESTURE_PINCH_BEGIN:
122 case ET_GESTURE_PINCH_END:
123 case ET_GESTURE_PINCH_UPDATE:
124 case ET_GESTURE_LONG_PRESS:
125 case ET_GESTURE_LONG_TAP:
126 case ET_GESTURE_MULTIFINGER_SWIPE:
127 case ET_GESTURE_SHOW_PRESS:
128 // When adding a gesture event which is paired with an event which
129 // occurs earlier, add the event to |IsEndingEvent|.
132 case ET_SCROLL_FLING_CANCEL:
133 case ET_SCROLL_FLING_START:
134 // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
135 // Gesture or Scroll events.
136 return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;
144 // An ending event is paired with the event which started it. Setting capture
145 // should not prevent ending events from getting to their initial target.
146 bool IsEndingEvent() const {
148 case ui::ET_TOUCH_CANCELLED:
149 case ui::ET_GESTURE_TAP_CANCEL:
150 case ui::ET_GESTURE_END:
151 case ui::ET_GESTURE_SCROLL_END:
152 case ui::ET_GESTURE_PINCH_END:
159 bool IsScrollEvent() const {
160 // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
161 // Gesture or Scroll events.
162 return type_ == ET_SCROLL ||
163 ((type_ == ET_SCROLL_FLING_START ||
164 type_ == ET_SCROLL_FLING_CANCEL) &&
165 !(flags() & EF_FROM_TOUCH));
168 bool IsScrollGestureEvent() const {
169 return type_ == ET_GESTURE_SCROLL_BEGIN ||
170 type_ == ET_GESTURE_SCROLL_UPDATE ||
171 type_ == ET_GESTURE_SCROLL_END;
174 bool IsFlingScrollEvent() const {
175 return type_ == ET_SCROLL_FLING_CANCEL ||
176 type_ == ET_SCROLL_FLING_START;
179 bool IsMouseWheelEvent() const {
180 return type_ == ET_MOUSEWHEEL;
183 // Returns true if the event has a valid |native_event_|.
184 bool HasNativeEvent() const;
186 // Immediately stops the propagation of the event. This must be called only
187 // from an EventHandler during an event-dispatch. Any event handler that may
188 // be in the list will not receive the event after this is called.
189 // Note that StopPropagation() can be called only for cancelable events.
190 void StopPropagation();
191 bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }
193 // Marks the event as having been handled. A handled event does not reach the
194 // next event phase. For example, if an event is handled during the pre-target
195 // phase, then the event is dispatched to all pre-target handlers, but not to
196 // the target or post-target handlers.
197 // Note that SetHandled() can be called only for cancelable events.
199 bool handled() const { return result_ != ER_UNHANDLED; }
202 Event(EventType type, base::TimeDelta time_stamp, int flags);
203 Event(const base::NativeEvent& native_event, EventType type, int flags);
204 Event(const Event& copy);
205 void SetType(EventType type);
206 void set_delete_native_event(bool delete_native_event) {
207 delete_native_event_ = delete_native_event;
209 void set_cancelable(bool cancelable) { cancelable_ = cancelable; }
211 void set_time_stamp(const base::TimeDelta& time_stamp) {
212 time_stamp_ = time_stamp;
215 void set_name(const std::string& name) { name_ = name; }
218 friend class EventTestApi;
220 // Safely initializes the native event members of this class.
222 void InitWithNativeEvent(const base::NativeEvent& native_event);
226 base::TimeDelta time_stamp_;
227 LatencyInfo latency_;
229 base::NativeEvent native_event_;
230 bool delete_native_event_;
232 EventTarget* target_;
237 class EVENTS_EXPORT CancelModeEvent : public Event {
240 virtual ~CancelModeEvent();
243 class EVENTS_EXPORT LocatedEvent : public Event {
245 virtual ~LocatedEvent();
247 float x() const { return location_.x(); }
248 float y() const { return location_.y(); }
249 void set_location(const gfx::PointF& location) { location_ = location; }
250 // TODO(tdresser): Always return floating point location. See
252 gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
253 gfx::PointF location_f() const { return location_; }
254 void set_root_location(const gfx::PointF& root_location) {
255 root_location_ = root_location;
257 gfx::Point root_location() const {
258 return gfx::ToFlooredPoint(root_location_);
261 // Transform the locations using |inverted_root_transform|.
262 // This is applied to both |location_| and |root_location_|.
263 virtual void UpdateForRootTransform(
264 const gfx::Transform& inverted_root_transform);
266 template <class T> void ConvertLocationToTarget(T* source, T* target) {
267 if (!target || target == source)
269 // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See
271 gfx::Point offset = gfx::ToFlooredPoint(location_);
272 T::ConvertPointToTarget(source, target, &offset);
273 gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset;
274 location_= location_ - diff;
278 friend class LocatedEventTestApi;
279 explicit LocatedEvent(const base::NativeEvent& native_event);
281 // Create a new LocatedEvent which is identical to the provided model.
282 // If source / target windows are provided, the model location will be
283 // converted from |source| coordinate system to |target| coordinate system.
285 LocatedEvent(const LocatedEvent& model, T* source, T* target)
287 location_(model.location_),
288 root_location_(model.root_location_) {
289 ConvertLocationToTarget(source, target);
292 // Used for synthetic events in testing.
293 LocatedEvent(EventType type,
294 const gfx::PointF& location,
295 const gfx::PointF& root_location,
296 base::TimeDelta time_stamp,
299 gfx::PointF location_;
301 // |location_| multiplied by an optional transformation matrix for
302 // rotations, animations and skews.
303 gfx::PointF root_location_;
306 class EVENTS_EXPORT MouseEvent : public LocatedEvent {
308 explicit MouseEvent(const base::NativeEvent& native_event);
310 // Create a new MouseEvent based on the provided model.
311 // Uses the provided |type| and |flags| for the new event.
312 // If source / target windows are provided, the model location will be
313 // converted from |source| coordinate system to |target| coordinate system.
315 MouseEvent(const MouseEvent& model, T* source, T* target)
316 : LocatedEvent(model, source, target),
317 changed_button_flags_(model.changed_button_flags_) {
321 MouseEvent(const MouseEvent& model,
326 : LocatedEvent(model, source, target),
327 changed_button_flags_(model.changed_button_flags_) {
332 // Used for synthetic events in testing and by the gesture recognizer.
333 MouseEvent(EventType type,
334 const gfx::PointF& location,
335 const gfx::PointF& root_location,
337 int changed_button_flags);
339 // Conveniences to quickly test what button is down
340 bool IsOnlyLeftMouseButton() const {
341 return (flags() & EF_LEFT_MOUSE_BUTTON) &&
342 !(flags() & (EF_MIDDLE_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
345 bool IsLeftMouseButton() const {
346 return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
349 bool IsOnlyMiddleMouseButton() const {
350 return (flags() & EF_MIDDLE_MOUSE_BUTTON) &&
351 !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON));
354 bool IsMiddleMouseButton() const {
355 return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
358 bool IsOnlyRightMouseButton() const {
359 return (flags() & EF_RIGHT_MOUSE_BUTTON) &&
360 !(flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON));
363 bool IsRightMouseButton() const {
364 return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
367 bool IsAnyButton() const {
368 return (flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
369 EF_RIGHT_MOUSE_BUTTON)) != 0;
372 // Compares two mouse down events and returns true if the second one should
373 // be considered a repeat of the first.
374 static bool IsRepeatedClickEvent(
375 const MouseEvent& event1,
376 const MouseEvent& event2);
378 // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
379 int GetClickCount() const;
381 // Set the click count for a mousedown message. Can be 1, 2 or 3.
382 void SetClickCount(int click_count);
384 // Identifies the button that changed. During a press this corresponds to the
385 // button that was pressed and during a release this corresponds to the button
386 // that was released.
387 // NOTE: during a press and release flags() contains the complete set of
388 // flags. Use this to determine the button that was pressed or released.
389 int changed_button_flags() const { return changed_button_flags_; }
392 // Returns the repeat count based on the previous mouse click, if it is
393 // recent enough and within a small enough distance.
394 static int GetRepeatCount(const MouseEvent& click_event);
396 // See description above getter for details.
397 int changed_button_flags_;
399 static MouseEvent* last_click_event_;
404 class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
406 // See |offset| for details.
407 static const int kWheelDelta;
409 explicit MouseWheelEvent(const base::NativeEvent& native_event);
410 explicit MouseWheelEvent(const ScrollEvent& scroll_event);
411 MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
412 MouseWheelEvent(const MouseWheelEvent& mouse_wheel_event);
415 MouseWheelEvent(const MouseWheelEvent& model,
420 : MouseEvent(model, source, target, type, flags),
421 offset_(model.x_offset(), model.y_offset()){
424 // The amount to scroll. This is in multiples of kWheelDelta.
425 // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
426 int x_offset() const { return offset_.x(); }
427 int y_offset() const { return offset_.y(); }
428 const gfx::Vector2d& offset() const { return offset_; }
430 // Overridden from LocatedEvent.
431 virtual void UpdateForRootTransform(
432 const gfx::Transform& inverted_root_transform) OVERRIDE;
435 gfx::Vector2d offset_;
438 class EVENTS_EXPORT TouchEvent : public LocatedEvent {
440 explicit TouchEvent(const base::NativeEvent& native_event);
442 // Create a new TouchEvent which is identical to the provided model.
443 // If source / target windows are provided, the model location will be
444 // converted from |source| coordinate system to |target| coordinate system.
446 TouchEvent(const TouchEvent& model, T* source, T* target)
447 : LocatedEvent(model, source, target),
448 touch_id_(model.touch_id_),
449 radius_x_(model.radius_x_),
450 radius_y_(model.radius_y_),
451 rotation_angle_(model.rotation_angle_),
452 force_(model.force_),
453 source_device_id_(model.source_device_id_) {
456 TouchEvent(EventType type,
457 const gfx::PointF& location,
459 base::TimeDelta time_stamp);
461 TouchEvent(EventType type,
462 const gfx::PointF& location,
465 base::TimeDelta timestamp,
471 virtual ~TouchEvent();
473 int touch_id() const { return touch_id_; }
474 float radius_x() const { return radius_x_; }
475 float radius_y() const { return radius_y_; }
476 float rotation_angle() const { return rotation_angle_; }
477 float force() const { return force_; }
478 int source_device_id() const { return source_device_id_; }
480 // Relocate the touch-point to a new |origin|.
481 // This is useful when touch event is in X Root Window coordinates,
482 // and it needs to be mapped into Aura Root Window coordinates.
483 void Relocate(const gfx::Point& origin);
485 // Used for unit tests.
486 void set_radius_x(const float r) { radius_x_ = r; }
487 void set_radius_y(const float r) { radius_y_ = r; }
488 void set_source_device_id(int source_device_id) {
489 source_device_id_ = source_device_id;
492 // Overridden from LocatedEvent.
493 virtual void UpdateForRootTransform(
494 const gfx::Transform& inverted_root_transform) OVERRIDE;
497 void set_radius(float radius_x, float radius_y) {
498 radius_x_ = radius_x;
499 radius_y_ = radius_y;
502 void set_rotation_angle(float rotation_angle) {
503 rotation_angle_ = rotation_angle;
506 void set_force(float force) { force_ = force; }
509 // The identity (typically finger) of the touch starting at 0 and incrementing
510 // for each separable additional touch that the hardware can detect.
513 // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
516 // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
519 // Angle of the major axis away from the X axis. Default 0.0.
520 float rotation_angle_;
522 // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
525 // The device id of the screen the event came from. Default to be -1.
526 int source_device_id_;
529 class EVENTS_EXPORT KeyEvent : public Event {
531 KeyEvent(const base::NativeEvent& native_event, bool is_char);
533 // Used for synthetic events.
534 KeyEvent(EventType type, KeyboardCode key_code, int flags, bool is_char);
536 // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
537 // See also: ui/events/keycodes/dom4/keycode_converter_data.h
538 KeyEvent(EventType type, KeyboardCode key_code, const std::string& code,
539 int flags, bool is_char);
541 // This allows an I18N virtual keyboard to fabricate a keyboard event that
542 // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
543 // letter A with acute, U+0410 Cyrillic capital letter A).
544 void set_character(uint16 character) { character_ = character; }
546 // Gets the character generated by this key event. It only supports Unicode
548 uint16 GetCharacter() const;
550 KeyboardCode key_code() const { return key_code_; }
551 bool is_char() const { return is_char_; }
553 // This is only intended to be used externally by classes that are modifying
554 // events in EventFilter::PreHandleKeyEvent(). set_character() should also be
556 void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
558 // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
559 // TODO(msw): Additional work may be needed for analogues on other platforms.
560 bool IsUnicodeKeyCode() const;
562 std::string code() const { return code_; }
564 // Normalizes flags_ to make it Windows/Mac compatible. Since the way
565 // of setting modifier mask on X is very different than Windows/Mac as shown
566 // in http://crbug.com/127142#c8, the normalization is necessary.
567 void NormalizeFlags();
570 KeyboardCode key_code_;
572 // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
573 // http://www.w3.org/TR/uievents/#keyboard-key-codes.
575 // This value represents the physical position in the keyboard and can be
576 // converted from / to keyboard scan code like XKB.
579 // True if this is a translated character event (vs. a raw key down). Both
580 // share the same type: ET_KEY_PRESSED.
586 // A key event which is translated by an input method (IME).
587 // For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not
588 // consume the key, the IME usually generates and dispatches a
589 // TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and
590 // it does consume the event, it might dispatch a
591 // TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec.
592 class EVENTS_EXPORT TranslatedKeyEvent : public KeyEvent {
594 TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char);
596 // Used for synthetic events such as a VKEY_PROCESSKEY key event.
597 TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags);
599 // Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so
600 // that RenderWidgetHostViewAura and NativeWidgetAura could handle the event.
601 void ConvertToKeyEvent();
604 DISALLOW_COPY_AND_ASSIGN(TranslatedKeyEvent);
607 class EVENTS_EXPORT ScrollEvent : public MouseEvent {
609 explicit ScrollEvent(const base::NativeEvent& native_event);
611 ScrollEvent(const ScrollEvent& model,
614 : MouseEvent(model, source, target),
615 x_offset_(model.x_offset_),
616 y_offset_(model.y_offset_),
617 x_offset_ordinal_(model.x_offset_ordinal_),
618 y_offset_ordinal_(model.y_offset_ordinal_),
619 finger_count_(model.finger_count_){
623 ScrollEvent(EventType type,
624 const gfx::PointF& location,
625 base::TimeDelta time_stamp,
629 float x_offset_ordinal,
630 float y_offset_ordinal,
633 // Scale the scroll event's offset value.
634 // This is useful in the multi-monitor setup where it needs to be scaled
635 // to provide a consistent user experience.
636 void Scale(const float factor);
638 float x_offset() const { return x_offset_; }
639 float y_offset() const { return y_offset_; }
640 float x_offset_ordinal() const { return x_offset_ordinal_; }
641 float y_offset_ordinal() const { return y_offset_ordinal_; }
642 int finger_count() const { return finger_count_; }
645 // Potential accelerated offsets.
648 // Unaccelerated offsets.
649 float x_offset_ordinal_;
650 float y_offset_ordinal_;
651 // Number of fingers on the pad.
655 class EVENTS_EXPORT GestureEvent : public LocatedEvent {
657 GestureEvent(EventType type,
661 base::TimeDelta time_stamp,
662 const GestureEventDetails& details,
663 unsigned int touch_ids_bitfield);
665 // Create a new GestureEvent which is identical to the provided model.
666 // If source / target windows are provided, the model location will be
667 // converted from |source| coordinate system to |target| coordinate system.
668 template <typename T>
669 GestureEvent(const GestureEvent& model, T* source, T* target)
670 : LocatedEvent(model, source, target),
671 details_(model.details_),
672 touch_ids_bitfield_(model.touch_ids_bitfield_) {
675 virtual ~GestureEvent();
677 const GestureEventDetails& details() const { return details_; }
679 // Returns the lowest touch-id of any of the touches which make up this
680 // gesture. If there are no touches associated with this gesture, returns -1.
681 int GetLowestTouchId() const;
684 GestureEventDetails details_;
686 // The set of indices of ones in the binary representation of
687 // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
688 // This value is stored as a bitfield because the number of touch ids varies,
689 // but we currently don't need more than 32 touches at a time.
690 const unsigned int touch_ids_bitfield_;
695 #endif // UI_EVENTS_EVENT_H_