Implement PointerEvent#dx

In this CL, the event handler keeps track of the delta from the previous
pointer position so authors don't have to.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/887793002
This commit is contained in:
Adam Barth 2015-01-29 13:23:45 -08:00
parent be00ee1268
commit 36e9c3e46e
6 changed files with 44 additions and 37 deletions

View File

@ -55,8 +55,8 @@ PointerEvent::PointerEvent(const WebPointerEvent& event)
, m_kind(stringForKind(event.kind))
, m_x(event.x)
, m_y(event.y)
, m_dx(event.dx)
, m_dy(event.dy)
, m_dx(0)
, m_dy(0)
, m_buttons(event.buttons)
, m_down(false)
, m_primary(false)

View File

@ -77,6 +77,9 @@ public:
double orientation() const { return m_orientation; }
double tilt() const { return m_tilt; }
void setDX(double dx) { m_dx = dx; }
void setDY(double dy) { m_dy = dy; }
private:
PointerEvent();
explicit PointerEvent(const WebPointerEvent& event);

View File

@ -76,12 +76,16 @@ HitTestResult NewEventHandler::performHitTest(const LayoutPoint& point)
return result;
}
bool NewEventHandler::dispatchPointerEvent(Node& target, const WebPointerEvent& event)
bool NewEventHandler::dispatchPointerEvent(PointerState& state, const WebPointerEvent& event)
{
RefPtr<PointerEvent> pointerEvent = PointerEvent::create(event);
pointerEvent->setDX(event.x - state.x);
pointerEvent->setDY(event.y - state.y);
state.x = event.x;
state.y = event.y;
// TODO(abarth): Keep track of how many pointers are targeting the same node
// and only mark the first one as primary.
return target.dispatchEvent(pointerEvent.release());
return state.target->dispatchEvent(pointerEvent.release());
}
bool NewEventHandler::dispatchGestureEvent(Node& target, const WebGestureEvent& event)
@ -188,19 +192,20 @@ bool NewEventHandler::handlePointerDownEvent(const WebPointerEvent& event)
// drag outside the window frame on Linux. For now, send the pointer
// cancel at this point.
if (event.kind == WebPointerEvent::Mouse
&& m_targetForPointer.find(event.pointer) != m_targetForPointer.end()) {
&& m_stateForPointer.find(event.pointer) != m_stateForPointer.end()) {
WebPointerEvent fakeCancel = event;
fakeCancel.type = WebInputEvent::PointerCancel;
handlePointerCancelEvent(fakeCancel);
}
ASSERT(m_targetForPointer.find(event.pointer) == m_targetForPointer.end());
ASSERT(m_stateForPointer.find(event.pointer) == m_stateForPointer.end());
HitTestResult hitTestResult = performHitTest(positionForEvent(event));
RefPtr<Node> target = targetForHitTestResult(hitTestResult);
if (!target)
return false;
m_targetForPointer[event.pointer] = target;
bool eventSwallowed = !dispatchPointerEvent(*target, event);
PointerState& state = m_stateForPointer[event.pointer];
state.target = target;
bool eventSwallowed = !dispatchPointerEvent(state, event);
// TODO(abarth): Set the target for the pointer to something determined when
// dispatching the event.
updateSelectionForPointerDown(hitTestResult, event);
@ -209,40 +214,40 @@ bool NewEventHandler::handlePointerDownEvent(const WebPointerEvent& event)
bool NewEventHandler::handlePointerUpEvent(const WebPointerEvent& event)
{
auto it = m_targetForPointer.find(event.pointer);
if (it == m_targetForPointer.end())
auto it = m_stateForPointer.find(event.pointer);
if (it == m_stateForPointer.end())
return false;
RefPtr<Node> target = it->second;
m_targetForPointer.erase(it);
ASSERT(target);
bool eventSwallowed = !dispatchPointerEvent(*target, event);
PointerState stateCopy = it->second;
m_stateForPointer.erase(it);
ASSERT(stateCopy.target);
bool eventSwallowed = !dispatchPointerEvent(stateCopy, event);
// When the user releases the primary pointer, we need to dispatch a tap
// event to the common ancestor for where the pointer went down and where
// it came up.
if (!dispatchClickEvent(*target, event))
if (!eventSwallowed && !dispatchClickEvent(*stateCopy.target, event))
eventSwallowed = true;
return eventSwallowed;
}
bool NewEventHandler::handlePointerMoveEvent(const WebPointerEvent& event)
{
auto it = m_targetForPointer.find(event.pointer);
if (it == m_targetForPointer.end())
auto it = m_stateForPointer.find(event.pointer);
if (it == m_stateForPointer.end())
return false;
RefPtr<Node> target = it->second;
ASSERT(target);
return dispatchPointerEvent(*target.get(), event);
PointerState& state = it->second;
ASSERT(state.target);
return dispatchPointerEvent(state, event);
}
bool NewEventHandler::handlePointerCancelEvent(const WebPointerEvent& event)
{
auto it = m_targetForPointer.find(event.pointer);
if (it == m_targetForPointer.end())
auto it = m_stateForPointer.find(event.pointer);
if (it == m_stateForPointer.end())
return false;
RefPtr<Node> target = it->second;
m_targetForPointer.erase(it);
ASSERT(target);
return dispatchPointerEvent(*target, event);
PointerState stateCopy = it->second;
m_stateForPointer.erase(it);
ASSERT(stateCopy.target);
return dispatchPointerEvent(stateCopy, event);
}
}

