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 '../menu/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 3 : 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 : this.mongolTooltip,
50 : bool enableFeedback = true,
51 : BoxConstraints? constraints,
52 : required Widget icon,
53 1 : }) : assert(splashRadius == null || splashRadius > 0),
54 2 : 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 2 : @override
85 : Widget build(BuildContext context) {
86 2 : assert(debugCheckHasMaterial(context));
87 2 : final ThemeData theme = Theme.of(context);
88 : Color? currentColor;
89 2 : if (onPressed != null) {
90 2 : currentColor = color;
91 : } else {
92 2 : currentColor = disabledColor ?? theme.disabledColor;
93 : }
94 :
95 : final VisualDensity effectiveVisualDensity =
96 4 : visualDensity ?? theme.visualDensity;
97 :
98 2 : final BoxConstraints unadjustedConstraints = constraints ??
99 : const BoxConstraints(
100 : minWidth: _kMinButtonSize,
101 : minHeight: _kMinButtonSize,
102 : );
103 : final BoxConstraints adjustedConstraints =
104 2 : effectiveVisualDensity.effectiveConstraints(unadjustedConstraints);
105 :
106 2 : Widget result = ConstrainedBox(
107 : constraints: adjustedConstraints,
108 2 : child: Padding(
109 2 : padding: padding,
110 2 : child: SizedBox(
111 2 : height: iconSize,
112 2 : width: iconSize,
113 2 : child: Align(
114 2 : alignment: alignment,
115 2 : child: IconTheme.merge(
116 2 : data: IconThemeData(
117 2 : size: iconSize,
118 : color: currentColor,
119 : ),
120 2 : child: icon,
121 : ),
122 : ),
123 : ),
124 : ),
125 : );
126 :
127 2 : if (tooltip != null) {
128 2 : result = MongolTooltip(
129 2 : message: tooltip!,
130 : child: result,
131 : );
132 : }
133 :
134 2 : return Semantics(
135 : button: true,
136 2 : enabled: onPressed != null,
137 2 : child: InkResponse(
138 2 : focusNode: focusNode,
139 2 : autofocus: autofocus,
140 2 : canRequestFocus: onPressed != null,
141 2 : onTap: onPressed,
142 2 : mouseCursor: mouseCursor,
143 2 : enableFeedback: enableFeedback,
144 : child: result,
145 4 : focusColor: focusColor ?? theme.focusColor,
146 4 : hoverColor: hoverColor ?? theme.hoverColor,
147 4 : highlightColor: highlightColor ?? theme.highlightColor,
148 4 : splashColor: splashColor ?? theme.splashColor,
149 2 : radius: splashRadius ??
150 2 : math.max(
151 : Material.defaultSplashRadius,
152 16 : (iconSize + math.min(padding.horizontal, padding.vertical)) * 0.7,
153 : // x 0.5 for diameter -> radius and + 40% overflow derived from other Material apps.
154 : ),
155 : ),
156 : );
157 : }
158 : }
|