Commit 45f2c589 authored by Adam Barth's avatar Adam Barth

Add PointerRouter

This patch is the first step towards implementing gestures. The pointer router
allows the gesture detectors to hook in at the end of the pointer event
propagation chain.

Related to #145
parent 338ca571
// 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 'dart:sky' as sky;
import 'package:sky/base/hit_test.dart';
typedef void _Route(sky.PointerEvent event);
class PointerRouter extends HitTestTarget {
final Map<int, List<_Route>> _routeMap = new Map<int, List<_Route>>();
void addRoute(int pointer, _Route route) {
List<_Route> routes = _routeMap.putIfAbsent(pointer, () => new List<_Route>());
assert(!routes.contains(route));
routes.add(route);
}
void removeRoute(int pointer, _Route route) {
assert(_routeMap.containsKey(pointer));
List<_Route> routes = _routeMap[pointer];
assert(routes.contains(route));
routes.remove(route);
if (routes.isEmpty)
_routeMap.remove(pointer);
}
EventDisposition handleEvent(sky.Event e, HitTestEntry entry) {
if (e is! sky.PointerEvent)
return EventDisposition.ignored;
sky.PointerEvent event = e;
List<_Route> routes = _routeMap[event.pointer];
if (routes == null)
return EventDisposition.ignored;
for (_Route route in new List<_Route>.from(routes))
route(event);
return EventDisposition.processed;
}
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'dart:sky' as sky; import 'dart:sky' as sky;
import 'package:sky/base/pointer_router.dart';
import 'package:sky/base/hit_test.dart'; import 'package:sky/base/hit_test.dart';
import 'package:sky/base/scheduler.dart' as scheduler; import 'package:sky/base/scheduler.dart' as scheduler;
import 'package:sky/rendering/box.dart'; import 'package:sky/rendering/box.dart';
...@@ -92,6 +93,8 @@ class SkyBinding { ...@@ -92,6 +93,8 @@ class SkyBinding {
} }
} }
final PointerRouter pointerRouter = new PointerRouter();
Map<int, PointerState> _stateForPointer = new Map<int, PointerState>(); Map<int, PointerState> _stateForPointer = new Map<int, PointerState>();
PointerState _createStateForPointer(sky.PointerEvent event, Point position) { PointerState _createStateForPointer(sky.PointerEvent event, Point position) {
...@@ -127,6 +130,7 @@ class SkyBinding { ...@@ -127,6 +130,7 @@ class SkyBinding {
HitTestResult hitTest(Point position) { HitTestResult hitTest(Point position) {
HitTestResult result = new HitTestResult(); HitTestResult result = new HitTestResult();
result.add(new HitTestEntry(pointerRouter));
_renderView.hitTest(result, position: position); _renderView.hitTest(result, position: position);
return result; return result;
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'dart:collection'; import 'dart:collection';
import 'package:sky/base/hit_test.dart'; import 'package:sky/base/hit_test.dart';
import 'package:sky/rendering/object.dart';
import 'package:sky/rendering/sky_binding.dart'; import 'package:sky/rendering/sky_binding.dart';
import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/basic.dart';
import 'package:sky/widgets/framework.dart'; import 'package:sky/widgets/framework.dart';
...@@ -80,6 +81,8 @@ class DragController { ...@@ -80,6 +81,8 @@ class DragController {
DragTarget _getDragTarget(List<HitTestEntry> path) { DragTarget _getDragTarget(List<HitTestEntry> path) {
for (HitTestEntry entry in path.reversed) { for (HitTestEntry entry in path.reversed) {
if (entry.target is! RenderObject)
continue;
for (Widget widget in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) { for (Widget widget in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) {
if (widget is DragTarget) if (widget is DragTarget)
return widget; return widget;
......
...@@ -1282,6 +1282,8 @@ class WidgetSkyBinding extends SkyBinding { ...@@ -1282,6 +1282,8 @@ class WidgetSkyBinding extends SkyBinding {
if (disposition == EventDisposition.consumed) if (disposition == EventDisposition.consumed)
return EventDisposition.consumed; return EventDisposition.consumed;
for (HitTestEntry entry in result.path.reversed) { for (HitTestEntry entry in result.path.reversed) {
if (entry.target is! RenderObject)
continue;
for (Widget target in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) { for (Widget target in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) {
if (target is Listener) { if (target is Listener) {
EventDisposition targetDisposition = target._handleEvent(event); EventDisposition targetDisposition = target._handleEvent(event);
......
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