diff --git a/sky/packages/sky/example/demo_launcher/lib/main.dart b/sky/packages/sky/example/demo_launcher/lib/main.dart index c1458a24f2d..b2e550513c1 100644 --- a/sky/packages/sky/example/demo_launcher/lib/main.dart +++ b/sky/packages/sky/example/demo_launcher/lib/main.dart @@ -18,7 +18,7 @@ AssetBundle _initBundle() { final AssetBundle _bundle = _initBundle(); -void launch(String relativeUrl, String bundle) { +EventDisposition launch(String relativeUrl, String bundle) { // TODO(eseidel): This is a hack to keep non-skyx examples working for now: Uri productionBase = Uri.parse( 'https://domokit.github.io/example/demo_launcher/lib/main.dart'); @@ -42,6 +42,7 @@ void launch(String relativeUrl, String bundle) { } activity.startActivity(intent); + return EventDisposition.processed; } class SkyDemo { diff --git a/sky/packages/sky/example/fitness/lib/feed.dart b/sky/packages/sky/example/fitness/lib/feed.dart index c68e5ec316e..1bfc9104891 100644 --- a/sky/packages/sky/example/fitness/lib/feed.dart +++ b/sky/packages/sky/example/fitness/lib/feed.dart @@ -82,11 +82,12 @@ class FeedFragment extends StatefulComponent { bool _isShowingSnackBar = false; - void _handleFitnessModeChange(FitnessMode value) { + EventDisposition _handleFitnessModeChange(FitnessMode value) { setState(() { _fitnessMode = value; _drawerShowing = false; }); + return EventDisposition.processed; } Drawer buildDrawer() { @@ -137,9 +138,10 @@ class FeedFragment extends StatefulComponent { }); } - void _handleShowSettings() { + EventDisposition _handleShowSettings() { navigator.pop(); navigator.pushNamed('/settings'); + return EventDisposition.processed; } // TODO(jackson): We should be localizing diff --git a/sky/packages/sky/example/fitness/lib/meal.dart b/sky/packages/sky/example/fitness/lib/meal.dart index 0ce8ba9aafa..deaccd09dc1 100644 --- a/sky/packages/sky/example/fitness/lib/meal.dart +++ b/sky/packages/sky/example/fitness/lib/meal.dart @@ -56,9 +56,10 @@ class MealFragment extends StatefulComponent { String _description = ""; - void _handleSave() { + EventDisposition _handleSave() { onCreated(new Meal(when: new DateTime.now(), description: _description)); navigator.pop(); + return EventDisposition.processed; } Widget buildToolBar() { diff --git a/sky/packages/sky/example/fitness/lib/measurement.dart b/sky/packages/sky/example/fitness/lib/measurement.dart index eb202025b55..26b2cab9204 100644 --- a/sky/packages/sky/example/fitness/lib/measurement.dart +++ b/sky/packages/sky/example/fitness/lib/measurement.dart @@ -60,7 +60,7 @@ class MeasurementFragment extends StatefulComponent { String _weight = ""; String _errorMessage = null; - void _handleSave() { + EventDisposition _handleSave() { double parsedWeight; try { parsedWeight = double.parse(_weight); @@ -68,10 +68,11 @@ class MeasurementFragment extends StatefulComponent { setState(() { _errorMessage = "Save failed"; }); - return; + return EventDisposition.processed; } onCreated(new Measurement(when: new DateTime.now(), weight: parsedWeight)); navigator.pop(); + return EventDisposition.processed; } Widget buildToolBar() { diff --git a/sky/packages/sky/example/game/lib/sprite_box.dart b/sky/packages/sky/example/game/lib/sprite_box.dart index 52e2ba45c60..5312d251538 100644 --- a/sky/packages/sky/example/game/lib/sprite_box.dart +++ b/sky/packages/sky/example/game/lib/sprite_box.dart @@ -174,9 +174,9 @@ class SpriteBox extends RenderBox { } } - void handleEvent(Event event, _SpriteBoxHitTestEntry entry) { + EventDisposition handleEvent(Event event, _SpriteBoxHitTestEntry entry) { if (!attached) - return; + return EventDisposition.ignored; if (event is PointerEvent) { @@ -225,6 +225,7 @@ class SpriteBox extends RenderBox { } } } + return EventDisposition.ignored; } bool hitTest(HitTestResult result, { Point position }) { diff --git a/sky/packages/sky/example/mine_digger/lib/main.dart b/sky/packages/sky/example/mine_digger/lib/main.dart index ccedf360974..35a86651850 100644 --- a/sky/packages/sky/example/mine_digger/lib/main.dart +++ b/sky/packages/sky/example/mine_digger/lib/main.dart @@ -208,10 +208,11 @@ class MineDiggerApp extends App { ); } - void handleToolbarPointerDown(sky.PointerEvent event) { + EventDisposition handleToolbarPointerDown(sky.PointerEvent event) { setState(() { resetGame(); }); + return EventDisposition.processed; } // User action. The user uncovers the cell which can cause losing the game. diff --git a/sky/packages/sky/example/rendering/flex.dart b/sky/packages/sky/example/rendering/flex.dart index 702dbc7d0c3..55b2460040c 100644 --- a/sky/packages/sky/example/rendering/flex.dart +++ b/sky/packages/sky/example/rendering/flex.dart @@ -37,11 +37,15 @@ class RenderSolidColor extends RenderDecoratedBox { size = constraints.constrain(desiredSize); } - void handleEvent(sky.Event event, BoxHitTestEntry entry) { - if (event.type == 'pointerdown') + EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) { + if (event.type == 'pointerdown') { decoration = new BoxDecoration(backgroundColor: const sky.Color(0xFFFF0000)); - else if (event.type == 'pointerup') + return EventDisposition.processed; + } else if (event.type == 'pointerup') { decoration = new BoxDecoration(backgroundColor: backgroundColor); + return EventDisposition.processed; + } + return super.handleEvent(event, entry); } } diff --git a/sky/packages/sky/example/rendering/sector_layout.dart b/sky/packages/sky/example/rendering/sector_layout.dart index 52dd265b336..a91914c5076 100644 --- a/sky/packages/sky/example/rendering/sector_layout.dart +++ b/sky/packages/sky/example/rendering/sector_layout.dart @@ -517,11 +517,15 @@ class RenderSolidColor extends RenderDecoratedSector { deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); } - void handleEvent(sky.Event event, HitTestEntry entry) { - if (event.type == 'pointerdown') + EventDisposition handleEvent(sky.Event event, HitTestEntry entry) { + if (event.type == 'pointerdown') { decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000)); - else if (event.type == 'pointerup') + return EventDisposition.processed; + } else if (event.type == 'pointerup') { decoration = new BoxDecoration(backgroundColor: backgroundColor); + return EventDisposition.processed; + } + return EventDisposition.ignored; } } diff --git a/sky/packages/sky/example/rendering/solid_color_box.dart b/sky/packages/sky/example/rendering/solid_color_box.dart index b6624c666fb..edca5473ee1 100644 --- a/sky/packages/sky/example/rendering/solid_color_box.dart +++ b/sky/packages/sky/example/rendering/solid_color_box.dart @@ -42,10 +42,14 @@ class RenderSolidColorBox extends RenderDecoratedBox { size = constraints.constrain(desiredSize); } - void handleEvent(sky.Event event, BoxHitTestEntry entry) { - if (event.type == 'pointerdown') + EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) { + if (event.type == 'pointerdown') { decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000)); - else if (event.type == 'pointerup') + return EventDisposition.processed; + } else if (event.type == 'pointerup') { decoration = new BoxDecoration(backgroundColor: backgroundColor); + return EventDisposition.processed; + } + return EventDisposition.ignored; } } diff --git a/sky/packages/sky/example/rendering/touch_demo.dart b/sky/packages/sky/example/rendering/touch_demo.dart index edd6f129f07..fcda20e5549 100644 --- a/sky/packages/sky/example/rendering/touch_demo.dart +++ b/sky/packages/sky/example/rendering/touch_demo.dart @@ -43,7 +43,7 @@ class RenderTouchDemo extends RenderBox { RenderTouchDemo(); - void handleEvent(sky.Event event, BoxHitTestEntry entry) { + EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) { if (event is sky.PointerEvent) { switch (event.type) { case 'pointerdown': @@ -60,8 +60,10 @@ class RenderTouchDemo extends RenderBox { dots[event.pointer].update(event); break; } + markNeedsPaint(); + return EventDisposition.processed; } - markNeedsPaint(); + return EventDisposition.processed; } void performLayout() { diff --git a/sky/packages/sky/example/stocks/lib/stock_home.dart b/sky/packages/sky/example/stocks/lib/stock_home.dart index f286e9d73aa..1aa50a1dfe5 100644 --- a/sky/packages/sky/example/stocks/lib/stock_home.dart +++ b/sky/packages/sky/example/stocks/lib/stock_home.dart @@ -103,12 +103,13 @@ class StockHome extends StatefulComponent { }); } - void _handleStockModeChange(StockMode value) { + EventDisposition _handleStockModeChange(StockMode value) { setState(() { stockMode = value; }); if (modeUpdater != null) modeUpdater(value); + return EventDisposition.processed; } Drawer buildDrawer() { @@ -156,9 +157,10 @@ class StockHome extends StatefulComponent { ); } - void _handleShowSettings() { + EventDisposition _handleShowSettings() { navigator.pop(); navigator.pushNamed('/settings'); + return EventDisposition.processed; } Widget buildToolBar() { diff --git a/sky/packages/sky/example/stocks/lib/stock_settings.dart b/sky/packages/sky/example/stocks/lib/stock_settings.dart index 27432b8890e..c3ddb8efbcc 100644 --- a/sky/packages/sky/example/stocks/lib/stock_settings.dart +++ b/sky/packages/sky/example/stocks/lib/stock_settings.dart @@ -39,7 +39,7 @@ class StockSettings extends StatefulComponent { sendUpdates(); } - void _confirmOptimismChange() { + EventDisposition _confirmOptimismChange() { switch (optimism) { case StockMode.optimistic: _handleOptimismChanged(false); @@ -70,6 +70,7 @@ class StockSettings extends StatefulComponent { }).then(_handleOptimismChanged); break; } + return EventDisposition.processed; } void sendUpdates() { diff --git a/sky/packages/sky/example/widgets/piano.dart b/sky/packages/sky/example/widgets/piano.dart index 658d63527e5..6625d12bca9 100644 --- a/sky/packages/sky/example/widgets/piano.dart +++ b/sky/packages/sky/example/widgets/piano.dart @@ -26,17 +26,19 @@ class Key { final String soundUrl; MediaPlayerProxy player; - void down() { + EventDisposition down() { if (player == null) - return; + return EventDisposition.ignored; player.ptr.seekTo(0); player.ptr.start(); + return EventDisposition.processed; } - void up() { + EventDisposition up() { if (player == null) - return; + return EventDisposition.ignored; player.ptr.pause(); + return EventDisposition.processed; } } diff --git a/sky/packages/sky/example/widgets/styled_text.dart b/sky/packages/sky/example/widgets/styled_text.dart index 5a639d143bd..9892a2ebeef 100644 --- a/sky/packages/sky/example/widgets/styled_text.dart +++ b/sky/packages/sky/example/widgets/styled_text.dart @@ -71,10 +71,11 @@ HAL: This mission is too important for me to allow you to jeopardize it.'''; ); } - void toggleToTextFunction(_) { + EventDisposition toggleToTextFunction(_) { setState(() { toText = (toText == toPlainText) ? toStyledText : toPlainText; }); + return EventDisposition.processed; } Widget build() { diff --git a/sky/packages/sky/lib/base/hit_test.dart b/sky/packages/sky/lib/base/hit_test.dart index 9707142760d..4d769a0464c 100644 --- a/sky/packages/sky/lib/base/hit_test.dart +++ b/sky/packages/sky/lib/base/hit_test.dart @@ -4,8 +4,14 @@ import 'dart:sky' as sky; +enum EventDisposition { + ignored, + processed, + consumed, +} + abstract class HitTestTarget { - void handleEvent(sky.Event event, HitTestEntry entry); + EventDisposition handleEvent(sky.Event event, HitTestEntry entry); } class HitTestEntry { diff --git a/sky/packages/sky/lib/editing/input.dart b/sky/packages/sky/lib/editing/input.dart index e9f806034e6..b63251ec455 100644 --- a/sky/packages/sky/lib/editing/input.dart +++ b/sky/packages/sky/lib/editing/input.dart @@ -107,7 +107,7 @@ class Input extends StatefulComponent { ); } - void focus(_) { + EventDisposition focus(_) { if (Focus.at(this)) { assert(_keyboardHandle.attached); _keyboardHandle.showByRequest(); @@ -115,6 +115,7 @@ class Input extends StatefulComponent { Focus.moveTo(this); // we'll get told to rebuild and we'll take care of the keyboard then } + return EventDisposition.processed; } void didUnmount() { diff --git a/sky/packages/sky/lib/rendering/flex.dart b/sky/packages/sky/lib/rendering/flex.dart index 8b61489dfb4..5bc9d0380b3 100644 --- a/sky/packages/sky/lib/rendering/flex.dart +++ b/sky/packages/sky/lib/rendering/flex.dart @@ -7,6 +7,8 @@ import 'dart:math' as math; import 'package:sky/rendering/box.dart'; import 'package:sky/rendering/object.dart'; +export 'package:sky/rendering/object.dart' show EventDisposition; + class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin { int flex; diff --git a/sky/packages/sky/lib/rendering/object.dart b/sky/packages/sky/lib/rendering/object.dart index 06fdf3c9cda..18ece8d4d70 100644 --- a/sky/packages/sky/lib/rendering/object.dart +++ b/sky/packages/sky/lib/rendering/object.dart @@ -12,7 +12,7 @@ import 'package:sky/base/node.dart'; import 'package:sky/base/scheduler.dart' as scheduler; export 'dart:sky' show Point, Offset, Size, Rect, Color, Paint, Path; -export 'package:sky/base/hit_test.dart' show HitTestTarget, HitTestEntry, HitTestResult; +export 'package:sky/base/hit_test.dart' show EventDisposition, HitTestTarget, HitTestEntry, HitTestResult; class ParentData { void detach() { @@ -415,9 +415,10 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { // EVENTS - void handleEvent(sky.Event event, HitTestEntry entry) { + EventDisposition handleEvent(sky.Event event, HitTestEntry entry) { // override this if you have a client, to hand it to the client // override this if you want to do anything with the event + return EventDisposition.ignored; } diff --git a/sky/packages/sky/lib/rendering/sky_binding.dart b/sky/packages/sky/lib/rendering/sky_binding.dart index 8eadf4b7c0e..7d4e4f98f59 100644 --- a/sky/packages/sky/lib/rendering/sky_binding.dart +++ b/sky/packages/sky/lib/rendering/sky_binding.dart @@ -109,7 +109,7 @@ class SkyBinding { return state; } - void _handlePointerEvent(sky.PointerEvent event) { + EventDisposition _handlePointerEvent(sky.PointerEvent event) { Point position = new Point(event.x, event.y); PointerState state = _getOrCreateStateForPointer(event, position); @@ -123,13 +123,20 @@ class SkyBinding { event.dy = position.y - state.lastPosition.y; state.lastPosition = position; - dispatchEvent(event, state.result); + return dispatchEvent(event, state.result); } - void dispatchEvent(sky.Event event, HitTestResult result) { + EventDisposition dispatchEvent(sky.Event event, HitTestResult result) { assert(result != null); - for (HitTestEntry entry in result.path.reversed) - entry.target.handleEvent(event, entry); + EventDisposition disposition = EventDisposition.ignored; + for (HitTestEntry entry in result.path.reversed) { + EventDisposition entryDisposition = entry.target.handleEvent(event, entry); + if (entryDisposition == EventDisposition.consumed) + return EventDisposition.consumed; + else if (entryDisposition == EventDisposition.processed) + disposition = EventDisposition.processed; + } + return disposition; } String toString() => 'Render Tree:\n${_renderView}'; diff --git a/sky/packages/sky/lib/widgets/basic.dart b/sky/packages/sky/lib/widgets/basic.dart index 30ee9577325..8763cd046e6 100644 --- a/sky/packages/sky/lib/widgets/basic.dart +++ b/sky/packages/sky/lib/widgets/basic.dart @@ -19,6 +19,7 @@ import 'package:sky/rendering/stack.dart'; import 'package:sky/widgets/default_text_style.dart'; import 'package:sky/widgets/widget.dart'; +export 'package:sky/base/hit_test.dart' show EventDisposition; export 'package:sky/rendering/box.dart' show BackgroundImage, BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims; export 'package:sky/rendering/flex.dart' show FlexDirection, FlexJustifyContent, FlexAlignItems; export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path; diff --git a/sky/packages/sky/lib/widgets/button_base.dart b/sky/packages/sky/lib/widgets/button_base.dart index aa3db426131..a6a378fd475 100644 --- a/sky/packages/sky/lib/widgets/button_base.dart +++ b/sky/packages/sky/lib/widgets/button_base.dart @@ -14,20 +14,23 @@ abstract class ButtonBase extends StatefulComponent { highlight = source.highlight; } - void _handlePointerDown(_) { + EventDisposition _handlePointerDown(_) { setState(() { highlight = true; }); + return EventDisposition.processed; } - void _handlePointerUp(_) { + EventDisposition _handlePointerUp(_) { setState(() { highlight = false; }); + return EventDisposition.processed; } - void _handlePointerCancel(_) { + EventDisposition _handlePointerCancel(_) { setState(() { highlight = false; }); + return EventDisposition.processed; } Widget build() { diff --git a/sky/packages/sky/lib/widgets/dismissable.dart b/sky/packages/sky/lib/widgets/dismissable.dart index b89787e4e1c..f3415ccd5f1 100644 --- a/sky/packages/sky/lib/widgets/dismissable.dart +++ b/sky/packages/sky/lib/widgets/dismissable.dart @@ -99,15 +99,16 @@ class Dismissable extends StatefulComponent { _maybeCallOnResized(); } - void _handlePointerDown(sky.PointerEvent event) { + EventDisposition _handlePointerDown(sky.PointerEvent event) { _dragUnderway = true; _dragX = 0.0; _fadePerformance.progress = 0.0; + return EventDisposition.processed; } - void _handlePointerMove(sky.PointerEvent event) { + EventDisposition _handlePointerMove(sky.PointerEvent event) { if (!_isActive) - return; + return EventDisposition.ignored; double oldDragX = _dragX; _dragX += event.dx; @@ -115,17 +116,19 @@ class Dismissable extends StatefulComponent { setState(() {}); // Rebuild to update the new drag endpoint. if (!_fadePerformance.isAnimating) _fadePerformance.progress = _dragX.abs() / (_size.width * _kDismissCardThreshold); + return EventDisposition.processed; } - void _handlePointerUpOrCancel(_) { + EventDisposition _handlePointerUpOrCancel(_) { if (!_isActive) - return; + return EventDisposition.ignored; _dragUnderway = false; if (_fadePerformance.isCompleted) _startResizePerformance(); else if (!_fadePerformance.isAnimating) _fadePerformance.reverse(); + return EventDisposition.processed; } bool _isHorizontalFlingGesture(sky.GestureEvent event) { @@ -134,15 +137,16 @@ class Dismissable extends StatefulComponent { return vx - vy > _kMinFlingVelocityDelta && vx > _kMinFlingVelocity; } - void _handleFlingStart(sky.GestureEvent event) { + EventDisposition _handleFlingStart(sky.GestureEvent event) { if (!_isActive) - return; + return EventDisposition.ignored; if (_isHorizontalFlingGesture(event)) { _dragUnderway = false; _dragX = event.velocityX.sign; _fadePerformance.fling(Direction.forward, velocity: event.velocityX.abs() * _kFlingVelocityScale); } + return EventDisposition.processed; } void _handleSizeChanged(Size newSize) { diff --git a/sky/packages/sky/lib/widgets/drawer.dart b/sky/packages/sky/lib/widgets/drawer.dart index 4537ee58d80..7cb8df0a0f8 100644 --- a/sky/packages/sky/lib/widgets/drawer.dart +++ b/sky/packages/sky/lib/widgets/drawer.dart @@ -139,33 +139,48 @@ class Drawer extends StatefulComponent { void _settle() { _isMostlyClosed ? _performance.reverse() : _performance.play(); } - void handleMaskTap(_) { _performance.reverse(); } + EventDisposition handleMaskTap(_) { + _performance.reverse(); + return EventDisposition.consumed; + } // TODO(mpcomplete): Figure out how to generalize these handlers on a // "PannableThingy" interface. - void handlePointerDown(_) { _performance.stop(); } + EventDisposition handlePointerDown(_) { + _performance.stop(); + return EventDisposition.processed; + } - void handlePointerMove(sky.PointerEvent event) { + EventDisposition handlePointerMove(sky.PointerEvent event) { if (_performance.isAnimating) - return; + return EventDisposition.ignored; _performance.progress += event.dx / _kWidth; + return EventDisposition.processed; } - void handlePointerUp(_) { - if (!_performance.isAnimating) + EventDisposition handlePointerUp(_) { + if (!_performance.isAnimating) { _settle(); + return EventDisposition.processed; + } + return EventDisposition.ignored; } - void handlePointerCancel(_) { - if (!_performance.isAnimating) + EventDisposition handlePointerCancel(_) { + if (!_performance.isAnimating) { _settle(); + return EventDisposition.processed; + } + return EventDisposition.ignored; } - void handleFlingStart(event) { + EventDisposition handleFlingStart(event) { if (event.velocityX.abs() >= _kMinFlingVelocity) { _performance.fling( event.velocityX < 0.0 ? Direction.reverse : Direction.forward, velocity: event.velocityX.abs() * _kFlingVelocityScale); + return EventDisposition.processed; } + return EventDisposition.ignored; } } diff --git a/sky/packages/sky/lib/widgets/drawer_item.dart b/sky/packages/sky/lib/widgets/drawer_item.dart index 1e179dc5718..4ac5b210640 100644 --- a/sky/packages/sky/lib/widgets/drawer_item.dart +++ b/sky/packages/sky/lib/widgets/drawer_item.dart @@ -14,13 +14,15 @@ import 'package:sky/widgets/ink_well.dart'; import 'package:sky/widgets/theme.dart'; import 'package:sky/widgets/widget.dart'; +typedef EventDisposition OnPressedFunction(); + class DrawerItem extends ButtonBase { DrawerItem({ Key key, this.icon, this.children, this.onPressed, this.selected: false }) : super(key: key); String icon; List children; - Function onPressed; + OnPressedFunction onPressed; bool selected; void syncFields(DrawerItem source) { @@ -82,7 +84,8 @@ class DrawerItem extends ButtonBase { return new Listener( onGestureTap: (_) { if (onPressed != null) - onPressed(); + return onPressed(); + return EventDisposition.ignored; }, child: new Container( height: 48.0, diff --git a/sky/packages/sky/lib/widgets/ink_well.dart b/sky/packages/sky/lib/widgets/ink_well.dart index 86139365e0c..6fc097f31e2 100644 --- a/sky/packages/sky/lib/widgets/ink_well.dart +++ b/sky/packages/sky/lib/widgets/ink_well.dart @@ -84,17 +84,18 @@ class RenderInkWell extends RenderProxyBox { final List _splashes = new List(); - void handleEvent(sky.Event event, BoxHitTestEntry entry) { + EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) { if (event is sky.GestureEvent) { switch (event.type) { case 'gesturetapdown': _startSplash(event.primaryPointer, entry.localPosition); - break; + return EventDisposition.processed; case 'gesturetap': _confirmSplash(event.primaryPointer); - break; + return EventDisposition.processed; } } + return EventDisposition.ignored; } void _startSplash(int pointer, Point position) { diff --git a/sky/packages/sky/lib/widgets/radio.dart b/sky/packages/sky/lib/widgets/radio.dart index 1a77d5120ce..abad4085d1e 100644 --- a/sky/packages/sky/lib/widgets/radio.dart +++ b/sky/packages/sky/lib/widgets/radio.dart @@ -68,12 +68,13 @@ class Radio extends ButtonBase { } ) ), - onGestureTap: _handleClick + onGestureTap: _handleTap ); } - void _handleClick(_) { + EventDisposition _handleTap(_) { onChanged(value); + return EventDisposition.consumed; } } diff --git a/sky/packages/sky/lib/widgets/scrollable.dart b/sky/packages/sky/lib/widgets/scrollable.dart index 0d0e84c3837..5f21205e030 100644 --- a/sky/packages/sky/lib/widgets/scrollable.dart +++ b/sky/packages/sky/lib/widgets/scrollable.dart @@ -181,20 +181,23 @@ abstract class Scrollable extends StatefulComponent { scrollTo(value); } - void _handlePointerDown(_) { + EventDisposition _handlePointerDown(_) { _stopToEndAnimation(); _stopToOffsetAnimation(); + return EventDisposition.processed; } - void _handleScrollUpdate(sky.GestureEvent event) { + EventDisposition _handleScrollUpdate(sky.GestureEvent event) { scrollBy(direction == ScrollDirection.horizontal ? event.dx : -event.dy); + return EventDisposition.processed; } - void _handleFlingStart(sky.GestureEvent event) { + EventDisposition _handleFlingStart(sky.GestureEvent event) { double eventVelocity = direction == ScrollDirection.horizontal ? -event.velocityX : -event.velocityY; _startToEndAnimation(velocity: _velocityForFlingGesture(eventVelocity)); + return EventDisposition.processed; } void _maybeSettleScrollOffset() { @@ -202,13 +205,20 @@ abstract class Scrollable extends StatefulComponent { settleScrollOffset(); } - void _handlePointerUpOrCancel(_) { _maybeSettleScrollOffset(); } + EventDisposition _handlePointerUpOrCancel(_) { + _maybeSettleScrollOffset(); + return EventDisposition.processed; + } - void _handleFlingCancel(sky.GestureEvent event) { _maybeSettleScrollOffset(); } + EventDisposition _handleFlingCancel(sky.GestureEvent event) { + _maybeSettleScrollOffset(); + return EventDisposition.processed; + } - void _handleWheel(sky.WheelEvent event) { + EventDisposition _handleWheel(sky.WheelEvent event) { scrollBy(-event.offsetY); + return EventDisposition.processed; } } diff --git a/sky/packages/sky/lib/widgets/switch.dart b/sky/packages/sky/lib/widgets/switch.dart index f943378fc50..969936fab2b 100644 --- a/sky/packages/sky/lib/widgets/switch.dart +++ b/sky/packages/sky/lib/widgets/switch.dart @@ -80,9 +80,12 @@ class _RenderSwitch extends RenderConstrainedBox { ..addListener(markNeedsPaint); } - void handleEvent(sky.Event event, BoxHitTestEntry entry) { - if (event is sky.GestureEvent && - event.type == 'gesturetap') _onChanged(!_value); + EventDisposition handleEvent(sky.Event event, BoxHitTestEntry entry) { + if (event is sky.GestureEvent && event.type == 'gesturetap') { + _onChanged(!_value); + return EventDisposition.consumed; + } + return EventDisposition.ignored; } bool _value; diff --git a/sky/packages/sky/lib/widgets/tabs.dart b/sky/packages/sky/lib/widgets/tabs.dart index 669da4d0ffb..71f94bb1ea7 100644 --- a/sky/packages/sky/lib/widgets/tabs.dart +++ b/sky/packages/sky/lib/widgets/tabs.dart @@ -475,7 +475,7 @@ class TabBar extends Scrollable { .clamp(scrollBehavior.minScrollOffset, scrollBehavior.maxScrollOffset); } - void _handleTap(int tabIndex) { + EventDisposition _handleTap(int tabIndex) { if (tabIndex != selectedIndex) { if (_tabWidths != null) { if (isScrollable) @@ -484,7 +484,9 @@ class TabBar extends Scrollable { } if (onChanged != null) onChanged(tabIndex); + return EventDisposition.processed; } + return EventDisposition.ignored; } Widget _toTab(TabLabel label, int tabIndex) { diff --git a/sky/packages/sky/lib/widgets/toggleable.dart b/sky/packages/sky/lib/widgets/toggleable.dart index 0a02fde3a10..347089efd0b 100644 --- a/sky/packages/sky/lib/widgets/toggleable.dart +++ b/sky/packages/sky/lib/widgets/toggleable.dart @@ -57,8 +57,9 @@ abstract class Toggleable extends AnimatedComponent { super.syncFields(source); } - void _handleClick(sky.Event e) { + EventDisposition _handleClick(sky.Event e) { onChanged(!value); + return EventDisposition.consumed; } // Override these to draw yourself diff --git a/sky/packages/sky/lib/widgets/widget.dart b/sky/packages/sky/lib/widgets/widget.dart index dcab05d7437..2b4ba213071 100644 --- a/sky/packages/sky/lib/widgets/widget.dart +++ b/sky/packages/sky/lib/widgets/widget.dart @@ -13,6 +13,7 @@ import 'package:sky/rendering/box.dart'; import 'package:sky/rendering/object.dart'; import 'package:sky/rendering/sky_binding.dart'; +export 'package:sky/base/hit_test.dart' show EventDisposition; export 'package:sky/rendering/box.dart' show BoxConstraints, BoxDecoration, Border, BorderSide, EdgeDims; export 'package:sky/rendering/flex.dart' show FlexDirection; export 'package:sky/rendering/object.dart' show Point, Offset, Size, Rect, Color, Paint, Path; @@ -446,9 +447,9 @@ abstract class Inherited extends TagNode { } -typedef void GestureEventListener(sky.GestureEvent e); -typedef void PointerEventListener(sky.PointerEvent e); -typedef void EventListener(sky.Event e); +typedef EventDisposition GestureEventListener(sky.GestureEvent e); +typedef EventDisposition PointerEventListener(sky.PointerEvent e); +typedef EventDisposition EventListener(sky.Event e); class Listener extends TagNode { @@ -529,11 +530,12 @@ class Listener extends TagNode { return listeners; } - void _handleEvent(sky.Event e) { + EventDisposition _handleEvent(sky.Event e) { EventListener listener = listeners[e.type]; if (listener != null) { - listener(e); + return listener(e); } + return EventDisposition.ignored; } } @@ -1169,20 +1171,29 @@ class WidgetSkyBinding extends SkyBinding { assert(SkyBinding.instance is WidgetSkyBinding); } - void dispatchEvent(sky.Event event, HitTestResult result) { + EventDisposition dispatchEvent(sky.Event event, HitTestResult result) { assert(SkyBinding.instance == this); - super.dispatchEvent(event, result); + EventDisposition disposition = super.dispatchEvent(event, result); + if (disposition == EventDisposition.consumed) + return EventDisposition.consumed; for (HitTestEntry entry in result.path.reversed) { Widget target = RenderObjectWrapper._getMounted(entry.target); if (target == null) continue; RenderObject targetRoot = target.root; while (target != null && target.root == targetRoot) { - if (target is Listener) - target._handleEvent(event); + if (target is Listener) { + EventDisposition targetDisposition = target._handleEvent(event); + if (targetDisposition == EventDisposition.consumed) { + return targetDisposition; + } else if (targetDisposition == EventDisposition.processed) { + disposition = EventDisposition.processed; + } + } target = target._parent; } } + return disposition; } void beginFrame(double timeStamp) {