diff --git a/packages/flutter/lib/base/pointer_router.dart b/packages/flutter/lib/base/pointer_router.dart new file mode 100644 index 0000000000..5b12864d62 --- /dev/null +++ b/packages/flutter/lib/base/pointer_router.dart @@ -0,0 +1,40 @@ +// 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> _routeMap = new Map>(); + + 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; + } +} diff --git a/packages/flutter/lib/rendering/sky_binding.dart b/packages/flutter/lib/rendering/sky_binding.dart index 5eca6e8f34..0a4b0f689e 100644 --- a/packages/flutter/lib/rendering/sky_binding.dart +++ b/packages/flutter/lib/rendering/sky_binding.dart @@ -4,6 +4,7 @@ import 'dart:sky' as sky; +import 'package:sky/base/pointer_router.dart'; import 'package:sky/base/hit_test.dart'; import 'package:sky/base/scheduler.dart' as scheduler; import 'package:sky/rendering/box.dart'; @@ -92,6 +93,8 @@ class SkyBinding { } } + final PointerRouter pointerRouter = new PointerRouter(); + Map _stateForPointer = new Map(); PointerState _createStateForPointer(sky.PointerEvent event, Point position) { @@ -127,6 +130,7 @@ class SkyBinding { HitTestResult hitTest(Point position) { HitTestResult result = new HitTestResult(); + result.add(new HitTestEntry(pointerRouter)); _renderView.hitTest(result, position: position); return result; } diff --git a/packages/flutter/lib/widgets/drag_target.dart b/packages/flutter/lib/widgets/drag_target.dart index d7d6d5d1c3..63e8c1ec95 100644 --- a/packages/flutter/lib/widgets/drag_target.dart +++ b/packages/flutter/lib/widgets/drag_target.dart @@ -5,6 +5,7 @@ import 'dart:collection'; import 'package:sky/base/hit_test.dart'; +import 'package:sky/rendering/object.dart'; import 'package:sky/rendering/sky_binding.dart'; import 'package:sky/widgets/basic.dart'; import 'package:sky/widgets/framework.dart'; @@ -80,6 +81,8 @@ class DragController { DragTarget _getDragTarget(List path) { for (HitTestEntry entry in path.reversed) { + if (entry.target is! RenderObject) + continue; for (Widget widget in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) { if (widget is DragTarget) return widget; diff --git a/packages/flutter/lib/widgets/framework.dart b/packages/flutter/lib/widgets/framework.dart index 5859650745..9617933d27 100644 --- a/packages/flutter/lib/widgets/framework.dart +++ b/packages/flutter/lib/widgets/framework.dart @@ -1282,6 +1282,8 @@ class WidgetSkyBinding extends SkyBinding { if (disposition == EventDisposition.consumed) return EventDisposition.consumed; for (HitTestEntry entry in result.path.reversed) { + if (entry.target is! RenderObject) + continue; for (Widget target in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) { if (target is Listener) { EventDisposition targetDisposition = target._handleEvent(event);