diff --git a/package/lib/src/controls/elevated_button.dart b/package/lib/src/controls/elevated_button.dart index 20dac37ac..91b20e150 100644 --- a/package/lib/src/controls/elevated_button.dart +++ b/package/lib/src/controls/elevated_button.dart @@ -8,7 +8,7 @@ import '../utils/icons.dart'; import 'create_control.dart'; import 'error.dart'; -class ElevatedButtonControl extends StatelessWidget { +class ElevatedButtonControl extends StatefulWidget { final Control? parent; final Control control; final List children; @@ -22,35 +22,66 @@ class ElevatedButtonControl extends StatelessWidget { required this.parentDisabled}) : super(key: key); + @override + State createState() => _ElevatedButtonControlState(); +} + +class _ElevatedButtonControlState extends State { + late final FocusNode _focusNode; + String? _lastFocusValue; + + @override + void initState() { + super.initState(); + _focusNode = FocusNode(); + _focusNode.addListener(_onFocusChange); + } + + @override + void dispose() { + _focusNode.removeListener(_onFocusChange); + _focusNode.dispose(); + super.dispose(); + } + + void _onFocusChange() { + FletAppServices.of(context).server.sendPageEvent( + eventTarget: widget.control.id, + eventName: _focusNode.hasFocus ? "focus" : "blur", + eventData: ""); + } + @override Widget build(BuildContext context) { - debugPrint("Button build: ${control.id}"); + debugPrint("Button build: ${widget.control.id}"); final server = FletAppServices.of(context).server; - String text = control.attrString("text", "")!; - IconData? icon = getMaterialIcon(control.attrString("icon", "")!); + String text = widget.control.attrString("text", "")!; + IconData? icon = getMaterialIcon(widget.control.attrString("icon", "")!); Color? iconColor = HexColor.fromString( - Theme.of(context), control.attrString("iconColor", "")!); - var contentCtrls = children.where((c) => c.name == "content"); - bool onHover = control.attrBool("onHover", false)!; - bool onLongPress = control.attrBool("onLongPress", false)!; - bool autofocus = control.attrBool("autofocus", false)!; - bool disabled = control.isDisabled || parentDisabled; + Theme.of(context), widget.control.attrString("iconColor", "")!); + var contentCtrls = widget.children.where((c) => c.name == "content"); + bool onHover = widget.control.attrBool("onHover", false)!; + bool onLongPress = widget.control.attrBool("onLongPress", false)!; + bool autofocus = widget.control.attrBool("autofocus", false)!; + bool disabled = widget.control.isDisabled || widget.parentDisabled; Function()? onPressed = !disabled ? () { - debugPrint("Button ${control.id} clicked!"); + debugPrint("Button ${widget.control.id} clicked!"); server.sendPageEvent( - eventTarget: control.id, eventName: "click", eventData: ""); + eventTarget: widget.control.id, + eventName: "click", + eventData: ""); } : null; Function()? onLongPressHandler = onLongPress && !disabled ? () { - debugPrint("Button ${control.id} long pressed!"); + debugPrint("Button ${widget.control.id} long pressed!"); server.sendPageEvent( - eventTarget: control.id, + eventTarget: widget.control.id, eventName: "long_press", eventData: ""); } @@ -58,9 +89,9 @@ class ElevatedButtonControl extends StatelessWidget { Function(bool)? onHoverHandler = onHover && !disabled ? (state) { - debugPrint("Button ${control.id} hovered!"); + debugPrint("Button ${widget.control.id} hovered!"); server.sendPageEvent( - eventTarget: control.id, + eventTarget: widget.control.id, eventName: "hover", eventData: state.toString()); } @@ -70,7 +101,7 @@ class ElevatedButtonControl extends StatelessWidget { var theme = Theme.of(context); - var style = parseButtonStyle(Theme.of(context), control, "style", + var style = parseButtonStyle(Theme.of(context), widget.control, "style", defaultForegroundColor: theme.colorScheme.primary, defaultBackgroundColor: theme.colorScheme.surface, defaultOverlayColor: theme.colorScheme.primary.withOpacity(0.08), @@ -91,6 +122,7 @@ class ElevatedButtonControl extends StatelessWidget { button = ElevatedButton.icon( style: style, autofocus: autofocus, + focusNode: _focusNode, onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, @@ -103,19 +135,29 @@ class ElevatedButtonControl extends StatelessWidget { button = ElevatedButton( style: style, autofocus: autofocus, + focusNode: _focusNode, onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, - child: createControl(control, contentCtrls.first.id, disabled)); + child: + createControl(widget.control, contentCtrls.first.id, disabled)); } else { button = ElevatedButton( style: style, + autofocus: autofocus, + focusNode: _focusNode, onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, child: Text(text)); } - return constrainedControl(context, button, parent, control); + var focusValue = widget.control.attrString("focus"); + if (focusValue != null && focusValue != _lastFocusValue) { + _lastFocusValue = focusValue; + _focusNode.requestFocus(); + } + + return constrainedControl(context, button, widget.parent, widget.control); } } diff --git a/sdk/python/packages/flet-core/src/flet_core/elevated_button.py b/sdk/python/packages/flet-core/src/flet_core/elevated_button.py index 6de7255b8..eb25e10b9 100644 --- a/sdk/python/packages/flet-core/src/flet_core/elevated_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/elevated_button.py @@ -1,3 +1,4 @@ +import time from typing import Any, Optional, Union from flet_core.buttons import ButtonStyle @@ -78,6 +79,8 @@ def __init__( on_click=None, on_long_press=None, on_hover=None, + on_focus=None, + on_blur=None, ): ConstrainedControl.__init__( self, @@ -124,6 +127,8 @@ def __init__( self.on_click = on_click self.on_long_press = on_long_press self.on_hover = on_hover + self.on_focus = on_focus + self.on_blur = on_blur def _get_control_name(self): return "elevatedbutton" @@ -151,6 +156,14 @@ def _get_children(self): self.__content._set_attr_internal("n", "content") return [self.__content] + def focus(self): + self._set_attr_json("focus", str(time.time())) + self.update() + + async def focus_async(self): + self._set_attr_json("focus", str(time.time())) + await self.update_async() + # text @property def text(self): @@ -260,3 +273,21 @@ def on_hover(self): def on_hover(self, handler): self._add_event_handler("hover", handler) self._set_attr("onHover", True if handler is not None else None) + + # on_focus + @property + def on_focus(self): + return self._get_event_handler("focus") + + @on_focus.setter + def on_focus(self, handler): + self._add_event_handler("focus", handler) + + # on_blur + @property + def on_blur(self): + return self._get_event_handler("blur") + + @on_blur.setter + def on_blur(self, handler): + self._add_event_handler("blur", handler)