Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: ui/aura/event.cc

Issue 10827145: Convert Aura to use ui::Event. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ui/aura/event.h ('k') | ui/aura/event_filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 #include "ui/aura/event.h"
6
7 #if defined(USE_X11)
8 #include <X11/Xlib.h>
9 #endif
10
11 #include <cstring>
12
13 #include "ui/aura/window.h"
14 #include "ui/base/keycodes/keyboard_code_conversion.h"
15 #include "ui/gfx/point3.h"
16 #include "ui/gfx/interpolated_transform.h"
17 #include "ui/gfx/transform.h"
18
19 #if defined(OS_MACOSX)
20 #include "ui/aura/event_mac.h"
21 #endif
22
23 #if defined(USE_X11)
24 #include "ui/base/keycodes/keyboard_code_conversion_x.h"
25 #endif
26
27 namespace {
28
29 base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
30 #if defined(USE_X11)
31 XEvent* copy = new XEvent;
32 *copy = *event;
33 return copy;
34 #elif defined(OS_WIN)
35 return event;
36 #elif defined(OS_MACOSX)
37 return aura::CopyNativeEvent(event);
38 #else
39 NOTREACHED() <<
40 "Don't know how to copy base::NativeEvent for this platform";
41 #endif
42 }
43
44 } // namespace
45
46 namespace aura {
47
48 Event::~Event() {
49 #if defined(USE_X11)
50 if (delete_native_event_)
51 delete native_event_;
52 #endif
53 }
54
55 bool Event::HasNativeEvent() const {
56 base::NativeEvent null_event;
57 std::memset(&null_event, 0, sizeof(null_event));
58 return !!std::memcmp(&native_event_, &null_event, sizeof(null_event));
59 }
60
61 Event::Event(ui::EventType type, int flags)
62 : type_(type),
63 time_stamp_(base::Time::NowFromSystemTime() - base::Time()),
64 flags_(flags),
65 delete_native_event_(false) {
66 Init();
67 }
68
69 Event::Event(const base::NativeEvent& native_event,
70 ui::EventType type,
71 int flags)
72 : type_(type),
73 time_stamp_(ui::EventTimeFromNative(native_event)),
74 flags_(flags),
75 delete_native_event_(false) {
76 InitWithNativeEvent(native_event);
77 }
78
79 Event::Event(const Event& copy)
80 : native_event_(copy.native_event_),
81 type_(copy.type_),
82 time_stamp_(copy.time_stamp_),
83 flags_(copy.flags_),
84 delete_native_event_(false) {
85 }
86
87 void Event::Init() {
88 std::memset(&native_event_, 0, sizeof(native_event_));
89 }
90
91 void Event::InitWithNativeEvent(const base::NativeEvent& native_event) {
92 native_event_ = native_event;
93 }
94
95 LocatedEvent::~LocatedEvent() {
96 }
97
98 LocatedEvent::LocatedEvent(const base::NativeEvent& native_event)
99 : Event(native_event,
100 ui::EventTypeFromNative(native_event),
101 ui::EventFlagsFromNative(native_event)),
102 location_(ui::EventLocationFromNative(native_event)),
103 root_location_(location_) {
104 }
105
106 LocatedEvent::LocatedEvent(const LocatedEvent& model,
107 Window* source,
108 Window* target)
109 : Event(model),
110 location_(model.location_),
111 root_location_(model.root_location_) {
112 if (target && target != source)
113 Window::ConvertPointToWindow(source, target, &location_);
114 }
115
116 LocatedEvent::LocatedEvent(ui::EventType type,
117 const gfx::Point& location,
118 const gfx::Point& root_location,
119 int flags)
120 : Event(type, flags),
121 location_(location),
122 root_location_(root_location) {
123 }
124
125 void LocatedEvent::UpdateForRootTransform(const ui::Transform& root_transform) {
126 // Transform has to be done at root level.
127 DCHECK_EQ(root_location_.x(), location_.x());
128 DCHECK_EQ(root_location_.y(), location_.y());
129 gfx::Point3f p(location_);
130 root_transform.TransformPointReverse(p);
131 root_location_ = location_ = p.AsPoint();
132 }
133
134 MouseEvent::MouseEvent(const base::NativeEvent& native_event)
135 : LocatedEvent(native_event) {
136 if (type() == ui::ET_MOUSE_PRESSED)
137 SetClickCount(GetRepeatCount(*this));
138 }
139
140 MouseEvent::MouseEvent(const MouseEvent& model, Window* source, Window* target)
141 : LocatedEvent(model, source, target) {
142 }
143
144 MouseEvent::MouseEvent(const MouseEvent& model,
145 Window* source,
146 Window* target,
147 ui::EventType type,
148 int flags)
149 : LocatedEvent(model, source, target) {
150 set_type(type);
151 set_flags(flags);
152 }
153
154 MouseEvent::MouseEvent(ui::EventType type,
155 const gfx::Point& location,
156 const gfx::Point& root_location,
157 int flags)
158 : LocatedEvent(type, location, root_location, flags) {
159 }
160
161 // static
162 bool MouseEvent::IsRepeatedClickEvent(
163 const MouseEvent& event1,
164 const MouseEvent& event2) {
165 // These values match the Windows defaults.
166 static const int kDoubleClickTimeMS = 500;
167 static const int kDoubleClickWidth = 4;
168 static const int kDoubleClickHeight = 4;
169
170 if (event1.type() != ui::ET_MOUSE_PRESSED ||
171 event2.type() != ui::ET_MOUSE_PRESSED)
172 return false;
173
174 // Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks.
175 if ((event1.flags() & ~ui::EF_IS_DOUBLE_CLICK) !=
176 (event2.flags() & ~ui::EF_IS_DOUBLE_CLICK))
177 return false;
178
179 base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp();
180
181 if (time_difference.InMilliseconds() > kDoubleClickTimeMS)
182 return false;
183
184 if (abs(event2.x() - event1.x()) > kDoubleClickWidth / 2)
185 return false;
186
187 if (abs(event2.y() - event1.y()) > kDoubleClickHeight / 2)
188 return false;
189
190 return true;
191 }
192
193 // static
194 int MouseEvent::GetRepeatCount(const MouseEvent& event) {
195 int click_count = 1;
196 if (last_click_event_) {
197 if (IsRepeatedClickEvent(*last_click_event_, event))
198 click_count = last_click_event_->GetClickCount() + 1;
199 delete last_click_event_;
200 }
201 last_click_event_ = new MouseEvent(event, NULL, NULL);
202 if (click_count > 3)
203 click_count = 3;
204 last_click_event_->SetClickCount(click_count);
205 return click_count;
206 }
207
208 // static
209 MouseEvent* MouseEvent::last_click_event_ = NULL;
210
211 int MouseEvent::GetClickCount() const {
212 if (type() != ui::ET_MOUSE_PRESSED)
213 return 0;
214
215 if (flags() & ui::EF_IS_TRIPLE_CLICK)
216 return 3;
217 else if (flags() & ui::EF_IS_DOUBLE_CLICK)
218 return 2;
219 else
220 return 1;
221 }
222
223 void MouseEvent::SetClickCount(int click_count) {
224 if (type() != ui::ET_MOUSE_PRESSED)
225 return;
226
227 DCHECK(click_count > 0);
228 DCHECK(click_count <= 3);
229
230 int f = flags();
231 switch (click_count) {
232 case 1:
233 f &= ~ui::EF_IS_DOUBLE_CLICK;
234 f &= ~ui::EF_IS_TRIPLE_CLICK;
235 break;
236 case 2:
237 f |= ui::EF_IS_DOUBLE_CLICK;
238 f &= ~ui::EF_IS_TRIPLE_CLICK;
239 break;
240 case 3:
241 f &= ~ui::EF_IS_DOUBLE_CLICK;
242 f |= ui::EF_IS_TRIPLE_CLICK;
243 break;
244 }
245 set_flags(f);
246 }
247
248 TouchEvent::TouchEvent(const base::NativeEvent& native_event)
249 : LocatedEvent(native_event),
250 touch_id_(ui::GetTouchId(native_event)),
251 radius_x_(ui::GetTouchRadiusX(native_event)),
252 radius_y_(ui::GetTouchRadiusY(native_event)),
253 rotation_angle_(ui::GetTouchAngle(native_event)),
254 force_(ui::GetTouchForce(native_event)) {
255 }
256
257 TouchEvent::TouchEvent(const TouchEvent& model,
258 Window* source,
259 Window* target)
260 : LocatedEvent(model, source, target),
261 touch_id_(model.touch_id_),
262 radius_x_(model.radius_x_),
263 radius_y_(model.radius_y_),
264 rotation_angle_(model.rotation_angle_),
265 force_(model.force_) {
266 }
267
268 TouchEvent::TouchEvent(ui::EventType type,
269 const gfx::Point& location,
270 int touch_id,
271 base::TimeDelta time_stamp)
272 : LocatedEvent(type, location, location, 0),
273 touch_id_(touch_id),
274 radius_x_(0.0f),
275 radius_y_(0.0f),
276 rotation_angle_(0.0f),
277 force_(0.0f) {
278 set_time_stamp(time_stamp);
279 }
280
281 TouchEvent::~TouchEvent() {
282 }
283
284 void TouchEvent::UpdateForRootTransform(const ui::Transform& root_transform) {
285 LocatedEvent::UpdateForRootTransform(root_transform);
286 gfx::Point3f scale;
287 ui::InterpolatedTransform::FactorTRS(root_transform, NULL, NULL, &scale);
288 if (scale.x())
289 radius_x_ /= scale.x();
290 if (scale.y())
291 radius_y_ /= scale.y();
292 }
293
294 ui::EventType TouchEvent::GetEventType() const {
295 return type();
296 }
297
298 gfx::Point TouchEvent::GetLocation() const {
299 return location();
300 }
301
302 int TouchEvent::GetTouchId() const {
303 return touch_id_;
304 }
305
306 int TouchEvent::GetEventFlags() const {
307 return flags();
308 }
309
310 base::TimeDelta TouchEvent::GetTimestamp() const {
311 return time_stamp();
312 }
313
314 float TouchEvent::RadiusX() const {
315 return radius_x_;
316 }
317
318 float TouchEvent::RadiusY() const {
319 return radius_y_;
320 }
321
322 float TouchEvent::RotationAngle() const {
323 return rotation_angle_;
324 }
325
326 float TouchEvent::Force() const {
327 return force_;
328 }
329
330 KeyEvent::KeyEvent(const base::NativeEvent& native_event, bool is_char)
331 : Event(native_event,
332 ui::EventTypeFromNative(native_event),
333 ui::EventFlagsFromNative(native_event)),
334 key_code_(ui::KeyboardCodeFromNative(native_event)),
335 is_char_(is_char),
336 character_(0),
337 unmodified_character_(0) {
338 }
339
340 KeyEvent::KeyEvent(ui::EventType type,
341 ui::KeyboardCode key_code,
342 int flags)
343 : Event(type, flags),
344 key_code_(key_code),
345 is_char_(false),
346 character_(ui::GetCharacterFromKeyCode(key_code, flags)),
347 unmodified_character_(0) {
348 }
349
350 uint16 KeyEvent::GetCharacter() const {
351 if (character_)
352 return character_;
353
354 #if defined(OS_WIN)
355 return (native_event().message == WM_CHAR) ? key_code_ :
356 ui::GetCharacterFromKeyCode(key_code_, flags());
357 #elif defined(USE_X11)
358 if (!native_event())
359 return ui::GetCharacterFromKeyCode(key_code_, flags());
360
361 DCHECK(native_event()->type == KeyPress ||
362 native_event()->type == KeyRelease);
363
364 uint16 ch = 0;
365 if (!IsControlDown())
366 ch = ui::GetCharacterFromXEvent(native_event());
367 return ch ? ch : ui::GetCharacterFromKeyCode(key_code_, flags());
368 #else
369 NOTIMPLEMENTED();
370 return 0;
371 #endif
372 }
373
374 uint16 KeyEvent::GetUnmodifiedCharacter() const {
375 if (unmodified_character_)
376 return unmodified_character_;
377
378 #if defined(OS_WIN)
379 // Looks like there is no way to get unmodified character on Windows.
380 return (native_event().message == WM_CHAR) ? key_code_ :
381 ui::GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN);
382 #elif defined(USE_X11)
383 if (!native_event())
384 return ui::GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN);
385
386 DCHECK(native_event()->type == KeyPress ||
387 native_event()->type == KeyRelease);
388
389 static const unsigned int kIgnoredModifiers = ControlMask | LockMask |
390 Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask;
391
392 XKeyEvent copy = native_event()->xkey; // bit-wise copy is safe.
393 // We can't use things like (native_event()->xkey.state & ShiftMask), as it
394 // may mask out bits used by X11 internally.
395 copy.state &= ~kIgnoredModifiers;
396 uint16 ch = ui::GetCharacterFromXEvent(reinterpret_cast<XEvent*>(&copy));
397 return ch ? ch :
398 ui::GetCharacterFromKeyCode(key_code_, flags() & ui::EF_SHIFT_DOWN);
399 #else
400 NOTIMPLEMENTED();
401 return 0;
402 #endif
403 }
404
405 KeyEvent* KeyEvent::Copy() {
406 KeyEvent* copy = new KeyEvent(::CopyNativeEvent(native_event()), is_char());
407 #if defined(USE_X11)
408 copy->set_delete_native_event(true);
409 #endif
410 return copy;
411 }
412
413 TranslatedKeyEvent::TranslatedKeyEvent(const base::NativeEvent& native_event,
414 bool is_char)
415 : KeyEvent(native_event, is_char) {
416 set_type(type() == ui::ET_KEY_PRESSED ?
417 ui::ET_TRANSLATED_KEY_PRESS : ui::ET_TRANSLATED_KEY_RELEASE);
418 }
419
420 TranslatedKeyEvent::TranslatedKeyEvent(bool is_press,
421 ui::KeyboardCode key_code,
422 int flags)
423 : KeyEvent((is_press ?
424 ui::ET_TRANSLATED_KEY_PRESS : ui::ET_TRANSLATED_KEY_RELEASE),
425 key_code,
426 flags) {
427 }
428
429 void TranslatedKeyEvent::ConvertToKeyEvent() {
430 set_type(type() == ui::ET_TRANSLATED_KEY_PRESS ?
431 ui::ET_KEY_PRESSED : ui::ET_KEY_RELEASED);
432 }
433
434 ScrollEvent::ScrollEvent(const base::NativeEvent& native_event)
435 : MouseEvent(native_event) {
436 if (type() == ui::ET_SCROLL) {
437 ui::GetScrollOffsets(native_event, &x_offset_, &y_offset_);
438 double start, end;
439 ui::GetGestureTimes(native_event, &start, &end);
440 } else if (type() == ui::ET_SCROLL_FLING_START) {
441 bool is_cancel;
442 ui::GetFlingData(native_event, &x_offset_, &y_offset_, &is_cancel);
443 }
444 }
445
446 GestureEvent::GestureEvent(ui::EventType type,
447 int x,
448 int y,
449 int flags,
450 base::Time time_stamp,
451 const ui::GestureEventDetails& details,
452 unsigned int touch_ids_bitfield)
453 : LocatedEvent(type, gfx::Point(x, y), gfx::Point(x, y), flags),
454 details_(details),
455 touch_ids_bitfield_(touch_ids_bitfield) {
456 set_time_stamp(base::TimeDelta::FromSeconds(time_stamp.ToDoubleT()));
457 }
458
459 GestureEvent::GestureEvent(const GestureEvent& model,
460 Window* source,
461 Window* target)
462 : LocatedEvent(model, source, target),
463 details_(model.details_),
464 touch_ids_bitfield_(model.touch_ids_bitfield_) {
465 }
466
467 GestureEvent::~GestureEvent() {
468 }
469
470 int GestureEvent::GetLowestTouchId() const {
471 if (touch_ids_bitfield_ == 0)
472 return -1;
473 int i = -1;
474 // Find the index of the least significant 1 bit
475 while (!(1 << ++i & touch_ids_bitfield_));
476 return i;
477 }
478
479 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/event.h ('k') | ui/aura/event_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698