1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef UI_EVENTS_GESTURE_DETECTION_GESTURE_EVENT_DETAILS_H_
6#define UI_EVENTS_GESTURE_DETECTION_GESTURE_EVENT_DETAILS_H_
7
8#include "base/logging.h"
9#include "ui/events/event_constants.h"
10#include "ui/events/events_base_export.h"
11#include "ui/gfx/rect.h"
12#include "ui/gfx/rect_conversions.h"
13
14namespace ui {
15
16struct EVENTS_BASE_EXPORT GestureEventDetails {
17 public:
18  GestureEventDetails();
19  explicit GestureEventDetails(EventType type);
20  GestureEventDetails(EventType type, float delta_x, float delta_y);
21
22  EventType type() const { return type_; }
23
24  int touch_points() const { return touch_points_; }
25  void set_touch_points(int touch_points) {
26    DCHECK_GT(touch_points, 0);
27    touch_points_ = touch_points;
28  }
29
30  int oldest_touch_id() const { return oldest_touch_id_; }
31  void set_oldest_touch_id(int oldest_touch_id) {
32    DCHECK_GE(oldest_touch_id, 0);
33    oldest_touch_id_ = oldest_touch_id;
34  }
35
36  // TODO(tdresser): Return RectF. See crbug.com/337824.
37  const gfx::Rect bounding_box() const {
38    return ToEnclosingRect(bounding_box_);
39  }
40
41  const gfx::RectF& bounding_box_f() const {
42    return bounding_box_;
43  }
44
45  void set_bounding_box(const gfx::RectF& box) { bounding_box_ = box; }
46
47  float scroll_x_hint() const {
48    DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
49    return data.scroll_begin.x_hint;
50  }
51
52  float scroll_y_hint() const {
53    DCHECK_EQ(ET_GESTURE_SCROLL_BEGIN, type_);
54    return data.scroll_begin.y_hint;
55  }
56
57  float scroll_x() const {
58    DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
59    return data.scroll_update.x;
60  }
61
62  float scroll_y() const {
63    DCHECK_EQ(ET_GESTURE_SCROLL_UPDATE, type_);
64    return data.scroll_update.y;
65  }
66
67  float velocity_x() const {
68    DCHECK_EQ(ET_SCROLL_FLING_START, type_);
69    return data.fling_velocity.x;
70  }
71
72  float velocity_y() const {
73    DCHECK_EQ(ET_SCROLL_FLING_START, type_);
74    return data.fling_velocity.y;
75  }
76
77  float first_finger_width() const {
78    DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
79    return data.first_finger_enclosing_rectangle.width;
80  }
81
82  float first_finger_height() const {
83    DCHECK_EQ(ET_GESTURE_TWO_FINGER_TAP, type_);
84    return data.first_finger_enclosing_rectangle.height;
85  }
86
87  float scale() const {
88    DCHECK_EQ(ET_GESTURE_PINCH_UPDATE, type_);
89    return data.scale;
90  }
91
92  bool swipe_left() const {
93    DCHECK_EQ(ET_GESTURE_SWIPE, type_);
94    return data.swipe.left;
95  }
96
97  bool swipe_right() const {
98    DCHECK_EQ(ET_GESTURE_SWIPE, type_);
99    return data.swipe.right;
100  }
101
102  bool swipe_up() const {
103    DCHECK_EQ(ET_GESTURE_SWIPE, type_);
104    return data.swipe.up;
105  }
106
107  bool swipe_down() const {
108    DCHECK_EQ(ET_GESTURE_SWIPE, type_);
109    return data.swipe.down;
110  }
111
112  int tap_count() const {
113    DCHECK(type_ == ET_GESTURE_TAP ||
114           type_ == ET_GESTURE_TAP_UNCONFIRMED ||
115           type_ == ET_GESTURE_DOUBLE_TAP);
116    return data.tap_count;
117  }
118
119  void set_tap_count(int tap_count) {
120    DCHECK_GE(tap_count, 0);
121    DCHECK(type_ == ET_GESTURE_TAP ||
122           type_ == ET_GESTURE_TAP_UNCONFIRMED ||
123           type_ == ET_GESTURE_DOUBLE_TAP);
124    data.tap_count = tap_count;
125  }
126
127  void set_scale(float scale) {
128    DCHECK_GE(scale, 0.0f);
129    DCHECK_EQ(type_, ET_GESTURE_PINCH_UPDATE);
130    data.scale = scale;
131  }
132
133 private:
134  EventType type_;
135  union Details {
136    Details();
137    struct {  // SCROLL start details.
138      // Distance that caused the scroll to start.  Generally redundant with
139      // the x/y values from the first scroll_update.
140      float x_hint;
141      float y_hint;
142    } scroll_begin;
143
144    struct {  // SCROLL delta.
145      float x;
146      float y;
147    } scroll_update;
148
149    float scale;  // PINCH scale.
150
151    struct {  // FLING velocity.
152      float x;
153      float y;
154    } fling_velocity;
155
156    // Dimensions of the first finger's enclosing rectangle for
157    // TWO_FINGER_TAP.
158    struct {
159      float width;
160      float height;
161    } first_finger_enclosing_rectangle;
162
163    struct {  // SWIPE direction.
164      bool left;
165      bool right;
166      bool up;
167      bool down;
168    } swipe;
169
170    // Tap information must be set for ET_GESTURE_TAP,
171    // ET_GESTURE_TAP_UNCONFIRMED, and ET_GESTURE_DOUBLE_TAP events.
172    int tap_count;  // TAP repeat count.
173  } data;
174
175  int touch_points_;  // Number of active touch points in the gesture.
176
177  // Bounding box is an axis-aligned rectangle that contains all the
178  // enclosing rectangles of the touch-points in the gesture.
179  gfx::RectF bounding_box_;
180
181  // The touch id of the oldest touch contributing to the gesture.
182  int oldest_touch_id_;
183};
184
185}  // namespace ui
186
187#endif  // UI_EVENTS_GESTURE_DETECTION_GESTURE_EVENT_DETAILS_H_
188