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/gesture_event_details.h"
15 #include "ui/events/gestures/gesture_types.h"
16 #include "ui/events/keycodes/keyboard_codes.h"
17 #include "ui/events/latency_info.h"
18 #include "ui/gfx/point.h"
19 #include "ui/gfx/point_conversions.h"
28 class EVENTS_EXPORT Event
{
34 explicit DispatcherApi(Event
* event
) : event_(event
) {}
36 void set_target(EventTarget
* target
) {
37 event_
->target_
= target
;
40 void set_phase(EventPhase phase
) { event_
->phase_
= phase
; }
41 void set_result(int result
) {
42 event_
->result_
= static_cast<EventResult
>(result
);
49 DISALLOW_COPY_AND_ASSIGN(DispatcherApi
);
52 const base::NativeEvent
& native_event() const { return native_event_
; }
53 EventType
type() const { return type_
; }
54 const std::string
& name() const { return name_
; }
55 // time_stamp represents time since machine was booted.
56 const base::TimeDelta
& time_stamp() const { return time_stamp_
; }
57 int flags() const { return flags_
; }
59 // This is only intended to be used externally by classes that are modifying
60 // events in EventFilter::PreHandleKeyEvent().
61 void set_flags(int flags
) { flags_
= flags
; }
63 EventTarget
* target() const { return target_
; }
64 EventPhase
phase() const { return phase_
; }
65 EventResult
result() const { return result_
; }
67 LatencyInfo
* latency() { return &latency_
; }
68 const LatencyInfo
* latency() const { return &latency_
; }
69 void set_latency(const LatencyInfo
& latency
) { latency_
= latency
; }
71 // By default, events are "cancelable", this means any default processing that
72 // the containing abstraction layer may perform can be prevented by calling
73 // SetHandled(). SetHandled() or StopPropagation() must not be called for
74 // events that are not cancelable.
75 bool cancelable() const { return cancelable_
; }
77 // The following methods return true if the respective keys were pressed at
78 // the time the event was created.
79 bool IsShiftDown() const { return (flags_
& EF_SHIFT_DOWN
) != 0; }
80 bool IsControlDown() const { return (flags_
& EF_CONTROL_DOWN
) != 0; }
81 bool IsCapsLockDown() const { return (flags_
& EF_CAPS_LOCK_DOWN
) != 0; }
82 bool IsAltDown() const { return (flags_
& EF_ALT_DOWN
) != 0; }
83 bool IsAltGrDown() const { return (flags_
& EF_ALTGR_DOWN
) != 0; }
84 bool IsRepeat() const { return (flags_
& EF_IS_REPEAT
) != 0; }
86 bool IsKeyEvent() const {
87 return type_
== ET_KEY_PRESSED
||
88 type_
== ET_KEY_RELEASED
||
89 type_
== ET_TRANSLATED_KEY_PRESS
||
90 type_
== ET_TRANSLATED_KEY_RELEASE
;
93 bool IsMouseEvent() const {
94 return type_
== ET_MOUSE_PRESSED
||
95 type_
== ET_MOUSE_DRAGGED
||
96 type_
== ET_MOUSE_RELEASED
||
97 type_
== ET_MOUSE_MOVED
||
98 type_
== ET_MOUSE_ENTERED
||
99 type_
== ET_MOUSE_EXITED
||
100 type_
== ET_MOUSEWHEEL
||
101 type_
== ET_MOUSE_CAPTURE_CHANGED
;
104 bool IsTouchEvent() const {
105 return type_
== ET_TOUCH_RELEASED
||
106 type_
== ET_TOUCH_PRESSED
||
107 type_
== ET_TOUCH_MOVED
||
108 type_
== ET_TOUCH_CANCELLED
;
111 bool IsGestureEvent() const {
113 case ET_GESTURE_SCROLL_BEGIN
:
114 case ET_GESTURE_SCROLL_END
:
115 case ET_GESTURE_SCROLL_UPDATE
:
117 case ET_GESTURE_TAP_CANCEL
:
118 case ET_GESTURE_TAP_DOWN
:
119 case ET_GESTURE_BEGIN
:
121 case ET_GESTURE_TWO_FINGER_TAP
:
122 case ET_GESTURE_PINCH_BEGIN
:
123 case ET_GESTURE_PINCH_END
:
124 case ET_GESTURE_PINCH_UPDATE
:
125 case ET_GESTURE_LONG_PRESS
:
126 case ET_GESTURE_LONG_TAP
:
127 case ET_GESTURE_SWIPE
:
128 case ET_GESTURE_SHOW_PRESS
:
129 case ET_GESTURE_WIN8_EDGE_SWIPE
:
130 // When adding a gesture event which is paired with an event which
131 // occurs earlier, add the event to |IsEndingEvent|.
134 case ET_SCROLL_FLING_CANCEL
:
135 case ET_SCROLL_FLING_START
:
136 // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
137 // Gesture or Scroll events.
138 return (flags_
& EF_FROM_TOUCH
) == EF_FROM_TOUCH
;
146 // An ending event is paired with the event which started it. Setting capture
147 // should not prevent ending events from getting to their initial target.
148 bool IsEndingEvent() const {
150 case ui::ET_TOUCH_CANCELLED
:
151 case ui::ET_GESTURE_TAP_CANCEL
:
152 case ui::ET_GESTURE_END
:
153 case ui::ET_GESTURE_SCROLL_END
:
154 case ui::ET_GESTURE_PINCH_END
:
161 bool IsScrollEvent() const {
162 // Flings can be GestureEvents too. EF_FROM_TOUCH determins if they're
163 // Gesture or Scroll events.
164 return type_
== ET_SCROLL
||
165 ((type_
== ET_SCROLL_FLING_START
||
166 type_
== ET_SCROLL_FLING_CANCEL
) &&
167 !(flags() & EF_FROM_TOUCH
));
170 bool IsScrollGestureEvent() const {
171 return type_
== ET_GESTURE_SCROLL_BEGIN
||
172 type_
== ET_GESTURE_SCROLL_UPDATE
||
173 type_
== ET_GESTURE_SCROLL_END
;
176 bool IsFlingScrollEvent() const {
177 return type_
== ET_SCROLL_FLING_CANCEL
||
178 type_
== ET_SCROLL_FLING_START
;
181 bool IsMouseWheelEvent() const {
182 return type_
== ET_MOUSEWHEEL
;
185 // Returns true if the event has a valid |native_event_|.
186 bool HasNativeEvent() const;
188 // Immediately stops the propagation of the event. This must be called only
189 // from an EventHandler during an event-dispatch. Any event handler that may
190 // be in the list will not receive the event after this is called.
191 // Note that StopPropagation() can be called only for cancelable events.
192 void StopPropagation();
193 bool stopped_propagation() const { return !!(result_
& ER_CONSUMED
); }
195 // Marks the event as having been handled. A handled event does not reach the
196 // next event phase. For example, if an event is handled during the pre-target
197 // phase, then the event is dispatched to all pre-target handlers, but not to
198 // the target or post-target handlers.
199 // Note that SetHandled() can be called only for cancelable events.
201 bool handled() const { return result_
!= ER_UNHANDLED
; }
204 Event(EventType type
, base::TimeDelta time_stamp
, int flags
);
205 Event(const base::NativeEvent
& native_event
, EventType type
, int flags
);
206 Event(const Event
& copy
);
207 void SetType(EventType type
);
208 void set_delete_native_event(bool delete_native_event
) {
209 delete_native_event_
= delete_native_event
;
211 void set_cancelable(bool cancelable
) { cancelable_
= cancelable
; }
213 void set_time_stamp(const base::TimeDelta
& time_stamp
) {
214 time_stamp_
= time_stamp
;
217 void set_name(const std::string
& name
) { name_
= name
; }
220 friend class EventTestApi
;
224 base::TimeDelta time_stamp_
;
225 LatencyInfo latency_
;
227 base::NativeEvent native_event_
;
228 bool delete_native_event_
;
230 EventTarget
* target_
;
235 class EVENTS_EXPORT CancelModeEvent
: public Event
{
238 virtual ~CancelModeEvent();
241 class EVENTS_EXPORT LocatedEvent
: public Event
{
243 virtual ~LocatedEvent();
245 float x() const { return location_
.x(); }
246 float y() const { return location_
.y(); }
247 void set_location(const gfx::PointF
& location
) { location_
= location
; }
248 // TODO(tdresser): Always return floating point location. See
250 gfx::Point
location() const { return gfx::ToFlooredPoint(location_
); }
251 const gfx::PointF
& location_f() const { return location_
; }
252 void set_root_location(const gfx::PointF
& root_location
) {
253 root_location_
= root_location
;
255 gfx::Point
root_location() const {
256 return gfx::ToFlooredPoint(root_location_
);
258 const gfx::PointF
& root_location_f() const {
259 return root_location_
;
262 // Transform the locations using |inverted_root_transform|.
263 // This is applied to both |location_| and |root_location_|.
264 virtual void UpdateForRootTransform(
265 const gfx::Transform
& inverted_root_transform
);
267 template <class T
> void ConvertLocationToTarget(T
* source
, T
* target
) {
268 if (!target
|| target
== source
)
270 // TODO(tdresser): Rewrite ConvertPointToTarget to use PointF. See
272 gfx::Point offset
= gfx::ToFlooredPoint(location_
);
273 T::ConvertPointToTarget(source
, target
, &offset
);
274 gfx::Vector2d diff
= gfx::ToFlooredPoint(location_
) - offset
;
275 location_
= location_
- diff
;
279 friend class LocatedEventTestApi
;
280 explicit LocatedEvent(const base::NativeEvent
& native_event
);
282 // Create a new LocatedEvent which is identical to the provided model.
283 // If source / target windows are provided, the model location will be
284 // converted from |source| coordinate system to |target| coordinate system.
286 LocatedEvent(const LocatedEvent
& model
, T
* source
, T
* target
)
288 location_(model
.location_
),
289 root_location_(model
.root_location_
) {
290 ConvertLocationToTarget(source
, target
);
293 // Used for synthetic events in testing.
294 LocatedEvent(EventType type
,
295 const gfx::PointF
& location
,
296 const gfx::PointF
& root_location
,
297 base::TimeDelta time_stamp
,
300 gfx::PointF location_
;
302 // |location_| multiplied by an optional transformation matrix for
303 // rotations, animations and skews.
304 gfx::PointF root_location_
;
307 class EVENTS_EXPORT MouseEvent
: public LocatedEvent
{
309 explicit MouseEvent(const base::NativeEvent
& native_event
);
311 // Create a new MouseEvent based on the provided model.
312 // Uses the provided |type| and |flags| for the new event.
313 // If source / target windows are provided, the model location will be
314 // converted from |source| coordinate system to |target| coordinate system.
316 MouseEvent(const MouseEvent
& model
, T
* source
, T
* target
)
317 : LocatedEvent(model
, source
, target
),
318 changed_button_flags_(model
.changed_button_flags_
) {
322 MouseEvent(const MouseEvent
& model
,
327 : LocatedEvent(model
, source
, target
),
328 changed_button_flags_(model
.changed_button_flags_
) {
333 // Used for synthetic events in testing and by the gesture recognizer.
334 MouseEvent(EventType type
,
335 const gfx::PointF
& location
,
336 const gfx::PointF
& root_location
,
338 int changed_button_flags
);
340 // Conveniences to quickly test what button is down
341 bool IsOnlyLeftMouseButton() const {
342 return (flags() & EF_LEFT_MOUSE_BUTTON
) &&
343 !(flags() & (EF_MIDDLE_MOUSE_BUTTON
| EF_RIGHT_MOUSE_BUTTON
));
346 bool IsLeftMouseButton() const {
347 return (flags() & EF_LEFT_MOUSE_BUTTON
) != 0;
350 bool IsOnlyMiddleMouseButton() const {
351 return (flags() & EF_MIDDLE_MOUSE_BUTTON
) &&
352 !(flags() & (EF_LEFT_MOUSE_BUTTON
| EF_RIGHT_MOUSE_BUTTON
));
355 bool IsMiddleMouseButton() const {
356 return (flags() & EF_MIDDLE_MOUSE_BUTTON
) != 0;
359 bool IsOnlyRightMouseButton() const {
360 return (flags() & EF_RIGHT_MOUSE_BUTTON
) &&
361 !(flags() & (EF_LEFT_MOUSE_BUTTON
| EF_MIDDLE_MOUSE_BUTTON
));
364 bool IsRightMouseButton() const {
365 return (flags() & EF_RIGHT_MOUSE_BUTTON
) != 0;
368 bool IsAnyButton() const {
369 return (flags() & (EF_LEFT_MOUSE_BUTTON
| EF_MIDDLE_MOUSE_BUTTON
|
370 EF_RIGHT_MOUSE_BUTTON
)) != 0;
373 // Compares two mouse down events and returns true if the second one should
374 // be considered a repeat of the first.
375 static bool IsRepeatedClickEvent(
376 const MouseEvent
& event1
,
377 const MouseEvent
& event2
);
379 // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
380 int GetClickCount() const;
382 // Set the click count for a mousedown message. Can be 1, 2 or 3.
383 void SetClickCount(int click_count
);
385 // Identifies the button that changed. During a press this corresponds to the
386 // button that was pressed and during a release this corresponds to the button
387 // that was released.
388 // NOTE: during a press and release flags() contains the complete set of
389 // flags. Use this to determine the button that was pressed or released.
390 int changed_button_flags() const { return changed_button_flags_
; }
393 // Returns the repeat count based on the previous mouse click, if it is
394 // recent enough and within a small enough distance.
395 static int GetRepeatCount(const MouseEvent
& click_event
);
397 // See description above getter for details.
398 int changed_button_flags_
;
400 static MouseEvent
* last_click_event_
;
405 class EVENTS_EXPORT MouseWheelEvent
: public MouseEvent
{
407 // See |offset| for details.
408 static const int kWheelDelta
;
410 explicit MouseWheelEvent(const base::NativeEvent
& native_event
);
411 explicit MouseWheelEvent(const ScrollEvent
& scroll_event
);
412 MouseWheelEvent(const MouseEvent
& mouse_event
, int x_offset
, int y_offset
);
413 MouseWheelEvent(const MouseWheelEvent
& mouse_wheel_event
);
416 MouseWheelEvent(const MouseWheelEvent
& model
,
419 : MouseEvent(model
, source
, target
, model
.type(), model
.flags()),
420 offset_(model
.x_offset(), model
.y_offset()) {
423 // Used for synthetic events in testing and by the gesture recognizer.
424 MouseWheelEvent(const gfx::Vector2d
& offset
,
425 const gfx::PointF
& location
,
426 const gfx::PointF
& root_location
,
428 int changed_button_flags
);
430 // The amount to scroll. This is in multiples of kWheelDelta.
431 // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
432 int x_offset() const { return offset_
.x(); }
433 int y_offset() const { return offset_
.y(); }
434 const gfx::Vector2d
& offset() const { return offset_
; }
436 // Overridden from LocatedEvent.
437 virtual void UpdateForRootTransform(
438 const gfx::Transform
& inverted_root_transform
) OVERRIDE
;
441 gfx::Vector2d offset_
;
444 class EVENTS_EXPORT TouchEvent
: public LocatedEvent
{
446 explicit TouchEvent(const base::NativeEvent
& native_event
);
448 // Create a new TouchEvent which is identical to the provided model.
449 // If source / target windows are provided, the model location will be
450 // converted from |source| coordinate system to |target| coordinate system.
452 TouchEvent(const TouchEvent
& model
, T
* source
, T
* target
)
453 : LocatedEvent(model
, source
, target
),
454 touch_id_(model
.touch_id_
),
455 radius_x_(model
.radius_x_
),
456 radius_y_(model
.radius_y_
),
457 rotation_angle_(model
.rotation_angle_
),
458 force_(model
.force_
),
459 source_device_id_(model
.source_device_id_
) {
462 TouchEvent(EventType type
,
463 const gfx::PointF
& location
,
465 base::TimeDelta time_stamp
);
467 TouchEvent(EventType type
,
468 const gfx::PointF
& location
,
471 base::TimeDelta timestamp
,
477 virtual ~TouchEvent();
479 int touch_id() const { return touch_id_
; }
480 float radius_x() const { return radius_x_
; }
481 float radius_y() const { return radius_y_
; }
482 float rotation_angle() const { return rotation_angle_
; }
483 float force() const { return force_
; }
484 int source_device_id() const { return source_device_id_
; }
486 // Used for unit tests.
487 void set_radius_x(const float r
) { radius_x_
= r
; }
488 void set_radius_y(const float r
) { radius_y_
= r
; }
489 void set_source_device_id(int source_device_id
) {
490 source_device_id_
= source_device_id
;
493 // Overridden from LocatedEvent.
494 virtual void UpdateForRootTransform(
495 const gfx::Transform
& inverted_root_transform
) OVERRIDE
;
498 void set_radius(float radius_x
, float radius_y
) {
499 radius_x_
= radius_x
;
500 radius_y_
= radius_y
;
503 void set_rotation_angle(float rotation_angle
) {
504 rotation_angle_
= rotation_angle
;
507 void set_force(float force
) { force_
= force
; }
510 // The identity (typically finger) of the touch starting at 0 and incrementing
511 // for each separable additional touch that the hardware can detect.
514 // Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
517 // Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
520 // Angle of the major axis away from the X axis. Default 0.0.
521 float rotation_angle_
;
523 // Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
526 // The device id of the screen the event came from. Default to be -1.
527 int source_device_id_
;
530 class EVENTS_EXPORT KeyEvent
: public Event
{
532 KeyEvent(const base::NativeEvent
& native_event
, bool is_char
);
534 // Used for synthetic events.
535 KeyEvent(EventType type
, KeyboardCode key_code
, int flags
, bool is_char
);
537 // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
538 // See also: ui/events/keycodes/dom4/keycode_converter_data.h
539 KeyEvent(EventType type
, KeyboardCode key_code
, const std::string
& code
,
540 int flags
, bool is_char
);
542 // This allows an I18N virtual keyboard to fabricate a keyboard event that
543 // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
544 // letter A with acute, U+0410 Cyrillic capital letter A).
545 void set_character(uint16 character
) { character_
= character
; }
547 // Gets the character generated by this key event. It only supports Unicode
549 uint16
GetCharacter() const;
551 // Gets the platform key code. For XKB, this is the xksym value.
552 uint32
platform_keycode() const { return platform_keycode_
; }
553 KeyboardCode
key_code() const { return key_code_
; }
554 bool is_char() const { return is_char_
; }
556 // This is only intended to be used externally by classes that are modifying
557 // events in EventFilter::PreHandleKeyEvent(). set_character() should also be
559 void set_key_code(KeyboardCode key_code
) { key_code_
= key_code
; }
561 // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
562 // TODO(msw): Additional work may be needed for analogues on other platforms.
563 bool IsUnicodeKeyCode() const;
565 std::string
code() const { return code_
; }
567 // Normalizes flags_ to make it Windows/Mac compatible. Since the way
568 // of setting modifier mask on X is very different than Windows/Mac as shown
569 // in http://crbug.com/127142#c8, the normalization is necessary.
570 void NormalizeFlags();
572 // Returns true if the key event has already been processed by an input method
573 // and there is no need to pass the key event to the input method again.
574 bool IsTranslated() const;
575 // Marks this key event as translated or not translated.
576 void SetTranslated(bool translated
);
579 // This allows a subclass TranslatedKeyEvent to be a non character event.
580 void set_is_char(bool is_char
) { is_char_
= is_char
; }
583 KeyboardCode key_code_
;
585 // String of 'code' defined in DOM KeyboardEvent (e.g. 'KeyA', 'Space')
586 // http://www.w3.org/TR/uievents/#keyboard-key-codes.
588 // This value represents the physical position in the keyboard and can be
589 // converted from / to keyboard scan code like XKB.
592 // True if this is a translated character event (vs. a raw key down). Both
593 // share the same type: ET_KEY_PRESSED.
596 // The platform related keycode value. For XKB, it's keysym value.
597 // For now, this is used for CharacterComposer in ChromeOS.
598 uint32 platform_keycode_
;
600 // String of 'key' defined in DOM KeyboardEvent (e.g. 'a', 'รข')
601 // http://www.w3.org/TR/uievents/#keyboard-key-codes.
603 // This value represents the text that the key event will insert to input
604 // field. For key with modifier key, it may have specifial text.
605 // e.g. CTRL+A has '\x01'.
608 static bool IsRepeated(const KeyEvent
& event
);
610 static KeyEvent
* last_key_event_
;
613 class EVENTS_EXPORT ScrollEvent
: public MouseEvent
{
615 explicit ScrollEvent(const base::NativeEvent
& native_event
);
617 ScrollEvent(const ScrollEvent
& model
,
620 : MouseEvent(model
, source
, target
),
621 x_offset_(model
.x_offset_
),
622 y_offset_(model
.y_offset_
),
623 x_offset_ordinal_(model
.x_offset_ordinal_
),
624 y_offset_ordinal_(model
.y_offset_ordinal_
),
625 finger_count_(model
.finger_count_
){
629 ScrollEvent(EventType type
,
630 const gfx::PointF
& location
,
631 base::TimeDelta time_stamp
,
635 float x_offset_ordinal
,
636 float y_offset_ordinal
,
639 // Scale the scroll event's offset value.
640 // This is useful in the multi-monitor setup where it needs to be scaled
641 // to provide a consistent user experience.
642 void Scale(const float factor
);
644 float x_offset() const { return x_offset_
; }
645 float y_offset() const { return y_offset_
; }
646 float x_offset_ordinal() const { return x_offset_ordinal_
; }
647 float y_offset_ordinal() const { return y_offset_ordinal_
; }
648 int finger_count() const { return finger_count_
; }
651 // Potential accelerated offsets.
654 // Unaccelerated offsets.
655 float x_offset_ordinal_
;
656 float y_offset_ordinal_
;
657 // Number of fingers on the pad.
661 class EVENTS_EXPORT GestureEvent
: public LocatedEvent
{
663 GestureEvent(EventType type
,
667 base::TimeDelta time_stamp
,
668 const GestureEventDetails
& details
,
669 unsigned int touch_ids_bitfield
);
671 // Create a new GestureEvent which is identical to the provided model.
672 // If source / target windows are provided, the model location will be
673 // converted from |source| coordinate system to |target| coordinate system.
674 template <typename T
>
675 GestureEvent(const GestureEvent
& model
, T
* source
, T
* target
)
676 : LocatedEvent(model
, source
, target
),
677 details_(model
.details_
),
678 touch_ids_bitfield_(model
.touch_ids_bitfield_
) {
681 virtual ~GestureEvent();
683 const GestureEventDetails
& details() const { return details_
; }
685 // Returns the lowest touch-id of any of the touches which make up this
686 // gesture. If there are no touches associated with this gesture, returns -1.
687 int GetLowestTouchId() const;
690 GestureEventDetails details_
;
692 // The set of indices of ones in the binary representation of
693 // touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
694 // This value is stored as a bitfield because the number of touch ids varies,
695 // but we currently don't need more than 32 touches at a time.
696 const unsigned int touch_ids_bitfield_
;
701 #endif // UI_EVENTS_EVENT_H_