Line data Source code
1 : import 'package:flutter/material.dart'; 2 : 3 : import '../../game/base_game.dart'; 4 : import '../../gestures/events.dart'; 5 : import '../base_component.dart'; 6 : 7 : mixin Draggable on BaseComponent { 8 : bool _isDragged = false; 9 2 : bool get isDragged => _isDragged; 10 : 11 0 : bool onDragStart(int pointerId, DragStartInfo info) { 12 : return true; 13 : } 14 : 15 0 : bool onDragUpdate(int pointerId, DragUpdateInfo info) { 16 : return true; 17 : } 18 : 19 1 : bool onDragEnd(int pointerId, DragEndInfo info) { 20 : return true; 21 : } 22 : 23 0 : bool onDragCancel(int pointerId) { 24 : return true; 25 : } 26 : 27 : final List<int> _currentPointerIds = []; 28 3 : bool _checkPointerId(int pointerId) => _currentPointerIds.contains(pointerId); 29 : 30 1 : bool handleDragStart(int pointerId, DragStartInfo info) { 31 2 : if (containsPoint(eventPosition(info))) { 32 1 : _isDragged = true; 33 2 : _currentPointerIds.add(pointerId); 34 1 : return onDragStart(pointerId, info); 35 : } 36 : return true; 37 : } 38 : 39 0 : bool handleDragUpdated(int pointerId, DragUpdateInfo details) { 40 0 : if (_checkPointerId(pointerId)) { 41 0 : return onDragUpdate(pointerId, details); 42 : } 43 : return true; 44 : } 45 : 46 1 : bool handleDragEnded(int pointerId, DragEndInfo details) { 47 1 : if (_checkPointerId(pointerId)) { 48 1 : _isDragged = false; 49 2 : _currentPointerIds.remove(pointerId); 50 1 : return onDragEnd(pointerId, details); 51 : } 52 : return true; 53 : } 54 : 55 1 : bool handleDragCanceled(int pointerId) { 56 1 : if (_checkPointerId(pointerId)) { 57 1 : _isDragged = false; 58 2 : _currentPointerIds.remove(pointerId); 59 1 : return handleDragCanceled(pointerId); 60 : } 61 : return true; 62 : } 63 : } 64 : 65 : mixin HasDraggableComponents on BaseGame { 66 1 : @mustCallSuper 67 : void onDragStart(int pointerId, DragStartInfo info) { 68 3 : _onGenericEventReceived((c) => c.handleDragStart(pointerId, info)); 69 : } 70 : 71 0 : @mustCallSuper 72 : void onDragUpdate(int pointerId, DragUpdateInfo details) { 73 0 : _onGenericEventReceived((c) => c.handleDragUpdated(pointerId, details)); 74 : } 75 : 76 1 : @mustCallSuper 77 : void onDragEnd(int pointerId, DragEndInfo details) { 78 3 : _onGenericEventReceived((c) => c.handleDragEnded(pointerId, details)); 79 : } 80 : 81 1 : @mustCallSuper 82 : void onDragCancel(int pointerId) { 83 3 : _onGenericEventReceived((c) => c.handleDragCanceled(pointerId)); 84 : } 85 : 86 1 : void _onGenericEventReceived(bool Function(Draggable) handler) { 87 3 : for (final c in components.reversed()) { 88 : var shouldContinue = true; 89 1 : if (c is BaseComponent) { 90 1 : shouldContinue = c.propagateToChildren<Draggable>(handler); 91 : } 92 1 : if (c is Draggable && shouldContinue) { 93 1 : shouldContinue = handler(c); 94 : } 95 : if (!shouldContinue) { 96 : break; 97 : } 98 : } 99 : } 100 : }