mobile gesture handler
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:math';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:thermion_dart/thermion_dart.dart';
|
import 'package:thermion_dart/thermion_dart.dart';
|
||||||
import 'package:vector_math/vector_math_64.dart';
|
import 'package:vector_math/vector_math_64.dart';
|
||||||
@@ -26,6 +27,8 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
|
|
||||||
Map<InputType, InputAction> _actions = {
|
Map<InputType, InputAction> _actions = {
|
||||||
InputType.LMB_HOLD_AND_MOVE: InputAction.TRANSLATE,
|
InputType.LMB_HOLD_AND_MOVE: InputAction.TRANSLATE,
|
||||||
|
InputType.SCALE1: InputAction.TRANSLATE,
|
||||||
|
InputType.SCALE2: InputAction.ZOOM,
|
||||||
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
InputType.MMB_HOLD_AND_MOVE: InputAction.ROTATE,
|
||||||
InputType.SCROLLWHEEL: InputAction.TRANSLATE,
|
InputType.SCROLLWHEEL: InputAction.TRANSLATE,
|
||||||
InputType.POINTER_MOVE: InputAction.NONE,
|
InputType.POINTER_MOVE: InputAction.NONE,
|
||||||
@@ -99,6 +102,8 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
InputType.KEYDOWN_W: InputAction.TRANSLATE,
|
InputType.KEYDOWN_W: InputAction.TRANSLATE,
|
||||||
InputType.KEYDOWN_S: InputAction.TRANSLATE,
|
InputType.KEYDOWN_S: InputAction.TRANSLATE,
|
||||||
InputType.KEYDOWN_D: InputAction.TRANSLATE,
|
InputType.KEYDOWN_D: InputAction.TRANSLATE,
|
||||||
|
InputType.SCALE1: InputAction.TRANSLATE,
|
||||||
|
InputType.SCALE2: InputAction.ZOOM,
|
||||||
if (freeLook) InputType.POINTER_MOVE: InputAction.ROTATE,
|
if (freeLook) InputType.POINTER_MOVE: InputAction.ROTATE,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,15 +240,6 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
@override
|
@override
|
||||||
Future<bool> get initialized => viewer.initialized;
|
Future<bool> get initialized => viewer.initialized;
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onScaleEnd() async {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onScaleStart() async {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> onScaleUpdate() async {}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void setActionForType(InputType gestureType, InputAction gestureAction) {
|
void setActionForType(InputType gestureType, InputAction gestureAction) {
|
||||||
_actions[gestureType] = gestureAction;
|
_actions[gestureType] = gestureAction;
|
||||||
@@ -261,4 +257,26 @@ class DelegateInputHandler implements InputHandler {
|
|||||||
void keyUp(PhysicalKey key) {
|
void keyUp(PhysicalKey key) {
|
||||||
_pressedKeys.remove(key);
|
_pressedKeys.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onScaleEnd(int pointerCount) async {}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onScaleStart(Vector2 localPosition, int pointerCount) async {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onScaleUpdate(Vector2 focalPoint, Vector2 focalPointDelta,
|
||||||
|
double horizontalScale, double verticalScale, double scale, int pointerCount) async {
|
||||||
|
if (pointerCount == 1) {
|
||||||
|
_inputDeltas[InputType.SCALE1] =
|
||||||
|
Vector3(focalPointDelta.x, focalPointDelta.y, 0);
|
||||||
|
} else if (pointerCount == 2) {
|
||||||
|
_inputDeltas[InputType.SCALE2] =
|
||||||
|
Vector3(0, 0, max(horizontalScale, verticalScale));
|
||||||
|
} else {
|
||||||
|
throw UnimplementedError("Only pointerCount <= 2 supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ abstract class InputHandler {
|
|||||||
Future<void> onPointerMove(
|
Future<void> onPointerMove(
|
||||||
Vector2 localPosition, Vector2 delta, bool isMiddle);
|
Vector2 localPosition, Vector2 delta, bool isMiddle);
|
||||||
Future<void> onPointerUp(bool isMiddle);
|
Future<void> onPointerUp(bool isMiddle);
|
||||||
Future<void> onScaleStart();
|
Future<void> onScaleStart(Vector2 focalPoint, int pointerCount);
|
||||||
Future<void> onScaleUpdate();
|
Future<void> onScaleUpdate(Vector2 focalPoint, Vector2 focalPointDelta, double horizontalScale, double verticalScale, double scale, int pointerCount);
|
||||||
Future<void> onScaleEnd();
|
Future<void> onScaleEnd(int pointerCount);
|
||||||
Future<bool> get initialized;
|
Future<bool> get initialized;
|
||||||
Future dispose();
|
Future dispose();
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class _ThermionListenerWidgetState extends State<ThermionListenerWidget> {
|
|||||||
|
|
||||||
Widget _mobile(double pixelRatio) {
|
Widget _mobile(double pixelRatio) {
|
||||||
return _MobileListenerWidget(
|
return _MobileListenerWidget(
|
||||||
gestureHandler: widget.gestureHandler, pixelRatio: pixelRatio);
|
gestureHandler: widget.gestureHandler, pixelRatio: pixelRatio, child:widget.child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -135,8 +135,10 @@ class _ThermionListenerWidgetState extends State<ThermionListenerWidget> {
|
|||||||
class _MobileListenerWidget extends StatefulWidget {
|
class _MobileListenerWidget extends StatefulWidget {
|
||||||
final InputHandler gestureHandler;
|
final InputHandler gestureHandler;
|
||||||
final double pixelRatio;
|
final double pixelRatio;
|
||||||
|
final Widget? child;
|
||||||
|
|
||||||
const _MobileListenerWidget({Key? key, required this.gestureHandler, required this.pixelRatio})
|
const _MobileListenerWidget(
|
||||||
|
{Key? key, required this.gestureHandler, required this.pixelRatio, this.child})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -154,22 +156,29 @@ class _MobileListenerWidgetState extends State<_MobileListenerWidget> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.translucent,
|
behavior: HitTestBehavior.translucent,
|
||||||
onTapDown: (details) => widget.gestureHandler
|
onTapDown: (details) => widget.gestureHandler.onPointerDown(
|
||||||
.onPointerDown(details.localPosition.toVector2() * widget.pixelRatio, false),
|
details.localPosition.toVector2() * widget.pixelRatio, false),
|
||||||
onDoubleTap: () {
|
onDoubleTap: () {
|
||||||
widget.gestureHandler.setActionForType(InputType.SCALE1,
|
widget.gestureHandler.setActionForType(InputType.SCALE1,
|
||||||
isPan ? InputAction.TRANSLATE : InputAction.ROTATE);
|
isPan ? InputAction.TRANSLATE : InputAction.ROTATE);
|
||||||
},
|
},
|
||||||
onScaleStart: (details) async {
|
onScaleStart: (details) async {
|
||||||
await widget.gestureHandler.onScaleStart();
|
await widget.gestureHandler.onScaleStart(
|
||||||
},
|
details.localFocalPoint.toVector2(), details.pointerCount);
|
||||||
onScaleUpdate: (details) async {
|
},
|
||||||
await widget.gestureHandler.onScaleUpdate();
|
onScaleUpdate: (ScaleUpdateDetails details) async {
|
||||||
},
|
await widget.gestureHandler.onScaleUpdate(
|
||||||
onScaleEnd: (details) async {
|
details.localFocalPoint.toVector2(),
|
||||||
await widget.gestureHandler.onScaleUpdate();
|
details.focalPointDelta.toVector2(),
|
||||||
},
|
details.horizontalScale,
|
||||||
);
|
details.verticalScale,
|
||||||
|
details.scale,
|
||||||
|
details.pointerCount);
|
||||||
|
},
|
||||||
|
onScaleEnd: (details) async {
|
||||||
|
await widget.gestureHandler.onScaleEnd(details.pointerCount);
|
||||||
|
},
|
||||||
|
child: widget.child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user