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/_configs/screen_helper.dart';
6 : import 'package:app_finance/_configs/theme_helper.dart';
7 : import 'package:app_finance/_ext/build_context_ext.dart';
8 : import 'package:app_finance/design/wrapper/text_wrapper.dart';
9 : import 'package:flutter/material.dart';
10 : import 'package:flutter/semantics.dart';
11 : import 'package:provider/provider.dart';
12 :
13 : typedef OnPressedFunction = void Function();
14 :
15 : class FullSizedButtonWidget extends StatelessWidget {
16 : final OnPressedFunction onPressed;
17 : final String title;
18 : final IconData icon;
19 : final BoxConstraints? constraints;
20 : final FocusController? controller;
21 : late final String heroTag;
22 :
23 1 : FullSizedButtonWidget({
24 : super.key,
25 : required this.onPressed,
26 : required this.title,
27 : required this.icon,
28 : this.constraints,
29 : this.controller,
30 2 : }) : heroTag = 'fz_button_${UniqueKey()}';
31 :
32 1 : @override
33 : Widget build(BuildContext context) {
34 3 : final isBottom = constraints != null ? ThemeHelper.isNavBottom(constraints!) : false;
35 1 : final bool isKeyboardVisible = ThemeHelper.isKeyboardVisible(context) || isBottom;
36 1 : final colorScheme = context.colorScheme;
37 1 : final indent = ThemeHelper.getIndent(4);
38 5 : final width = constraints != null ? constraints!.maxWidth - indent - 2 : double.infinity;
39 1 : final isWide = ScreenHelper.state().isWide;
40 1 : return ChangeNotifierProvider(
41 2 : create: (context) => _HoverModel(),
42 1 : child: Container(
43 0 : margin: isWide ? EdgeInsets.only(left: ThemeHelper.menuWidth + indent) : EdgeInsets.zero,
44 : width: isKeyboardVisible ? null : width,
45 2 : child: Consumer<_HoverModel>(builder: (context, hoverModel, _) {
46 3 : final color = context.textTheme.bodyLarge?.color;
47 1 : return MouseRegion(
48 0 : onEnter: (_) => hoverModel.setHover(true),
49 0 : onExit: (_) => hoverModel.setHover(false),
50 1 : child: Semantics(
51 2 : attributedLabel: AttributedString(title),
52 : button: true,
53 1 : child: FloatingActionButton(
54 1 : heroTag: heroTag,
55 1 : onPressed: onPressed,
56 1 : hoverColor: colorScheme.primary,
57 2 : focusColor: colorScheme.primary.withOpacity(0.8),
58 1 : tooltip: title,
59 2 : focusNode: controller?.last(this),
60 1 : child: Row(
61 : mainAxisAlignment: MainAxisAlignment.center,
62 1 : children: [
63 1 : Icon(
64 1 : icon,
65 1 : semanticLabel: title,
66 : size: 32,
67 1 : color: hoverModel.isHovered ? colorScheme.onPrimary : color,
68 : ),
69 : if (!isKeyboardVisible)
70 0 : Container(
71 0 : padding: EdgeInsets.only(left: ThemeHelper.getIndent()),
72 0 : constraints: BoxConstraints(maxWidth: width - 34),
73 0 : child: TextWrapper(
74 0 : title,
75 0 : style: context.textTheme.bodyLarge
76 0 : ?.copyWith(color: hoverModel.isHovered ? colorScheme.onPrimary : color),
77 : ),
78 : ),
79 : ],
80 : ),
81 : ),
82 : ),
83 : );
84 : }),
85 : ),
86 : );
87 : }
88 : }
89 :
90 : class _HoverModel extends ChangeNotifier {
91 : bool isHovered = false;
92 :
93 0 : void setHover(bool value) {
94 0 : if (isHovered != value) {
95 0 : isHovered = value;
96 0 : notifyListeners();
97 : }
98 : }
99 : }
|