Add wheel support to sky-scrollable

This CL plumbs wheel events through Sky again and uses them in sky-scrollable.

R=ojan@chromium.org

Review URL: https://codereview.chromium.org/876853005
This commit is contained in:
Adam Barth 2015-01-27 09:58:22 -08:00
parent f8aeeb7a7e
commit c3fc9e9663
11 changed files with 195 additions and 33 deletions

View File

@ -667,6 +667,8 @@ sky_core_files = [
"events/UIEvent.h",
"events/UIEventWithKeyState.cpp",
"events/UIEventWithKeyState.h",
"events/WheelEvent.cpp",
"events/WheelEvent.h",
"events/WindowEventContext.cpp",
"events/WindowEventContext.h",
"fetch/CachePolicy.h",
@ -1243,6 +1245,7 @@ core_idl_files = get_path_info([
"events/TextEvent.idl",
"events/TransitionEvent.idl",
"events/UIEvent.idl",
"events/WheelEvent.idl",
"frame/Console.idl",
"frame/ConsoleBase.idl",
"frame/ImageBitmap.idl",
@ -1334,6 +1337,7 @@ core_dependency_idl_files =
core_event_idl_files = get_path_info([
"css/FontFaceSetLoadEvent.idl",
"css/MediaQueryListEvent.idl",
"events/AnimationEvent.idl",
"events/AnimationPlayerEvent.idl",
"events/CompositionEvent.idl",
"events/CustomEvent.idl",
@ -1348,7 +1352,7 @@ core_event_idl_files = get_path_info([
"events/TextEvent.idl",
"events/TransitionEvent.idl",
"events/UIEvent.idl",
"events/AnimationEvent.idl",
"events/WheelEvent.idl",
"html/canvas/WebGLContextEvent.idl",
],
"abspath")

View File

@ -0,0 +1,43 @@
// Copyright 2015 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 "sky/engine/config.h"
#include "sky/engine/core/events/WheelEvent.h"
namespace blink {
WheelEvent::~WheelEvent()
{
}
const AtomicString& WheelEvent::interfaceName() const
{
return EventNames::WheelEvent;
}
WheelEvent::WheelEvent()
: WheelEvent(AtomicString(), WheelEventInit())
{
}
WheelEvent::WheelEvent(const WebWheelEvent& event)
: Event(EventTypeNames::wheel, true, true)
, m_x(event.x)
, m_y(event.y)
, m_offsetX(event.offsetX)
, m_offsetY(event.offsetY)
{
m_timeStamp = event.timeStampMS;
}
WheelEvent::WheelEvent(const AtomicString& type, const WheelEventInit& initializer)
: Event(type, initializer)
, m_x(initializer.x)
, m_y(initializer.y)
, m_offsetX(initializer.offsetX)
, m_offsetY(initializer.offsetY)
{
}
} // namespace blink

View File

@ -0,0 +1,57 @@
// Copyright 2015 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 SKY_ENGINE_CORE_EVENTS_WHEELEVENT_H_
#define SKY_ENGINE_CORE_EVENTS_WHEELEVENT_H_
#include "sky/engine/core/events/Event.h"
#include "sky/engine/public/platform/WebInputEvent.h"
namespace blink {
struct WheelEventInit : public EventInit {
double x = 0;
double y = 0;
double offsetX = 0;
double offsetY = 0;
};
class WheelEvent : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
static PassRefPtr<WheelEvent> create()
{
return adoptRef(new WheelEvent);
}
static PassRefPtr<WheelEvent> create(const WebWheelEvent& event)
{
return adoptRef(new WheelEvent(event));
}
static PassRefPtr<WheelEvent> create(const AtomicString& type, const WheelEventInit& initializer)
{
return adoptRef(new WheelEvent(type, initializer));
}
~WheelEvent() override;
const AtomicString& interfaceName() const override;
double x() const { return m_x; }
double y() const { return m_y; }
double offsetX() const { return m_offsetX; }
double offsetY() const { return m_offsetY; }
private:
WheelEvent();
explicit WheelEvent(const WebWheelEvent& event);
WheelEvent(const AtomicString&, const WheelEventInit&);
double m_x;
double m_y;
double m_offsetX;
double m_offsetY;
};
} // namespace blink
#endif // SKY_ENGINE_CORE_EVENTS_WHEELEVENT_H_

View File

@ -0,0 +1,12 @@
// Copyright 2015 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.
[
EventConstructor,
] interface WheelEvent : Event {
[InitializedByEventConstructor] readonly attribute double x;
[InitializedByEventConstructor] readonly attribute double y;
[InitializedByEventConstructor] readonly attribute double offsetX;
[InitializedByEventConstructor] readonly attribute double offsetY;
};

View File

@ -13,6 +13,7 @@
#include "sky/engine/core/events/GestureEvent.h"
#include "sky/engine/core/events/KeyboardEvent.h"
#include "sky/engine/core/events/PointerEvent.h"
#include "sky/engine/core/events/WheelEvent.h"
#include "sky/engine/core/frame/LocalFrame.h"
#include "sky/engine/core/frame/FrameView.h"
#include "sky/engine/core/rendering/RenderObject.h"
@ -95,6 +96,12 @@ bool NewEventHandler::dispatchKeyboardEvent(Node& target, const WebKeyboardEvent
return target.dispatchEvent(keyboardEvent.release());
}
bool NewEventHandler::dispatchWheelEvent(Node& target, const WebWheelEvent& event)
{
RefPtr<WheelEvent> wheelEvent = WheelEvent::create(event);
return target.dispatchEvent(wheelEvent.release());
}
bool NewEventHandler::dispatchClickEvent(Node& capturingTarget, const WebPointerEvent& event)
{
ASSERT(event.type == WebInputEvent::PointerUp);
@ -167,6 +174,13 @@ bool NewEventHandler::handleKeyboardEvent(const WebKeyboardEvent& event)
return handled;
}
bool NewEventHandler::handleWheelEvent(const WebWheelEvent& event)
{
HitTestResult hitTestResult = performHitTest(positionForEvent(event));
RefPtr<Node> target = targetForHitTestResult(hitTestResult);
return target && !dispatchWheelEvent(*target, event);
}
bool NewEventHandler::handlePointerDownEvent(const WebPointerEvent& event)
{
// In principle, we shouldn't get another pointer down for the same

View File

@ -17,6 +17,7 @@ class LocalFrame;
class WebGestureEvent;
class WebKeyboardEvent;
class WebPointerEvent;
class WebWheelEvent;
class NewEventHandler {
WTF_MAKE_NONCOPYABLE(NewEventHandler);
@ -27,6 +28,7 @@ public:
bool handlePointerEvent(const WebPointerEvent&);
bool handleGestureEvent(const WebGestureEvent&);
bool handleKeyboardEvent(const WebKeyboardEvent&);
bool handleWheelEvent(const WebWheelEvent&);
private:
bool handlePointerDownEvent(const WebPointerEvent&);
@ -38,6 +40,7 @@ private:
bool dispatchPointerEvent(Node& target, const WebPointerEvent&);
bool dispatchClickEvent(Node& capturingTarget, const WebPointerEvent&);
bool dispatchKeyboardEvent(Node& target, const WebKeyboardEvent& event);
bool dispatchWheelEvent(Node& target, const WebWheelEvent& event);
Node* targetForKeyboardEvent() const;
Node* targetForHitTestResult(const HitTestResult& hitTestResult);

View File

@ -121,6 +121,8 @@ public:
GesturePinchEnd,
GesturePinchUpdate,
GestureTypeLast = GesturePinchUpdate,
WheelEvent,
};
enum Modifiers {
@ -170,18 +172,21 @@ public:
return PointerTypeFirst <= type && type <= PointerTypeLast;
}
// Returns true if the WebInputEvent |type| is a keyboard event.
static bool isKeyboardEventType(int type)
{
return KeyboardTypeFirst <= type && type <= KeyboardTypeLast;
}
// Returns true if the WebInputEvent is a gesture event.
static bool isGestureEventType(int type)
{
return GestureTypeFirst <= type && type <= GestureTypeLast;
}
static bool isWheelEventType(int type)
{
return type == WheelEvent;
}
protected:
explicit WebInputEvent(unsigned sizeParam)
{
@ -238,32 +243,35 @@ public:
// what is returned by the Windows API. For example, it should
// store VK_SHIFT instead of VK_RSHIFT. The location information
// should be stored in |modifiers|.
int key;
int key = 0;
// |charCode| is the text generated by this keystroke. |unmodifiedCharCode|
// is |charCode|, but unmodified by an concurrently-held modifiers (except
// shift). This is useful for working out shortcut keys.
WebUChar charCode;
WebUChar unmodifiedCharCode;
WebUChar charCode = 0;
WebUChar unmodifiedCharCode = 0;
WebKeyboardEvent()
: WebInputEvent(sizeof(WebKeyboardEvent))
, key(0)
, charCode(0)
, unmodifiedCharCode(0)
{
}
WebKeyboardEvent() : WebInputEvent(sizeof(WebKeyboardEvent)) {}
};
// WebGestureEvent --------------------------------------------------------------
// WebWheelEvent --------------------------------------------------------------
class WebWheelEvent : public WebInputEvent {
public:
float x = 0;
float y = 0;
float offsetX = 0;
float offsetY = 0;
WebWheelEvent() : WebInputEvent(sizeof(WebWheelEvent)) {}
};
// WebGestureEvent ------------------------------------------------------------
class WebGestureEvent : public WebInputEvent {
public:
int x;
int y;
int globalX;
int globalY;
WebGestureDevice sourceDevice;
float x = 0;
float y = 0;
union {
// Tap information must be set for GestureTap, GestureTapUnconfirmed,
@ -320,10 +328,6 @@ public:
WebGestureEvent()
: WebInputEvent(sizeof(WebGestureEvent))
, x(0)
, y(0)
, globalX(0)
, globalY(0)
{
memset(&data, 0, sizeof(data));
}

View File

@ -339,6 +339,11 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent)
return m_page->mainFrame()->newEventHandler().handleKeyboardEvent(event);
}
if (WebInputEvent::isWheelEventType(inputEvent.type)) {
const WebWheelEvent& event = static_cast<const WebWheelEvent&>(inputEvent);
return m_page->mainFrame()->newEventHandler().handleWheelEvent(event);
}
return false;
}

View File

@ -32,7 +32,7 @@
<script>
module.exports = class extends SkyElement {
created() {
this.cities = cities;
this.cities = cities.slice(0, 300);
}
}.register();
</script>

View File

@ -12,7 +12,8 @@
on-gesturescrollend="handleScrollEnd_"
on-gesturescrollupdate="handleScrollUpdate_"
on-gestureflingstart="handleFlingStart_"
on-gestureflingcancel="handleFlingCancel_">
on-gestureflingcancel="handleFlingCancel_"
on-wheel="handleWheel_">
<template>
<style>
:host {
@ -115,6 +116,10 @@ module.exports = class extends SkyElement {
handleFlingCancel_(event) {
this.stopFling_();
}
handleWheel_(event) {
this.scrollBy(-event.offsetY);
}
}.register();
</script>
</sky-element>

View File

@ -165,14 +165,6 @@ scoped_ptr<blink::WebInputEvent> BuildWebGestureEvent(
web_event->x = event->location_data->in_view_location->x / device_pixel_ratio;
web_event->y = event->location_data->in_view_location->y / device_pixel_ratio;
// TODO(erg): Remove this null check as parallel to above.
if (!event->location_data->screen_location.is_null()) {
web_event->globalX =
event->location_data->screen_location->x / device_pixel_ratio;
web_event->globalY =
event->location_data->screen_location->y / device_pixel_ratio;
}
return web_event.Pass();
}
@ -204,6 +196,26 @@ scoped_ptr<blink::WebInputEvent> BuildWebKeyboardEvent(
return web_event.Pass();
}
scoped_ptr<blink::WebInputEvent> BuildWebWheelEvent(
const mojo::EventPtr& event, float device_pixel_ratio) {
scoped_ptr<blink::WebWheelEvent> web_event(new blink::WebWheelEvent);
web_event->modifiers = EventFlagsToWebInputEventModifiers(event->flags);
web_event->timeStampMS =
base::TimeDelta::FromInternalValue(event->time_stamp).InMillisecondsF();
web_event->type = blink::WebInputEvent::WheelEvent;
const auto& location = event->location_data->in_view_location;
web_event->x = location->x / device_pixel_ratio;
web_event->y = location->y / device_pixel_ratio;
web_event->offsetX = event->wheel_data->x_offset / device_pixel_ratio;
web_event->offsetY = event->wheel_data->y_offset / device_pixel_ratio;
return web_event.Pass();
}
} // namespace
scoped_ptr<blink::WebInputEvent> ConvertEvent(const mojo::EventPtr& event,
@ -242,6 +254,9 @@ scoped_ptr<blink::WebInputEvent> ConvertEvent(const mojo::EventPtr& event,
event->action == mojo::EVENT_TYPE_KEY_RELEASED) &&
event->key_data) {
return BuildWebKeyboardEvent(event, device_pixel_ratio);
} else if (event->action == mojo::EVENT_TYPE_MOUSEWHEEL &&
event->wheel_data) {
return BuildWebWheelEvent(event, device_pixel_ratio);
}
return scoped_ptr<blink::WebInputEvent>();