Line data Source code
1 : // Copyright 2014 The Flutter Authors.
2 : // Copyright 2021 Suragch.
3 : // All rights reserved.
4 : // Use of this source code is governed by a BSD-style license that can be
5 : // found in the LICENSE file.
6 :
7 : import 'dart:math' as math;
8 : import 'package:flutter/foundation.dart';
9 : import 'package:flutter/material.dart'
10 : show
11 : IconButton,
12 : VisualDensity,
13 : debugCheckHasMaterial,
14 : ThemeData,
15 : Theme,
16 : Material,
17 : kMinInteractiveDimension,
18 : InkResponse;
19 : import 'package:flutter/widgets.dart';
20 :
21 : import 'mongol_tooltip.dart';
22 :
23 : // Minimum logical pixel size of the IconButton.
24 : // See: <https://material.io/design/usability/accessibility.html#layout-typography>.
25 : const double _kMinButtonSize = kMinInteractiveDimension;
26 :
27 : /// An IconButton that uses a MongolTooltip
28 : ///
29 : /// Everything else about this widget except for the Tooltip should behave
30 : /// exactly like IconButton.
31 : class MongolIconButton extends IconButton {
32 1 : const MongolIconButton({
33 : Key? key,
34 : double iconSize = 24.0,
35 : VisualDensity? visualDensity,
36 : EdgeInsetsGeometry padding = const EdgeInsets.all(8.0),
37 : AlignmentGeometry alignment = Alignment.center,
38 : double? splashRadius,
39 : Color? color,
40 : Color? focusColor,
41 : Color? hoverColor,
42 : Color? highlightColor,
43 : Color? splashColor,
44 : Color? disabledColor,
45 : required void Function()? onPressed,
46 : MouseCursor mouseCursor = SystemMouseCursors.click,
47 : FocusNode? focusNode,
48 : bool autofocus = false,
49 : required this.mongolTooltip,
50 : bool enableFeedback = true,
51 : BoxConstraints? constraints,
52 : required Widget icon,
53 0 : }) : assert(splashRadius == null || splashRadius > 0),
54 1 : super(
55 : key: key,
56 : iconSize: iconSize,
57 : visualDensity: visualDensity,
58 : padding: padding,
59 : alignment: alignment,
60 : splashRadius: splashRadius,
61 : color: color,
62 : focusColor: focusColor,
63 : hoverColor: hoverColor,
64 : highlightColor: highlightColor,
65 : splashColor: splashColor,
66 : disabledColor: disabledColor,
67 : onPressed: onPressed,
68 : mouseCursor: mouseCursor,
69 : focusNode: focusNode,
70 : autofocus: autofocus,
71 : tooltip: mongolTooltip,
72 : enableFeedback: enableFeedback,
73 : constraints: constraints,
74 : icon: icon,
75 : );
76 :
77 : /// Mongolian text that describes the action that will occur when the button
78 : /// is pressed.
79 : ///
80 : /// This text is displayed when the user long-presses on the button and is
81 : /// used for accessibility.
82 : final String mongolTooltip;
83 :
84 1 : @override
85 : Widget build(BuildContext context) {
86 1 : assert(debugCheckHasMaterial(context));
87 1 : final ThemeData theme = Theme.of(context);
88 : Color? currentColor;
89 1 : if (onPressed != null) {
90 1 : currentColor = color;
91 : } else {
92 0 : currentColor = disabledColor ?? theme.disabledColor;
93 : }
94 :
95 : final VisualDensity effectiveVisualDensity =
96 2 : visualDensity ?? theme.visualDensity;
97 :
98 1 : final BoxConstraints unadjustedConstraints = constraints ??
99 : const BoxConstraints(
100 : minWidth: _kMinButtonSize,
101 : minHeight: _kMinButtonSize,
102 : );
103 : final BoxConstraints adjustedConstraints =
104 1 : effectiveVisualDensity.effectiveConstraints(unadjustedConstraints);
105 :
106 1 : Widget result = MongolTooltip(
107 1 : message: mongolTooltip,
108 1 : child: ConstrainedBox(
109 : constraints: adjustedConstraints,
110 1 : child: Padding(
111 1 : padding: padding,
112 1 : child: SizedBox(
113 1 : height: iconSize,
114 1 : width: iconSize,
115 1 : child: Align(
116 1 : alignment: alignment,
117 1 : child: IconTheme.merge(
118 1 : data: IconThemeData(
119 1 : size: iconSize,
120 : color: currentColor,
121 : ),
122 1 : child: icon,
123 : ),
124 : ),
125 : ),
126 : ),
127 : ),
128 : );
129 :
130 1 : return Semantics(
131 : button: true,
132 1 : enabled: onPressed != null,
133 1 : child: InkResponse(
134 1 : focusNode: focusNode,
135 1 : autofocus: autofocus,
136 1 : canRequestFocus: onPressed != null,
137 1 : onTap: onPressed,
138 1 : mouseCursor: mouseCursor,
139 1 : enableFeedback: enableFeedback,
140 : child: result,
141 2 : focusColor: focusColor ?? theme.focusColor,
142 2 : hoverColor: hoverColor ?? theme.hoverColor,
143 2 : highlightColor: highlightColor ?? theme.highlightColor,
144 2 : splashColor: splashColor ?? theme.splashColor,
145 1 : radius: splashRadius ??
146 1 : math.max(
147 : Material.defaultSplashRadius,
148 8 : (iconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
149 : // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
150 : ),
151 : ),
152 : );
153 : }
154 : }
|