Line data Source code
1 : // Copyright 2023 The terCAD team. All rights reserved.
2 : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
3 :
4 : import 'package:app_finance/_classes/controller/focus_controller.dart';
5 : import 'package:app_finance/_classes/herald/app_zoom.dart';
6 : import 'package:app_finance/_classes/structure/navigation/app_route.dart';
7 : import 'package:app_finance/_configs/mobile_platform.dart';
8 : import 'package:flutter/gestures.dart';
9 : import 'package:material_ui/material_ui.dart';
10 : import 'package:flutter/services.dart';
11 : import 'package:provider/provider.dart';
12 :
13 : enum AppEvents {
14 : zoomIn,
15 : zoomOut,
16 : zoomReset,
17 : tipDrawer,
18 : newBill,
19 : edit,
20 : delete,
21 : back,
22 : }
23 :
24 : class InputControllerWrapper extends StatefulWidget {
25 : final Widget child;
26 :
27 1 : const InputControllerWrapper({
28 : super.key,
29 : required this.child,
30 : });
31 :
32 1 : @override
33 1 : InputControllerWrapperState createState() => InputControllerWrapperState();
34 : }
35 :
36 : class InputControllerWrapperState extends State<InputControllerWrapper> {
37 : bool _ctrlPressed = false;
38 : late AppZoom zoom;
39 : final focus = FocusNode();
40 :
41 1 : @override
42 : void dispose() {
43 2 : focus.dispose();
44 1 : super.dispose();
45 : }
46 :
47 0 : void _onScaleUpdate(double step) => zoom.set(zoom.value + step);
48 :
49 0 : void _onScaleReset() => zoom.set(1.0);
50 :
51 0 : void _toggleDrawer() {
52 0 : if (Scaffold.of(context).isDrawerOpen) {
53 0 : Scaffold.of(context).closeDrawer();
54 : } else {
55 0 : Scaffold.of(context).openDrawer();
56 : }
57 : }
58 :
59 0 : void _pop() {
60 0 : if (Navigator.of(context).canPop()) {
61 0 : Navigator.of(context).pop();
62 : }
63 : }
64 :
65 0 : void onKeyEvent(KeyEvent event) {
66 0 : var isControlPressed = HardwareKeyboard.instance.isControlPressed;
67 0 : var isShiftPressed = HardwareKeyboard.instance.isShiftPressed;
68 : if (isControlPressed) {
69 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.minus)) {
70 0 : return _onScaleUpdate(-0.1);
71 : }
72 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.equal)) {
73 0 : return _onScaleUpdate(0.1);
74 : }
75 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.digit0)) {
76 0 : return _onScaleReset();
77 : }
78 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.keyN)) {
79 0 : Navigator.of(context).pushNamed(AppRoute.billAddRoute);
80 : return;
81 : }
82 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.keyE)) {
83 : return; // TBD: edit item
84 : }
85 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.keyD)) {
86 : return; // TBD: delete item
87 : }
88 0 : if (HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.backspace)) {
89 0 : return _pop();
90 : }
91 0 : } else if (isShiftPressed && HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.enter)) {
92 0 : return _toggleDrawer();
93 : }
94 0 : if (event.logicalKey == LogicalKeyboardKey.controlLeft || event.logicalKey == LogicalKeyboardKey.controlRight) {
95 0 : setState(() => _ctrlPressed = isControlPressed);
96 : }
97 : }
98 :
99 0 : void onPointerSignal(PointerSignalEvent event) {
100 0 : if (_ctrlPressed && event is PointerScrollEvent) {
101 0 : _onScaleUpdate(event.scrollDelta.dy > 0 ? -0.1 : 0.1);
102 : }
103 : }
104 :
105 1 : @override
106 : Widget build(BuildContext context) {
107 2 : zoom = Provider.of<AppZoom>(context, listen: false);
108 1 : if (isMobilePlatform) {
109 0 : return widget.child;
110 : }
111 1 : return Listener(
112 1 : onPointerSignal: onPointerSignal,
113 1 : child: KeyboardListener(
114 3 : focusNode: FocusController.force ? focus : (focus..requestFocus()),
115 1 : onKeyEvent: onKeyEvent,
116 2 : child: widget.child,
117 : ),
118 : );
119 : }
120 : }
|