提交 8bdad978 编写于 作者: A Adam Barth

Port touch-demo.sky to Dart and make it work in SkyShell

We still don't quite handle multitouch correctly, but single touches work now.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/932283002
上级 cf2f7afb
#!mojo mojo:sky_viewer
<sky>
<import src="fps-counter.sky" />
<style>
dot {
position: absolute;
......@@ -11,25 +10,23 @@ dot {
</style>
<dot />
<log>Ready</log>
<fps-counter />
<script>
var dot = document.querySelector("dot");
var log = document.querySelector("log");
import "dart:sky";
function logPointerEvent(evt) {
var message = "type=" + event.type;
var x = evt.x.toFixed(2);
var y = evt.y.toFixed(2);
message += " x=" + x + " y=" + y;
final Element dot = document.querySelector("dot");
var transform = "translate(" + (x - 50) + "px," + (y - 50) + "px)";
dot.style.transform = transform;
log.textContent = message;
void moveDot(event) {
double x = event.x;
double y = event.y;
dot.style.setProperty("transform", "translate(${x-50}px,${y-50}px)");
}
document.documentElement.addEventListener("pointerdown", logPointerEvent);
document.documentElement.addEventListener("pointermove", logPointerEvent);
document.documentElement.addEventListener("pointerup", logPointerEvent);
document.documentElement.addEventListener("pointercancel", logPointerEvent);
void main() {
document.addEventListener("pointerdown", moveDot);
document.addEventListener("pointermove", moveDot);
document.addEventListener("pointerup", moveDot);
document.addEventListener("pointercancel", moveDot);
}
</script>
</sky>
# 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.
import("//mojo/public/tools/bindings/mojom.gni")
mojom("viewport") {
sources = [
"input_event.mojom",
"viewport_observer.mojom",
]
}
// 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.
module sky;
enum EventType {
UNKNOWN,
POINTER_DOWN,
POINTER_UP,
POINTER_MOVE,
POINTER_CANCEL,
};
enum PointerKind {
TOUCH,
};
struct PointerData {
int32 pointer;
PointerKind kind;
float x;
float y;
int32 buttons;
float pressure;
float pressure_min;
float pressure_max;
float distance;
float distance_min;
float distance_max;
float radius_major;
float radius_minor;
float radius_min;
float radius_max;
float orientation;
float tilt;
};
struct InputEvent {
EventType type;
int64 time_stamp;
PointerData? pointer_data;
};
// 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.
module sky;
import "sky/services/viewport/input_event.mojom";
interface ViewportObserver {
OnViewportMetricsChanged(int32 width, int32 height, float device_pixel_ratio);
OnInputEvent(InputEvent event);
};
......@@ -45,6 +45,8 @@ shared_library("sky_shell") {
"ui/animator.h",
"ui/engine.cc",
"ui/engine.h",
"ui/input_event_converter.cc",
"ui/input_event_converter.h",
"ui/platform_impl.cc",
"ui/platform_impl.h",
"ui_delegate.cc",
......@@ -63,6 +65,7 @@ shared_library("sky_shell") {
"//mojo/services/network/public/interfaces",
"//skia",
"//sky/engine",
"//sky/services/viewport",
"//ui/gfx/geometry",
"//ui/gl",
":jni_headers",
......@@ -86,6 +89,7 @@ android_library("java") {
"//mojo/public/java:system",
"//mojo/services/network/public/interfaces:interfaces_java",
"//sky/services/oknet",
"//sky/services/viewport:viewport_java",
]
}
......
......@@ -5,12 +5,22 @@
package org.domokit.sky.shell;
import android.content.Context;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import org.chromium.base.JNINamespace;
import org.chromium.mojo.bindings.InterfaceRequest;
import org.chromium.mojo.system.Core;
import org.chromium.mojo.system.Pair;
import org.chromium.mojo.system.impl.CoreImpl;
import org.chromium.mojom.sky.EventType;
import org.chromium.mojom.sky.InputEvent;
import org.chromium.mojom.sky.PointerData;
import org.chromium.mojom.sky.PointerKind;
import org.chromium.mojom.sky.ViewportObserver;
/**
* A view containing Sky
......@@ -18,6 +28,7 @@ import org.chromium.base.JNINamespace;
@JNINamespace("sky::shell")
public class PlatformView extends SurfaceView {
private long mNativePlatformView;
private ViewportObserver.Proxy mViewportObserver;
private final SurfaceHolder.Callback mSurfaceCallback;
public PlatformView(Context context) {
......@@ -26,7 +37,7 @@ public class PlatformView extends SurfaceView {
setFocusable(true);
setFocusableInTouchMode(true);
mNativePlatformView = nativeAttach();
attach();
assert mNativePlatformView != 0;
final float density = context.getResources().getDisplayMetrics().density;
......@@ -34,8 +45,8 @@ public class PlatformView extends SurfaceView {
mSurfaceCallback = new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
assert mNativePlatformView != 0;
nativeSurfaceSetSize(mNativePlatformView, width, height, density);
assert mViewportObserver != null;
mViewportObserver.onViewportMetricsChanged(width, height, density);
}
@Override
......@@ -69,10 +80,45 @@ public class PlatformView extends SurfaceView {
}
}
private static native long nativeAttach();
private int getTypeForAction(int maskedAction) {
if (maskedAction == MotionEvent.ACTION_DOWN)
return EventType.POINTER_DOWN;
if (maskedAction == MotionEvent.ACTION_UP)
return EventType.POINTER_UP;
if (maskedAction == MotionEvent.ACTION_MOVE)
return EventType.POINTER_MOVE;
if (maskedAction == MotionEvent.ACTION_CANCEL)
return EventType.POINTER_CANCEL;
return EventType.UNKNOWN;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
PointerData pointerData = new PointerData();
pointerData.pointer = event.getPointerId(0);
pointerData.kind = PointerKind.TOUCH;
pointerData.x = event.getX();
pointerData.y = event.getY();
InputEvent inputEvent = new InputEvent();
inputEvent.type = getTypeForAction(event.getActionMasked());
inputEvent.timeStamp = event.getEventTime();
inputEvent.pointerData = pointerData;
mViewportObserver.onInputEvent(inputEvent);
return true;
}
private void attach() {
Core core = CoreImpl.getInstance();
Pair<ViewportObserver.Proxy, InterfaceRequest<ViewportObserver>> result =
ViewportObserver.MANAGER.getInterfaceRequest(core);
mViewportObserver = result.first;
mNativePlatformView = nativeAttach(result.second.passHandle().releaseNativeHandle());
}
private static native long nativeAttach(int inputObserverHandle);
private static native void nativeDetach(long nativePlatformView);
private static native void nativeSurfaceCreated(long nativePlatformView, Surface surface);
private static native void nativeSurfaceDestroyed(long nativePlatformView);
private static native void nativeSurfaceSetSize(
long nativePlatformView, int width, int height, float density);
}
......@@ -16,8 +16,12 @@
namespace sky {
namespace shell {
static jlong Attach(JNIEnv* env, jclass clazz) {
return reinterpret_cast<jlong>(Shell::Shared().view());
static jlong Attach(JNIEnv* env, jclass clazz, jint viewportObserverHandle) {
PlatformView* view = Shell::Shared().view();
view->ConnectToViewportObserver(
mojo::MakeRequest<ViewportObserver>(mojo::ScopedMessagePipeHandle(
mojo::MessagePipeHandle(viewportObserverHandle))));
return reinterpret_cast<jlong>(view);
}
// static
......@@ -34,6 +38,14 @@ PlatformView::~PlatformView() {
ReleaseWindow();
}
void PlatformView::ConnectToViewportObserver(
mojo::InterfaceRequest<ViewportObserver> request) {
config_.ui_task_runner->PostTask(
FROM_HERE,
base::Bind(&UIDelegate::ConnectToViewportObserver, config_.ui_delegate,
base::Passed(&request)));
}
void PlatformView::Detach(JNIEnv* env, jobject obj) {
DCHECK(!window_);
}
......@@ -60,17 +72,6 @@ void PlatformView::SurfaceDestroyed(JNIEnv* env, jobject obj) {
ReleaseWindow();
}
void PlatformView::SurfaceSetSize(JNIEnv* env,
jobject obj,
jint width,
jint height,
jfloat density) {
config_.ui_task_runner->PostTask(
FROM_HERE,
base::Bind(&UIDelegate::OnViewportMetricsChanged, config_.ui_delegate,
gfx::Size(width, height), density));
}
void PlatformView::ReleaseWindow() {
ANativeWindow_release(window_);
window_ = nullptr;
......
......@@ -33,6 +33,9 @@ class PlatformView {
explicit PlatformView(const Config& config);
~PlatformView();
void ConnectToViewportObserver(
mojo::InterfaceRequest<ViewportObserver> request);
// Called from Java
void Detach(JNIEnv* env, jobject obj);
void SurfaceCreated(JNIEnv* env, jobject obj, jobject jsurface);
......
......@@ -5,10 +5,12 @@
#include "sky/shell/ui/engine.h"
#include "base/bind.h"
#include "sky/engine/public/platform/WebInputEvent.h"
#include "sky/engine/public/web/Sky.h"
#include "sky/engine/public/web/WebLocalFrame.h"
#include "sky/engine/public/web/WebView.h"
#include "sky/shell/ui/animator.h"
#include "sky/shell/ui/input_event_converter.h"
#include "sky/shell/ui/platform_impl.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
......@@ -19,6 +21,8 @@ namespace shell {
Engine::Engine(const Config& config)
: animator_(new Animator(config, this)),
web_view_(nullptr),
device_pixel_ratio_(1.0f),
viewport_observer_binding_(this),
weak_factory_(this) {
}
......@@ -39,7 +43,7 @@ void Engine::Init(mojo::ScopedMessagePipeHandle service_provider) {
web_view_ = blink::WebView::create(this);
web_view_->setMainFrame(blink::WebLocalFrame::create(this));
web_view_->mainFrame()->load(
GURL("http://127.0.0.1:8000/sky/examples/spinning-square.sky"));
GURL("http://domokit.github.io/sky/examples/spinning-square.sky"));
}
void Engine::BeginFrame(base::TimeTicks frame_time) {
......@@ -63,16 +67,30 @@ skia::RefPtr<SkPicture> Engine::Paint() {
return skia::AdoptRef(recorder.endRecordingAsPicture());
}
void Engine::OnViewportMetricsChanged(const gfx::Size& physical_size,
void Engine::ConnectToViewportObserver(
mojo::InterfaceRequest<ViewportObserver> request) {
viewport_observer_binding_.Bind(request.Pass());
}
void Engine::OnViewportMetricsChanged(int width, int height,
float device_pixel_ratio) {
physical_size_ = physical_size;
physical_size_.SetSize(width, height);
device_pixel_ratio_ = device_pixel_ratio;
web_view_->setDeviceScaleFactor(device_pixel_ratio);
gfx::SizeF size = gfx::ScaleSize(physical_size, 1 / device_pixel_ratio);
gfx::SizeF size = gfx::ScaleSize(physical_size_, 1 / device_pixel_ratio);
// FIXME: We should be able to set the size of the WebView in floating point
// because its in logical pixels.
web_view_->resize(blink::WebSize(size.width(), size.height()));
}
void Engine::OnInputEvent(InputEventPtr event) {
scoped_ptr<blink::WebInputEvent> web_event =
ConvertEvent(event, device_pixel_ratio_);
if (!web_event)
return;
web_view_->handleInputEvent(*web_event);
}
void Engine::initializeLayerTreeView() {
}
......
......@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/system/core.h"
#include "skia/ext/refptr.h"
#include "sky/engine/public/web/WebFrameClient.h"
......@@ -24,6 +25,7 @@ class Animator;
class PlatformImpl;
class Engine : public UIDelegate,
public ViewportObserver,
public blink::WebFrameClient,
public blink::WebViewClient {
public:
......@@ -44,8 +46,13 @@ class Engine : public UIDelegate,
private:
// UIDelegate methods:
void OnViewportMetricsChanged(const gfx::Size& physical_size,
void ConnectToViewportObserver(
mojo::InterfaceRequest<ViewportObserver> request) override;
// ViewportObserver:
void OnViewportMetricsChanged(int width, int height,
float device_pixel_ratio) override;
void OnInputEvent(InputEventPtr event) override;
// WebViewClient methods:
void initializeLayerTreeView() override;
......@@ -54,7 +61,9 @@ class Engine : public UIDelegate,
scoped_ptr<PlatformImpl> platform_impl_;
scoped_ptr<Animator> animator_;
blink::WebView* web_view_;
float device_pixel_ratio_;
gfx::Size physical_size_;
mojo::Binding<ViewportObserver> viewport_observer_binding_;
base::WeakPtrFactory<Engine> weak_factory_;
......
// Copyright 2014 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/shell/ui/input_event_converter.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "sky/engine/public/platform/WebInputEvent.h"
namespace sky {
namespace {
scoped_ptr<blink::WebInputEvent> BuildWebPointerEvent(
const InputEventPtr& event, float device_pixel_ratio) {
scoped_ptr<blink::WebPointerEvent> web_event(new blink::WebPointerEvent);
web_event->timeStampMS =
base::TimeDelta::FromInternalValue(event->time_stamp).InMillisecondsF();
switch (event->type) {
case EVENT_TYPE_POINTER_DOWN:
web_event->type = blink::WebInputEvent::PointerDown;
break;
case EVENT_TYPE_POINTER_UP:
web_event->type = blink::WebInputEvent::PointerUp;
break;
case EVENT_TYPE_POINTER_MOVE:
web_event->type = blink::WebInputEvent::PointerMove;
break;
case EVENT_TYPE_POINTER_CANCEL:
web_event->type = blink::WebInputEvent::PointerCancel;
break;
default:
NOTIMPLEMENTED() << "Received unexpected event: " << event->type;
break;
}
if (event->pointer_data) {
if (event->pointer_data->kind == POINTER_KIND_TOUCH)
web_event->kind = blink::WebPointerEvent::Touch;
web_event->pointer = event->pointer_data->pointer;
web_event->x = event->pointer_data->x / device_pixel_ratio;
web_event->y = event->pointer_data->y / device_pixel_ratio;
}
return web_event.Pass();
}
} // namespace
scoped_ptr<blink::WebInputEvent> ConvertEvent(const InputEventPtr& event,
float device_pixel_ratio) {
if (event->type == EVENT_TYPE_POINTER_DOWN ||
event->type == EVENT_TYPE_POINTER_UP ||
event->type == EVENT_TYPE_POINTER_MOVE ||
event->type == EVENT_TYPE_POINTER_CANCEL) {
return BuildWebPointerEvent(event, device_pixel_ratio);
}
return scoped_ptr<blink::WebInputEvent>();
}
} // namespace mojo
// 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_SHELL_UI_INPUT_EVENT_CONVERTER_H_
#define SKY_SHELL_UI_INPUT_EVENT_CONVERTER_H_
#include "base/memory/scoped_ptr.h"
#include "sky/services/viewport/input_event.mojom.h"
namespace blink {
class WebInputEvent;
}
namespace sky {
scoped_ptr<blink::WebInputEvent> ConvertEvent(const InputEventPtr& event,
float device_pixel_ratio);
}
#endif // SKY_SHELL_UI_INPUT_EVENT_CONVERTER_H_
......@@ -5,6 +5,8 @@
#ifndef SKY_SHELL_UI_DELEGATE_H_
#define SKY_SHELL_UI_DELEGATE_H_
#include "mojo/public/cpp/bindings/interface_request.h"
#include "sky/services/viewport/viewport_observer.mojom.h"
#include "ui/gfx/geometry/size.h"
namespace sky {
......@@ -12,8 +14,8 @@ namespace shell {
class UIDelegate {
public:
virtual void OnViewportMetricsChanged(const gfx::Size& size,
float device_pixel_ratio) = 0;
virtual void ConnectToViewportObserver(
mojo::InterfaceRequest<ViewportObserver> request) = 0;
protected:
virtual ~UIDelegate();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册