View File

@ -31,13 +31,19 @@ public:
bool handleWheelEvent(const WebWheelEvent&);
private:
struct PointerState {
RefPtr<Node> target;
double x = 0;
double y = 0;
};
bool handlePointerDownEvent(const WebPointerEvent&);
bool handlePointerUpEvent(const WebPointerEvent&);
bool handlePointerMoveEvent(const WebPointerEvent&);
bool handlePointerCancelEvent(const WebPointerEvent&);
bool dispatchGestureEvent(Node& target, const WebGestureEvent& event);
bool dispatchPointerEvent(Node& target, const WebPointerEvent&);
bool dispatchPointerEvent(PointerState& state, const WebPointerEvent&);
bool dispatchClickEvent(Node& capturingTarget, const WebPointerEvent&);
bool dispatchKeyboardEvent(Node& target, const WebKeyboardEvent& event);
bool dispatchWheelEvent(Node& target, const WebWheelEvent& event);
@ -47,10 +53,10 @@ private:
HitTestResult performHitTest(const LayoutPoint&);
void updateSelectionForPointerDown(const HitTestResult&, const WebPointerEvent&);
typedef std::map<int, RefPtr<Node>> PointerTargetMap;
typedef std::map<int, PointerState> PointerStateMap;
LocalFrame& m_frame;
PointerTargetMap m_targetForPointer;
PointerStateMap m_stateForPointer;
bool m_suppressNextCharEvent;
};

View File

@ -212,8 +212,6 @@ public:
Kind kind = Touch;
float x = 0;
float y = 0;
float dx = 0;
float dy = 0;
int buttons = 0;
float pressure = 0;
float pressureMin = 0;

View File

@ -48,7 +48,6 @@ const kAnimationCurve = Curves.easeInOut;
module.exports = class extends SkyElement {
created() {
this.previousX_ = 0;
this.position_ = 0;
this.mask_ = null;
this.content_ = null;
@ -125,14 +124,10 @@ module.exports = class extends SkyElement {
handlePointerDown(event) {
this.animation_.stop();
this.previousX_ = event.x;
}
handlePointerMove(event) {
// TODO(abarth): Implement event.dx;
var deltaX = event.x - this.previousX_;
this.previousX_ = event.x;
this.position += deltaX;
this.position += event.dx;
}
handlePointerUp(event) {