From 302138145647a230598a83c74e6b8a51329148f4 Mon Sep 17 00:00:00 2001 From: Kris Giesing Date: Fri, 9 Oct 2015 11:14:15 -0700 Subject: [PATCH] Add hold and sweep semantics to gesture arena --- packages/flutter/lib/src/gestures/arena.dart | 27 +++++++++++++++++++ .../flutter/lib/src/rendering/binding.dart | 2 ++ 2 files changed, 29 insertions(+) diff --git a/packages/flutter/lib/src/gestures/arena.dart b/packages/flutter/lib/src/gestures/arena.dart index 17e70da4ec..d9fee7f63e 100644 --- a/packages/flutter/lib/src/gestures/arena.dart +++ b/packages/flutter/lib/src/gestures/arena.dart @@ -45,6 +45,7 @@ class GestureArenaEntry { class _GestureArenaState { final List members = new List(); bool isOpen = true; + bool isHeld = false; void add(GestureArenaMember member) { assert(isOpen); @@ -72,6 +73,32 @@ class GestureArena { _tryToResolveArena(key, state); } + /// Force resolution on this arena, giving the win to the first member + void sweep(Object key) { + _GestureArenaState state = _arenas[key]; + if (state == null) + return; // This arena either never existed or has been resolved. + assert(!state.isOpen); + if (state.isHeld) + return; // This arena is being held for a long-lived member + if (!state.members.isEmpty) { + // First member wins + state.members.first.acceptGesture(key); + // Give all the other members the bad news + for (int i = 1; i < state.members.length; i++) + state.members[i].rejectGesture(key); + } + _arenas.remove(key); + } + + /// Prevent the arena from being swept + void hold(Object key) { + _GestureArenaState state = _arenas[key]; + if (state == null) + return; // This arena either never existed or has been resolved. + state.isHeld = true; + } + void _tryToResolveArena(Object key, _GestureArenaState state) { assert(_arenas[key] == state); assert(!state.isOpen); diff --git a/packages/flutter/lib/src/rendering/binding.dart b/packages/flutter/lib/src/rendering/binding.dart index 7de8a4ebe7..bbc9c6cc87 100644 --- a/packages/flutter/lib/src/rendering/binding.dart +++ b/packages/flutter/lib/src/rendering/binding.dart @@ -167,6 +167,8 @@ class FlutterBinding extends HitTestTarget { pointerRouter.route(event); if (event.type == 'pointerdown') GestureArena.instance.close(event.pointer); + else if (event.type == 'pointerup') + GestureArena.instance.sweep(event.pointer); } } }