@@ -8,7 +8,7 @@ import '../utils/icons.dart';
88import 'create_control.dart' ;
99import 'error.dart' ;
1010
11- class IconButtonControl extends StatelessWidget {
11+ class IconButtonControl extends StatefulWidget {
1212 final Control ? parent;
1313 final Control control;
1414 final List <Control > children;
@@ -22,39 +22,70 @@ class IconButtonControl extends StatelessWidget {
2222 required this .parentDisabled})
2323 : super (key: key);
2424
25+ @override
26+ State <IconButtonControl > createState () => _IconButtonControlState ();
27+ }
28+
29+ class _IconButtonControlState extends State <IconButtonControl > {
30+ late final FocusNode _focusNode;
31+ String ? _lastFocusValue;
32+
33+ @override
34+ void initState () {
35+ super .initState ();
36+ _focusNode = FocusNode ();
37+ _focusNode.addListener (_onFocusChange);
38+ }
39+
40+ @override
41+ void dispose () {
42+ _focusNode.removeListener (_onFocusChange);
43+ _focusNode.dispose ();
44+ super .dispose ();
45+ }
46+
47+ void _onFocusChange () {
48+ FletAppServices .of (context).server.sendPageEvent (
49+ eventTarget: widget.control.id,
50+ eventName: _focusNode.hasFocus ? "focus" : "blur" ,
51+ eventData: "" );
52+ }
53+
2554 @override
2655 Widget build (BuildContext context) {
27- debugPrint ("Button build: ${control .id }" );
56+ debugPrint ("Button build: ${widget . control .id }" );
2857
29- IconData ? icon = getMaterialIcon (control.attrString ("icon" , "" )! );
58+ IconData ? icon = getMaterialIcon (widget. control.attrString ("icon" , "" )! );
3059 IconData ? selectedIcon =
31- getMaterialIcon (control.attrString ("selectedIcon" , "" )! );
60+ getMaterialIcon (widget. control.attrString ("selectedIcon" , "" )! );
3261 Color ? iconColor = HexColor .fromString (
33- Theme .of (context), control.attrString ("iconColor" , "" )! );
62+ Theme .of (context), widget. control.attrString ("iconColor" , "" )! );
3463 Color ? selectedIconColor = HexColor .fromString (
35- Theme .of (context), control.attrString ("selectedIconColor" , "" )! );
64+ Theme .of (context), widget. control.attrString ("selectedIconColor" , "" )! );
3665 Color ? bgColor = HexColor .fromString (
37- Theme .of (context), control.attrString ("bgColor" , "" )! );
38- double ? iconSize = control.attrDouble ("iconSize" );
39- var tooltip = control.attrString ("tooltip" );
40- var contentCtrls = children.where ((c) => c.name == "content" );
41- bool autofocus = control.attrBool ("autofocus" , false )! ;
42- bool selected = control.attrBool ("selected" , false )! ;
43- bool disabled = control.isDisabled || parentDisabled;
66+ Theme .of (context), widget. control.attrString ("bgColor" , "" )! );
67+ double ? iconSize = widget. control.attrDouble ("iconSize" );
68+ var tooltip = widget. control.attrString ("tooltip" );
69+ var contentCtrls = widget. children.where ((c) => c.name == "content" );
70+ bool autofocus = widget. control.attrBool ("autofocus" , false )! ;
71+ bool selected = widget. control.attrBool ("selected" , false )! ;
72+ bool disabled = widget. control.isDisabled || widget. parentDisabled;
4473
4574 Function ()? onPressed = disabled
4675 ? null
4776 : () {
48- debugPrint ("Button ${control .id } clicked!" );
77+ debugPrint ("Button ${widget . control .id } clicked!" );
4978 FletAppServices .of (context).server.sendPageEvent (
50- eventTarget: control.id, eventName: "click" , eventData: "" );
79+ eventTarget: widget.control.id,
80+ eventName: "click" ,
81+ eventData: "" );
5182 };
5283
5384 Widget ? button;
5485
5586 var theme = Theme .of (context);
5687
57- var style = parseButtonStyle (Theme .of (context), control, "style" ,
88+ var style = parseButtonStyle (Theme .of (context), widget. control, "style" ,
5889 defaultForegroundColor: theme.colorScheme.primary,
5990 defaultBackgroundColor: Colors .transparent,
6091 defaultOverlayColor: Colors .transparent,
@@ -70,6 +101,7 @@ class IconButtonControl extends StatelessWidget {
70101 if (icon != null ) {
71102 button = IconButton (
72103 autofocus: autofocus,
104+ focusNode: _focusNode,
73105 icon: Icon (
74106 icon,
75107 color: iconColor,
@@ -85,6 +117,7 @@ class IconButtonControl extends StatelessWidget {
85117 } else if (contentCtrls.isNotEmpty) {
86118 button = IconButton (
87119 autofocus: autofocus,
120+ focusNode: _focusNode,
88121 onPressed: onPressed,
89122 iconSize: iconSize,
90123 style: style,
@@ -93,7 +126,7 @@ class IconButtonControl extends StatelessWidget {
93126 selectedIcon: selectedIcon != null
94127 ? Icon (selectedIcon, color: selectedIconColor)
95128 : null ,
96- icon: createControl (control, contentCtrls.first.id, disabled));
129+ icon: createControl (widget. control, contentCtrls.first.id, disabled));
97130 } else {
98131 return const ErrorControl (
99132 "Icon button does not have an icon neither content specified." );
@@ -107,6 +140,12 @@ class IconButtonControl extends StatelessWidget {
107140 );
108141 }
109142
110- return constrainedControl (context, button, parent, control);
143+ var focusValue = widget.control.attrString ("focus" );
144+ if (focusValue != null && focusValue != _lastFocusValue) {
145+ _lastFocusValue = focusValue;
146+ _focusNode.requestFocus ();
147+ }
148+
149+ return constrainedControl (context, button, widget.parent, widget.control);
111150 }
112151}
0 commit comments