Skip to content

Commit

Permalink
Focusable ElevatedButton
Browse files Browse the repository at this point in the history
Close #1048
  • Loading branch information
FeodorFitsner committed Feb 22, 2023
1 parent 6b4e27f commit c573f4c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 19 deletions.
80 changes: 61 additions & 19 deletions package/lib/src/controls/elevated_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<Control> children;
Expand All @@ -22,45 +22,76 @@ class ElevatedButtonControl extends StatelessWidget {
required this.parentDisabled})
: super(key: key);

@override
State<ElevatedButtonControl> createState() => _ElevatedButtonControlState();
}

class _ElevatedButtonControlState extends State<ElevatedButtonControl> {
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: "");
}
: null;

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());
}
Expand All @@ -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),
Expand All @@ -91,6 +122,7 @@ class ElevatedButtonControl extends StatelessWidget {
button = ElevatedButton.icon(
style: style,
autofocus: autofocus,
focusNode: _focusNode,
onPressed: onPressed,
onLongPress: onLongPressHandler,
onHover: onHoverHandler,
Expand All @@ -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);
}
}
31 changes: 31 additions & 0 deletions sdk/python/packages/flet-core/src/flet_core/elevated_button.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
from typing import Any, Optional, Union

from flet_core.buttons import ButtonStyle
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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)

0 comments on commit c573f4c

Please sign in to comment.