From d7f4b1c227f10c83b956e9db6724b3fdd180ec6c Mon Sep 17 00:00:00 2001 From: Mathis Kirchner Date: Tue, 13 Jan 2026 20:41:03 +0100 Subject: [PATCH] seperate button into widget & change to agreed design --- .../views/main_menu/settings_view.dart | 61 +------------------ .../buttons/animated_dialog_button.dart | 48 +++++++++++++++ 2 files changed, 51 insertions(+), 58 deletions(-) create mode 100644 lib/presentation/widgets/buttons/animated_dialog_button.dart diff --git a/lib/presentation/views/main_menu/settings_view.dart b/lib/presentation/views/main_menu/settings_view.dart index cab26ef..21b9d64 100644 --- a/lib/presentation/views/main_menu/settings_view.dart +++ b/lib/presentation/views/main_menu/settings_view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:game_tracker/core/custom_theme.dart'; import 'package:game_tracker/core/enums.dart'; import 'package:game_tracker/l10n/generated/app_localizations.dart'; +import 'package:game_tracker/presentation/widgets/buttons/animated_dialog_button.dart'; import 'package:game_tracker/presentation/widgets/tiles/settings_list_tile.dart'; import 'package:game_tracker/services/data_transfer_service.dart'; import 'package:package_info_plus/package_info_plus.dart'; @@ -97,11 +98,11 @@ class _SettingsViewState extends State { title: '${loc.delete_all_data}?', content: loc.this_cannot_be_undone, actions: [ - _PressableButton( + AnimatedDialogButton( onPressed: () => Navigator.of(context).pop(false), child: Text(loc.cancel, style: const TextStyle(color: CustomTheme.textColor)), ), - _PressableButton( + AnimatedDialogButton( onPressed: () => Navigator.of(context).pop(true), child: Text(loc.delete, style: TextStyle(color: CustomTheme.secondaryColor)), ), @@ -218,59 +219,3 @@ class _SettingsViewState extends State { }); } } - -class _PressableButton extends StatefulWidget { - final VoidCallback onPressed; - final Widget child; - - const _PressableButton({required this.onPressed, required this.child}); - - @override - State<_PressableButton> createState() => _PressableButtonState(); -} - -class _PressableButtonState extends State<_PressableButton> { - bool _isPressed = false; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTapDown: (_) => setState(() => _isPressed = true), - onTapUp: (_) => setState(() => _isPressed = false), - onTapCancel: () => setState(() => _isPressed = false), - onTap: widget.onPressed, - child: AnimatedScale( - scale: _isPressed ? 0.95 : 1.0, - duration: const Duration(milliseconds: 100), - child: AnimatedOpacity( - opacity: _isPressed ? 0.6 : 1.0, - duration: const Duration(milliseconds: 100), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: widget.child, - ), - ), - ), - ); - } -} - - -/* - TextButton( - style: TextButton.styleFrom( - splashFactory: NoSplash.splashFactory, - overlayColor: Colors.transparent, - ), - onPressed: () => Navigator.of(context).pop(false), - child: Text(loc.cancel, style: const TextStyle(color: CustomTheme.textColor),), - ), - TextButton( - style: TextButton.styleFrom( - splashFactory: NoSplash.splashFactory, - overlayColor: Colors.transparent, - ), - onPressed: () => Navigator.of(context).pop(true), - child: Text(loc.delete, style: TextStyle(color: CustomTheme.secondaryColor),), - ), - */ diff --git a/lib/presentation/widgets/buttons/animated_dialog_button.dart b/lib/presentation/widgets/buttons/animated_dialog_button.dart new file mode 100644 index 0000000..cf49c19 --- /dev/null +++ b/lib/presentation/widgets/buttons/animated_dialog_button.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:game_tracker/core/custom_theme.dart'; + +/// A custom animated button widget that provides a scaling and opacity effect +/// when pressed. This widget is designed to be used in dialogs or other UI +/// components where a visually appealing button is required. +class AnimatedDialogButton extends StatefulWidget { + /// Callback function that is triggered when the button is pressed. + final VoidCallback onPressed; + + /// The child widget to be displayed inside the button, typically a text or icon. + final Widget child; + + /// Creates an instance of `AnimatedDialogButton`. + /// + /// The [onPressed] and [child] parameters are required. + const AnimatedDialogButton({required this.onPressed, required this.child}); + + @override + State createState() => _AnimatedDialogButtonState(); +} + +class _AnimatedDialogButtonState extends State { + bool _isPressed = false; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTapDown: (_) => setState(() => _isPressed = true), + onTapUp: (_) => setState(() => _isPressed = false), + onTapCancel: () => setState(() => _isPressed = false), + onTap: widget.onPressed, + child: AnimatedScale( + scale: _isPressed ? 0.95 : 1.0, + duration: const Duration(milliseconds: 100), + child: AnimatedOpacity( + opacity: _isPressed ? 0.6 : 1.0, + duration: const Duration(milliseconds: 100), + child: Container( + decoration: CustomTheme.standardBoxDecoration, + padding: EdgeInsets.symmetric(horizontal: 26, vertical: 6), + child: widget.child, + ), + ), + ), + ); + } +}