Commit 4e07b2be authored by ben@chromium.org's avatar ben@chromium.org

Copy aura::Event into ui::Event.

http://crbug.com/125937
TEST=existing
Review URL: https://chromiumcodereview.appspot.com/10831137

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149888 0039d316-1c4b-4281-b951-d872f2087c98
parent ef3e5f0e
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/event.h"
#if defined(USE_X11)
#include <X11/Xlib.h>
#endif
#include <cstring>
#include "ui/base/keycodes/keyboard_code_conversion.h"
#include "ui/gfx/point3.h"
#include "ui/gfx/interpolated_transform.h"
#include "ui/gfx/transform.h"
#if defined(USE_X11)
#include "ui/base/keycodes/keyboard_code_conversion_x.h"
#endif
namespace {
base::NativeEvent CopyNativeEvent(const base::NativeEvent& event) {
#if defined(USE_X11)
XEvent* copy = new XEvent;
*copy = *event;
return copy;
#elif defined(OS_WIN)
return event;
#else
NOTREACHED() <<
"Don't know how to copy base::NativeEvent for this platform";
return NULL;
#endif
}
} // namespace
namespace ui {
Event::~Event() {
#if defined(USE_X11)
if (delete_native_event_)
delete native_event_;
#endif
}
bool Event::HasNativeEvent() const {
base::NativeEvent null_event;
std::memset(&null_event, 0, sizeof(null_event));
return !!std::memcmp(&native_event_, &null_event, sizeof(null_event));
}
Event::Event(EventType type, int flags)
: type_(type),
time_stamp_(base::Time::NowFromSystemTime() - base::Time()),
flags_(flags),
delete_native_event_(false) {
Init();
}
Event::Event(const base::NativeEvent& native_event,
EventType type,
int flags)
: type_(type),
time_stamp_(EventTimeFromNative(native_event)),
flags_(flags),
delete_native_event_(false) {
InitWithNativeEvent(native_event);
}
Event::Event(const Event& copy)
: native_event_(copy.native_event_),
type_(copy.type_),
time_stamp_(copy.time_stamp_),
flags_(copy.flags_),
delete_native_event_(false) {
}
void Event::Init() {
std::memset(&native_event_, 0, sizeof(native_event_));
}
void Event::InitWithNativeEvent(const base::NativeEvent& native_event) {
native_event_ = native_event;
}
LocatedEvent::~LocatedEvent() {
}
LocatedEvent::LocatedEvent(const base::NativeEvent& native_event)
: Event(native_event,
EventTypeFromNative(native_event),
EventFlagsFromNative(native_event)),
location_(EventLocationFromNative(native_event)),
root_location_(location_) {
}
LocatedEvent::LocatedEvent(EventType type,
const gfx::Point& location,
const gfx::Point& root_location,
int flags)
: Event(type, flags),
location_(location),
root_location_(root_location) {
}
void LocatedEvent::UpdateForRootTransform(const Transform& root_transform) {
// Transform has to be done at root level.
DCHECK_EQ(root_location_.x(), location_.x());
DCHECK_EQ(root_location_.y(), location_.y());
gfx::Point3f p(location_);
root_transform.TransformPointReverse(p);
root_location_ = location_ = p.AsPoint();
}
MouseEvent::MouseEvent(const base::NativeEvent& native_event)
: LocatedEvent(native_event) {
if (type() == ET_MOUSE_PRESSED)
SetClickCount(GetRepeatCount(*this));
}
MouseEvent::MouseEvent(EventType type,
const gfx::Point& location,
const gfx::Point& root_location,
int flags)
: LocatedEvent(type, location, root_location, flags) {
}
// static
bool MouseEvent::IsRepeatedClickEvent(
const MouseEvent& event1,
const MouseEvent& event2) {
// These values match the Windows defaults.
static const int kDoubleClickTimeMS = 500;
static const int kDoubleClickWidth = 4;
static const int kDoubleClickHeight = 4;
if (event1.type() != ET_MOUSE_PRESSED ||
event2.type() != ET_MOUSE_PRESSED)
return false;
// Compare flags, but ignore EF_IS_DOUBLE_CLICK to allow triple clicks.
if ((event1.flags() & ~EF_IS_DOUBLE_CLICK) !=
(event2.flags() & ~EF_IS_DOUBLE_CLICK))
return false;
base::TimeDelta time_difference = event2.time_stamp() - event1.time_stamp();
if (time_difference.InMilliseconds() > kDoubleClickTimeMS)
return false;
if (abs(event2.x() - event1.x()) > kDoubleClickWidth / 2)
return false;
if (abs(event2.y() - event1.y()) > kDoubleClickHeight / 2)
return false;
return true;
}
// static
int MouseEvent::GetRepeatCount(const MouseEvent& event) {
int click_count = 1;
if (last_click_event_) {
if (IsRepeatedClickEvent(*last_click_event_, event))
click_count = last_click_event_->GetClickCount() + 1;
delete last_click_event_;
}
last_click_event_ = new MouseEvent(event.native_event());
if (click_count > 3)
click_count = 3;
last_click_event_->SetClickCount(click_count);
return click_count;
}
// static
MouseEvent* MouseEvent::last_click_event_ = NULL;
int MouseEvent::GetClickCount() const {
if (type() != ET_MOUSE_PRESSED)
return 0;
if (flags() & EF_IS_TRIPLE_CLICK)
return 3;
else if (flags() & EF_IS_DOUBLE_CLICK)
return 2;
else
return 1;
}
void MouseEvent::SetClickCount(int click_count) {
if (type() != ET_MOUSE_PRESSED)
return;
DCHECK(click_count > 0);
DCHECK(click_count <= 3);
int f = flags();
switch (click_count) {
case 1:
f &= ~EF_IS_DOUBLE_CLICK;
f &= ~EF_IS_TRIPLE_CLICK;
break;
case 2:
f |= EF_IS_DOUBLE_CLICK;
f &= ~EF_IS_TRIPLE_CLICK;
break;
case 3:
f &= ~EF_IS_DOUBLE_CLICK;
f |= EF_IS_TRIPLE_CLICK;
break;
}
set_flags(f);
}
TouchEventImpl::TouchEventImpl(const base::NativeEvent& native_event)
: LocatedEvent(native_event),
touch_id_(ui::GetTouchId(native_event)),
radius_x_(GetTouchRadiusX(native_event)),
radius_y_(GetTouchRadiusY(native_event)),
rotation_angle_(GetTouchAngle(native_event)),
force_(GetTouchForce(native_event)) {
}
TouchEventImpl::TouchEventImpl(EventType type,
const gfx::Point& location,
int touch_id,
base::TimeDelta time_stamp)
: LocatedEvent(type, location, location, 0),
touch_id_(touch_id),
radius_x_(0.0f),
radius_y_(0.0f),
rotation_angle_(0.0f),
force_(0.0f) {
set_time_stamp(time_stamp);
}
TouchEventImpl::~TouchEventImpl() {
}
void TouchEventImpl::UpdateForRootTransform(const Transform& root_transform) {
LocatedEvent::UpdateForRootTransform(root_transform);
gfx::Point3f scale;
InterpolatedTransform::FactorTRS(root_transform, NULL, NULL, &scale);
if (scale.x())
radius_x_ /= scale.x();
if (scale.y())
radius_y_ /= scale.y();
}
EventType TouchEventImpl::GetEventType() const {
return type();
}
gfx::Point TouchEventImpl::GetLocation() const {
return location();
}
int TouchEventImpl::GetTouchId() const {
return touch_id_;
}
int TouchEventImpl::GetEventFlags() const {
return flags();
}
base::TimeDelta TouchEventImpl::GetTimestamp() const {
return time_stamp();
}
float TouchEventImpl::RadiusX() const {
return radius_x_;
}
float TouchEventImpl::RadiusY() const {
return radius_y_;
}
float TouchEventImpl::RotationAngle() const {
return rotation_angle_;
}
float TouchEventImpl::Force() const {
return force_;
}
KeyEvent::KeyEvent(const base::NativeEvent& native_event, bool is_char)
: Event(native_event,
EventTypeFromNative(native_event),
EventFlagsFromNative(native_event)),
key_code_(KeyboardCodeFromNative(native_event)),
is_char_(is_char),
character_(0),
unmodified_character_(0) {
}
KeyEvent::KeyEvent(EventType type,
KeyboardCode key_code,
int flags)
: Event(type, flags),
key_code_(key_code),
is_char_(false),
character_(GetCharacterFromKeyCode(key_code, flags)),
unmodified_character_(0) {
}
uint16 KeyEvent::GetCharacter() const {
if (character_)
return character_;
#if defined(OS_WIN)
return (native_event().message == WM_CHAR) ? key_code_ :
GetCharacterFromKeyCode(key_code_, flags());
#elif defined(USE_X11)
if (!native_event())
return GetCharacterFromKeyCode(key_code_, flags());
DCHECK(native_event()->type == KeyPress ||
native_event()->type == KeyRelease);
uint16 ch = 0;
if (!IsControlDown())
ch = GetCharacterFromXEvent(native_event());
return ch ? ch : GetCharacterFromKeyCode(key_code_, flags());
#else
NOTIMPLEMENTED();
return 0;
#endif
}
uint16 KeyEvent::GetUnmodifiedCharacter() const {
if (unmodified_character_)
return unmodified_character_;
#if defined(OS_WIN)
// Looks like there is no way to get unmodified character on Windows.
return (native_event().message == WM_CHAR) ? key_code_ :
GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
#elif defined(USE_X11)
if (!native_event())
return GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
DCHECK(native_event()->type == KeyPress ||
native_event()->type == KeyRelease);
static const unsigned int kIgnoredModifiers = ControlMask | LockMask |
Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask;
XKeyEvent copy = native_event()->xkey; // bit-wise copy is safe.
// We can't use things like (native_event()->xkey.state & ShiftMask), as it
// may mask out bits used by X11 internally.
copy.state &= ~kIgnoredModifiers;
uint16 ch = GetCharacterFromXEvent(reinterpret_cast<XEvent*>(&copy));
return ch ? ch : GetCharacterFromKeyCode(key_code_, flags() & EF_SHIFT_DOWN);
#else
NOTIMPLEMENTED();
return 0;
#endif
}
KeyEvent* KeyEvent::Copy() {
KeyEvent* copy = new KeyEvent(::CopyNativeEvent(native_event()), is_char());
#if defined(USE_X11)
copy->set_delete_native_event(true);
#endif
return copy;
}
TranslatedKeyEvent::TranslatedKeyEvent(const base::NativeEvent& native_event,
bool is_char)
: KeyEvent(native_event, is_char) {
set_type(type() == ET_KEY_PRESSED ?
ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE);
}
TranslatedKeyEvent::TranslatedKeyEvent(bool is_press,
KeyboardCode key_code,
int flags)
: KeyEvent((is_press ? ET_TRANSLATED_KEY_PRESS : ET_TRANSLATED_KEY_RELEASE),
key_code,
flags) {
}
void TranslatedKeyEvent::ConvertToKeyEvent() {
set_type(type() == ET_TRANSLATED_KEY_PRESS ?
ET_KEY_PRESSED : ET_KEY_RELEASED);
}
ScrollEvent::ScrollEvent(const base::NativeEvent& native_event)
: MouseEvent(native_event) {
if (type() == ET_SCROLL) {
GetScrollOffsets(native_event, &x_offset_, &y_offset_);
double start, end;
GetGestureTimes(native_event, &start, &end);
} else if (type() == ET_SCROLL_FLING_START) {
bool is_cancel;
GetFlingData(native_event, &x_offset_, &y_offset_, &is_cancel);
}
}
GestureEventImpl::GestureEventImpl(EventType type,
int x,
int y,
int flags,
base::Time time_stamp,
const GestureEventDetails& details,
unsigned int touch_ids_bitfield)
: LocatedEvent(type, gfx::Point(x, y), gfx::Point(x, y), flags),
details_(details),
touch_ids_bitfield_(touch_ids_bitfield) {
set_time_stamp(base::TimeDelta::FromSeconds(time_stamp.ToDoubleT()));
}
GestureEventImpl::~GestureEventImpl() {
}
int GestureEventImpl::GetLowestTouchId() const {
if (touch_ids_bitfield_ == 0)
return -1;
int i = -1;
// Find the index of the least significant 1 bit
while (!(1 << ++i & touch_ids_bitfield_));
return i;
}
} // namespace ui
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_BASE_EVENT_H_
#define UI_BASE_EVENT_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/event_types.h"
#include "base/logging.h"
#include "base/time.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/events.h"
#include "ui/base/gestures/gesture_types.h"
#include "ui/base/keycodes/keyboard_codes.h"
#include "ui/base/ui_export.h"
#include "ui/gfx/point.h"
namespace ui {
class Transform;
class UI_EXPORT Event {
public:
virtual ~Event();
// For testing.
class TestApi {
public:
explicit TestApi(Event* event) : event_(event) {}
void set_time_stamp(const base::TimeDelta& time_stamp) {
event_->time_stamp_ = time_stamp;
}
private:
TestApi();
Event* event_;
};
const base::NativeEvent& native_event() const { return native_event_; }
EventType type() const { return type_; }
// time_stamp represents time since machine was booted.
const base::TimeDelta& time_stamp() const { return time_stamp_; }
int flags() const { return flags_; }
// This is only intended to be used externally by classes that are modifying
// events in EventFilter::PreHandleKeyEvent().
void set_flags(int flags) { flags_ = flags; }
// The following methods return true if the respective keys were pressed at
// the time the event was created.
bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
bool IsCapsLockDown() const { return (flags_ & EF_CAPS_LOCK_DOWN) != 0; }
bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
// Returns true if the event has a valid |native_event_|.
bool HasNativeEvent() const;
protected:
Event(EventType type, int flags);
Event(const base::NativeEvent& native_event, EventType type, int flags);
Event(const Event& copy);
void set_type(EventType type) { type_ = type; }
void set_delete_native_event(bool delete_native_event) {
delete_native_event_ = delete_native_event;
}
void set_time_stamp(base::TimeDelta time_stamp) { time_stamp_ = time_stamp; }
private:
void operator=(const Event&);
// Safely initializes the native event members of this class.
void Init();
void InitWithNativeEvent(const base::NativeEvent& native_event);
base::NativeEvent native_event_;
EventType type_;
base::TimeDelta time_stamp_;
int flags_;
bool delete_native_event_;
};
class UI_EXPORT LocatedEvent : public Event {
public:
// For testing.
class TestApi : public Event::TestApi {
public:
explicit TestApi(LocatedEvent* located_event)
: Event::TestApi(located_event),
located_event_(located_event) {}
void set_location(const gfx::Point& location) {
located_event_->location_ = location;
}
private:
TestApi();
LocatedEvent* located_event_;
};
virtual ~LocatedEvent();
int x() const { return location_.x(); }
int y() const { return location_.y(); }
gfx::Point location() const { return location_; }
gfx::Point root_location() const { return root_location_; }
// Applies |root_transform| to the event.
// This is applied to both |location_| and |root_location_|.
virtual void UpdateForRootTransform(const Transform& root_transform);
protected:
explicit LocatedEvent(const base::NativeEvent& native_event);
// Create a new LocatedEvent which is identical to the provided model.
// If source / target windows are provided, the model location will be
// converted from |source| coordinate system to |target| coordinate system.
template <class T>
LocatedEvent(const LocatedEvent& model, T* source, T* target)
: Event(model),
location_(model.location_),
root_location_(model.root_location_) {
if (target && target != source)
T::ConvertPointToTarget(source, target, &location_);
}
// Used for synthetic events in testing.
LocatedEvent(EventType type,
const gfx::Point& location,
const gfx::Point& root_location,
int flags);
gfx::Point location_;
gfx::Point root_location_;
private:
DISALLOW_COPY_AND_ASSIGN(LocatedEvent);
};
class UI_EXPORT MouseEvent : public LocatedEvent {
public:
explicit MouseEvent(const base::NativeEvent& native_event);
// Create a new MouseEvent based on the provided model.
// Uses the provided |type| and |flags| for the new event.
// If source / target windows are provided, the model location will be
// converted from |source| coordinate system to |target| coordinate system.
template <class T>
MouseEvent(const MouseEvent& model, T* source, T* target)
: LocatedEvent(model, source, target) {
}
template <class T>
MouseEvent(const MouseEvent& model,
T* source,
T* target,
EventType type,
int flags)
: LocatedEvent(model, source, target) {
set_type(type);
set_flags(flags);
}
// Used for synthetic events in testing and by the gesture recognizer.
MouseEvent(EventType type,
const gfx::Point& location,
const gfx::Point& root_location,
int flags);
// Compares two mouse down events and returns true if the second one should
// be considered a repeat of the first.
static bool IsRepeatedClickEvent(
const MouseEvent& event1,
const MouseEvent& event2);
// Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
int GetClickCount() const;
// Set the click count for a mousedown message. Can be 1, 2 or 3.
void SetClickCount(int click_count);
private:
gfx::Point root_location_;
static MouseEvent* last_click_event_;
// Returns the repeat count based on the previous mouse click, if it is
// recent enough and within a small enough distance.
static int GetRepeatCount(const MouseEvent& click_event);
DISALLOW_COPY_AND_ASSIGN(MouseEvent);
};
// TODO(beng): rename to TouchEvent after conversion is complete.
class UI_EXPORT TouchEventImpl : public LocatedEvent,
public TouchEvent {
public:
explicit TouchEventImpl(const base::NativeEvent& native_event);
// Create a new TouchEventImpl which is identical to the provided model.
// If source / target windows are provided, the model location will be
// converted from |source| coordinate system to |target| coordinate system.
template <class T>
TouchEventImpl(const TouchEventImpl& model, T* source, T* target)
: LocatedEvent(model, source, target),
touch_id_(model.touch_id_),
radius_x_(model.radius_x_),
radius_y_(model.radius_y_),
rotation_angle_(model.rotation_angle_),
force_(model.force_) {
}
TouchEventImpl(EventType type,
const gfx::Point& root_location,
int touch_id,
base::TimeDelta time_stamp);
virtual ~TouchEventImpl();
int touch_id() const { return touch_id_; }
float radius_x() const { return radius_x_; }
float radius_y() const { return radius_y_; }
float rotation_angle() const { return rotation_angle_; }
float force() const { return force_; }
// Used for unit tests.
void set_radius_x(const float r) { radius_x_ = r; }
void set_radius_y(const float r) { radius_y_ = r; }
// Overridden from LocatedEvent.
virtual void UpdateForRootTransform(const Transform& root_transform) OVERRIDE;
// Overridden from TouchEvent.
virtual EventType GetEventType() const OVERRIDE;
virtual gfx::Point GetLocation() const OVERRIDE;
virtual int GetTouchId() const OVERRIDE;
virtual int GetEventFlags() const OVERRIDE;
virtual base::TimeDelta GetTimestamp() const OVERRIDE;
virtual float RadiusX() const OVERRIDE;
virtual float RadiusY() const OVERRIDE;
virtual float RotationAngle() const OVERRIDE;
virtual float Force() const OVERRIDE;
private:
// The identity (typically finger) of the touch starting at 0 and incrementing
// for each separable additional touch that the hardware can detect.
const int touch_id_;
// Radius of the X (major) axis of the touch ellipse. 0.0 if unknown.
float radius_x_;
// Radius of the Y (minor) axis of the touch ellipse. 0.0 if unknown.
float radius_y_;
// Angle of the major axis away from the X axis. Default 0.0.
const float rotation_angle_;
// Force (pressure) of the touch. Normalized to be [0, 1]. Default to be 0.0.
const float force_;
DISALLOW_COPY_AND_ASSIGN(TouchEventImpl);
};
class UI_EXPORT KeyEvent : public Event {
public:
KeyEvent(const base::NativeEvent& native_event, bool is_char);
// Used for synthetic events in testing.
KeyEvent(EventType type, KeyboardCode key_code, int flags);
// These setters allow an I18N virtual keyboard to fabricate a keyboard event
// which does not have a corresponding KeyboardCode (example: U+00E1 Latin
// small letter A with acute, U+0410 Cyrillic capital letter A.)
// GetCharacter() and GetUnmodifiedCharacter() return the character.
void set_character(uint16 character) { character_ = character; }
void set_unmodified_character(uint16 unmodified_character) {
unmodified_character_ = unmodified_character;
}
// Gets the character generated by this key event. It only supports Unicode
// BMP characters.
uint16 GetCharacter() const;
// Gets the character generated by this key event ignoring concurrently-held
// modifiers (except shift).
uint16 GetUnmodifiedCharacter() const;
// Returns the copy of this key event. Used in NativeWebKeyboardEvent.
KeyEvent* Copy();
KeyboardCode key_code() const { return key_code_; }
bool is_char() const { return is_char_; }
// This is only intended to be used externally by classes that are modifying
// events in EventFilter::PreHandleKeyEvent(). set_character() should also be
// called.
void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }
private:
KeyboardCode key_code_;
// True if this is a translated character event (vs. a raw key down). Both
// share the same type: ET_KEY_PRESSED.
bool is_char_;
uint16 character_;
uint16 unmodified_character_;
};
// A key event which is translated by an input method (IME).
// For example, if an IME receives a KeyEvent(VKEY_SPACE), and it does not
// consume the key, the IME usually generates and dispatches a
// TranslatedKeyEvent(VKEY_SPACE) event. If the IME receives a KeyEvent and
// it does consume the event, it might dispatch a
// TranslatedKeyEvent(VKEY_PROCESSKEY) event as defined in the DOM spec.
class UI_EXPORT TranslatedKeyEvent : public KeyEvent {
public:
TranslatedKeyEvent(const base::NativeEvent& native_event, bool is_char);
// Used for synthetic events such as a VKEY_PROCESSKEY key event.
TranslatedKeyEvent(bool is_press, KeyboardCode key_code, int flags);
// Changes the type() of the object from ET_TRANSLATED_KEY_* to ET_KEY_* so
// that RenderWidgetHostViewAura and NativeWidgetAura could handle the event.
void ConvertToKeyEvent();
};
class UI_EXPORT DropTargetEvent : public LocatedEvent {
public:
DropTargetEvent(const OSExchangeData& data,
const gfx::Point& location,
const gfx::Point& root_location,
int source_operations)
: LocatedEvent(ET_DROP_TARGET_EVENT, location, root_location, 0),
data_(data),
source_operations_(source_operations) {
}
const OSExchangeData& data() const { return data_; }
int source_operations() const { return source_operations_; }
private:
// Data associated with the drag/drop session.
const OSExchangeData& data_;
// Bitmask of supported DragDropTypes::DragOperation by the source.
int source_operations_;
DISALLOW_COPY_AND_ASSIGN(DropTargetEvent);
};
class UI_EXPORT ScrollEvent : public MouseEvent {
public:
explicit ScrollEvent(const base::NativeEvent& native_event);
template <class T>
ScrollEvent(const ScrollEvent& model,
T* source,
T* target,
EventType type,
int flags)
: MouseEvent(model, source, target, type, flags),
x_offset_(model.x_offset_),
y_offset_(model.y_offset_) {
}
float x_offset() const { return x_offset_; }
float y_offset() const { return y_offset_; }
private:
float x_offset_;
float y_offset_;
DISALLOW_COPY_AND_ASSIGN(ScrollEvent);
};
// TODO(beng): rename to GestureEvent after conversion is complete.
class UI_EXPORT GestureEventImpl : public LocatedEvent,
public GestureEvent {
public:
GestureEventImpl(EventType type,
int x,
int y,
int flags,
base::Time time_stamp,
const GestureEventDetails& details,
unsigned int touch_ids_bitfield);
// Create a new GestureEventImpl which is identical to the provided model.
// If source / target windows are provided, the model location will be
// converted from |source| coordinate system to |target| coordinate system.
template <typename T>
GestureEventImpl(const GestureEventImpl& model, T* source, T* target)
: LocatedEvent(model, source, target),
details_(model.details_),
touch_ids_bitfield_(model.touch_ids_bitfield_) {
}
virtual ~GestureEventImpl();
const GestureEventDetails& details() const { return details_; }
// Returns the lowest touch-id of any of the touches which make up this
// gesture.
// If there are no touches associated with this gesture, returns -1.
virtual int GetLowestTouchId() const OVERRIDE;
private:
GestureEventDetails details_;
// The set of indices of ones in the binary representation of
// touch_ids_bitfield_ is the set of touch_ids associate with this gesture.
// This value is stored as a bitfield because the number of touch ids varies,
// but we currently don't need more than 32 touches at a time.
const unsigned int touch_ids_bitfield_;
DISALLOW_COPY_AND_ASSIGN(GestureEventImpl);
};
} // namespace ui
#endif // UI_BASE_EVENT_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/event.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(USE_X11)
#include <X11/Xlib.h>
#include "ui/base/x/x11_util.h"
#endif
namespace ui {
TEST(EventTest, NoNativeEvent) {
KeyEvent keyev(ET_KEY_PRESSED, VKEY_SPACE, 0);
EXPECT_FALSE(keyev.HasNativeEvent());
}
TEST(EventTest, NativeEvent) {
#if defined(OS_WIN)
MSG native_event = { NULL, WM_KEYUP, VKEY_A, 0 };
KeyEvent keyev(native_event, false);
EXPECT_TRUE(keyev.HasNativeEvent());
#elif defined(USE_X11)
scoped_ptr<XEvent> native_event(new XEvent);
InitXKeyEventForTesting(ET_KEY_RELEASED, VKEY_A, 0, native_event.get());
KeyEvent keyev(native_event.get(), false);
EXPECT_TRUE(keyev.HasNativeEvent());
#endif
}
TEST(EventTest, MAYBE_GetCharacter) {
// Check if Control+Enter returns 10.
KeyEvent keyev1(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN);
EXPECT_EQ(10, keyev1.GetCharacter());
EXPECT_EQ(13, keyev1.GetUnmodifiedCharacter());
// Check if Enter returns 13.
KeyEvent keyev2(ET_KEY_PRESSED, VKEY_RETURN, 0);
EXPECT_EQ(13, keyev2.GetCharacter());
EXPECT_EQ(13, keyev2.GetUnmodifiedCharacter());
#if defined(USE_X11)
// For X11, test the functions with native_event() as well. crbug.com/107837
scoped_ptr<XEvent> native_event(new XEvent);
InitXKeyEventForTesting(ET_KEY_PRESSED, VKEY_RETURN, EF_CONTROL_DOWN,
native_event.get());
KeyEvent keyev3(native_event.get(), false);
EXPECT_EQ(10, keyev3.GetCharacter());
EXPECT_EQ(13, keyev3.GetUnmodifiedCharacter());
InitXKeyEventForTesting(ET_KEY_PRESSED, VKEY_RETURN, 0, native_event.get());
KeyEvent keyev4(native_event.get(), false);
EXPECT_EQ(13, keyev4.GetCharacter());
EXPECT_EQ(13, keyev4.GetUnmodifiedCharacter());
#endif
}
TEST(EventTest, ClickCount) {
const gfx::Point origin(0, 0);
MouseEvent mouseev(ET_MOUSE_PRESSED, origin, origin, 0);
for (int i = 1; i <=3 ; ++i) {
mouseev.SetClickCount(i);
EXPECT_EQ(i, mouseev.GetClickCount());
}
}
TEST(EventTest, Repeated) {
const gfx::Point origin(0, 0);
MouseEvent mouse_ev1(ET_MOUSE_PRESSED, origin, origin, 0);
MouseEvent mouse_ev2(ET_MOUSE_PRESSED, origin, origin, 0);
MouseEvent::TestApi test_ev1(&mouse_ev1);
MouseEvent::TestApi test_ev2(&mouse_ev2);
base::TimeDelta start = base::TimeDelta::FromMilliseconds(0);
base::TimeDelta soon = start + base::TimeDelta::FromMilliseconds(1);
base::TimeDelta later = start + base::TimeDelta::FromMilliseconds(1000);
// Close point.
test_ev1.set_location(gfx::Point(0, 0));
test_ev2.set_location(gfx::Point(1, 0));
test_ev1.set_time_stamp(start);
test_ev2.set_time_stamp(soon);
EXPECT_TRUE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
// Too far.
test_ev1.set_location(gfx::Point(0, 0));
test_ev2.set_location(gfx::Point(10, 0));
test_ev1.set_time_stamp(start);
test_ev2.set_time_stamp(soon);
EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
// Too long a time between clicks.
test_ev1.set_location(gfx::Point(0, 0));
test_ev2.set_location(gfx::Point(0, 0));
test_ev1.set_time_stamp(start);
test_ev2.set_time_stamp(later);
EXPECT_FALSE(MouseEvent::IsRepeatedClickEvent(mouse_ev1, mouse_ev2));
}
} // namespace ui
...@@ -150,6 +150,8 @@ ...@@ -150,6 +150,8 @@
'base/dragdrop/os_exchange_data_provider_gtk.h', 'base/dragdrop/os_exchange_data_provider_gtk.h',
'base/dragdrop/os_exchange_data_provider_win.cc', 'base/dragdrop/os_exchange_data_provider_win.cc',
'base/dragdrop/os_exchange_data_provider_win.h', 'base/dragdrop/os_exchange_data_provider_win.h',
'base/event.cc',
'base/event.h',
'base/events.h', 'base/events.h',
'base/gestures/gesture_configuration.cc', 'base/gestures/gesture_configuration.cc',
'base/gestures/gesture_configuration.h', 'base/gestures/gesture_configuration.h',
...@@ -574,6 +576,8 @@ ...@@ -574,6 +576,8 @@
['exclude', '^base/dragdrop/os_exchange_data.h'], ['exclude', '^base/dragdrop/os_exchange_data.h'],
['exclude', '^base/dragdrop/os_exchange_data_provider_gtk.cc'], ['exclude', '^base/dragdrop/os_exchange_data_provider_gtk.cc'],
['exclude', '^base/dragdrop/os_exchange_data_provider_gtk.h'], ['exclude', '^base/dragdrop/os_exchange_data_provider_gtk.h'],
['exclude', '^base/event.cc'],
['exclude', '^base/event.h'],
], ],
}, { }, {
# Note: because of gyp predence rules this has to be defined as # Note: because of gyp predence rules this has to be defined as
......
...@@ -67,6 +67,7 @@ ...@@ -67,6 +67,7 @@
'base/cocoa/events_mac_unittest.mm', 'base/cocoa/events_mac_unittest.mm',
'base/cocoa/focus_tracker_unittest.mm', 'base/cocoa/focus_tracker_unittest.mm',
'base/dialogs/select_file_dialog_win_unittest.cc', 'base/dialogs/select_file_dialog_win_unittest.cc',
'base/event_unittest.cc',
'base/gtk/gtk_expanded_container_unittest.cc', 'base/gtk/gtk_expanded_container_unittest.cc',
'base/gtk/gtk_im_context_util_unittest.cc', 'base/gtk/gtk_im_context_util_unittest.cc',
'base/gtk/menu_label_accelerator_util_unittest.cc', 'base/gtk/menu_label_accelerator_util_unittest.cc',
...@@ -202,9 +203,14 @@ ...@@ -202,9 +203,14 @@
'gfx/render_text_unittest.cc', 'gfx/render_text_unittest.cc',
], ],
}], }],
['OS!="win" or use_aura==0', { ['toolkit_views==0', {
'sources!': [ 'sources!': [
'base/view_prop_unittest.cc', 'base/view_prop_unittest.cc',
'base/event_unittest.cc',
],
}, {
'sources': [
'base/gestures/velocity_calculator_unittest.cc',
], ],
}], }],
['use_aura==1', { ['use_aura==1', {
...@@ -215,11 +221,6 @@ ...@@ -215,11 +221,6 @@
'gfx/screen_unittest.cc', 'gfx/screen_unittest.cc',
], ],
}], }],
['use_aura==1 or toolkit_views==1', {
'sources': [
'base/gestures/velocity_calculator_unittest.cc',
],
}],
], ],
}, },
], ],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment