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