Live-Edit Modus #207

Merged
sneeex merged 20 commits from feature/202-live-edit-modus into development 2026-05-09 17:58:38 +00:00
2 changed files with 56 additions and 1 deletions
Showing only changes of commit 40e2229aa5 - Show all commits

View File

@@ -1,3 +1,5 @@
import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MainMenuButton extends StatefulWidget { class MainMenuButton extends StatefulWidget {
@@ -10,6 +12,7 @@ class MainMenuButton extends StatefulWidget {
required this.onPressed, required this.onPressed,
required this.icon, required this.icon,
this.text, this.text,
this.onLongPressed,
}); });
/// The callback to be invoked when the button is pressed. /// The callback to be invoked when the button is pressed.
@@ -21,6 +24,8 @@ class MainMenuButton extends StatefulWidget {
/// The text of the button. /// The text of the button.
final String? text; final String? text;
final void Function()? onLongPressed;
@override @override
State<MainMenuButton> createState() => _MainMenuButtonState(); State<MainMenuButton> createState() => _MainMenuButtonState();
} }
@@ -30,6 +35,14 @@ class _MainMenuButtonState extends State<MainMenuButton>
late AnimationController _animationController; late AnimationController _animationController;
late Animation<double> _scaleAnimation; late Animation<double> _scaleAnimation;
/// How long the button needs to be pressed to register it as long press
Timer? _longPressTimer;
/// How much time between two onLongPressed calls
Timer? _repeatTimer;
bool _isLongPressing = false;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -51,15 +64,29 @@ class _MainMenuButtonState extends State<MainMenuButton>
child: GestureDetector( child: GestureDetector(
onTapDown: (_) { onTapDown: (_) {
_animationController.forward(); _animationController.forward();
if (widget.onLongPressed != null) {
_longPressTimer = Timer(const Duration(milliseconds: 400), () {
_isLongPressing = true;
widget.onLongPressed?.call();
_repeatTimer = Timer.periodic(
const Duration(milliseconds: 250),
(_) => widget.onLongPressed?.call(),
);
});
}
}, },
onTapUp: (_) async { onTapUp: (_) async {
if (mounted) { _cancelTimers();
if (mounted && !_isLongPressing) {
widget.onPressed(); widget.onPressed();
} }
_isLongPressing = false;
await Future.delayed(const Duration(milliseconds: 100)); await Future.delayed(const Duration(milliseconds: 100));
await _animationController.reverse(); await _animationController.reverse();
}, },
onTapCancel: () { onTapCancel: () {
_isLongPressing = false;
_cancelTimers();
_animationController.reverse(); _animationController.reverse();
}, },
child: Container( child: Container(
@@ -93,7 +120,15 @@ class _MainMenuButtonState extends State<MainMenuButton>
@override @override
void dispose() { void dispose() {
_cancelTimers();
_animationController.dispose(); _animationController.dispose();
super.dispose(); super.dispose();
} }
void _cancelTimers() {
_longPressTimer?.cancel();
_longPressTimer = null;
_repeatTimer?.cancel();
_repeatTimer = null;
}
} }

View File

@@ -53,6 +53,16 @@ class _LiveEditListTileState extends State<LiveEditListTile> {
}), }),
} }
: null, : null,
onLongPressed: () => _score > minScore
? {
setState(() {
_score -= 10;
if (widget.onChanged != null) {
widget.onChanged!(_score);
}
}),
}
: null,
icon: Icons.remove_rounded, icon: Icons.remove_rounded,
), ),
Expanded( Expanded(
@@ -96,6 +106,16 @@ class _LiveEditListTileState extends State<LiveEditListTile> {
}), }),
} }
: null, : null,
onLongPressed: () => _score > minScore
? {
setState(() {
_score += 10;
if (widget.onChanged != null) {
widget.onChanged!(_score);
}
}),
}
: null,
icon: Icons.add_rounded, icon: Icons.add_rounded,
), ),
], ],