From a38e461db4813115cbdf73075f252fa03d0c8c28 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 4 Mar 2024 21:16:26 +0100 Subject: [PATCH 001/103] initial commit --- packages/flet/lib/src/controls/card.dart | 9 +++++++++ packages/flet/lib/src/controls/checkbox.dart | 5 +++++ .../flet/lib/src/controls/circle_avatar.dart | 11 ++++++++++- .../flet/lib/src/controls/create_control.dart | 6 ++++-- packages/flet/lib/src/controls/divider.dart | 4 ++++ .../flet/lib/src/controls/drag_target.dart | 12 ++++++++++++ packages/flet/lib/src/controls/draggable.dart | 18 ++++++++++++------ 7 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/flet/lib/src/controls/card.dart b/packages/flet/lib/src/controls/card.dart index 6e3f188a6..225ecda32 100644 --- a/packages/flet/lib/src/controls/card.dart +++ b/packages/flet/lib/src/controls/card.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; @@ -27,6 +28,11 @@ class CardControl extends StatelessWidget { var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); + var clipBehavior = Clip.values.firstWhereOrNull( + (e) => + e.name.toLowerCase() == + control.attrString("clipBehavior", "")!.toLowerCase(), + ); bool disabled = control.isDisabled || parentDisabled; bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; @@ -36,6 +42,9 @@ class CardControl extends StatelessWidget { elevation: control.attrDouble("elevation"), shape: parseOutlinedBorder(control, "shape"), margin: parseEdgeInsets(control, "margin"), + semanticContainer: control.attrBool("semanticContainer", true)!, + borderOnForeground: control.attrBool("borderOnForeground", true)!, + clipBehavior: clipBehavior, color: HexColor.fromString( Theme.of(context), control.attrString("color", "")!), shadowColor: HexColor.fromString( diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index 219b9cdf8..7e342354b 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; import '../utils/colors.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -118,6 +119,10 @@ class _CheckboxControlState extends State with FletStoreMixin { autofocus: autofocus, focusNode: _focusNode, value: _value, + isError: widget.control.attrBool("error", false)!, + semanticLabel: widget.control.attrString("semanticsLabel"), + shape: parseOutlinedBorder(widget.control, "shape"), + splashRadius: widget.control.attrDouble("splashRadius"), activeColor: HexColor.fromString( Theme.of(context), widget.control.attrString("activeColor", "")!), focusColor: HexColor.fromString( diff --git a/packages/flet/lib/src/controls/circle_avatar.dart b/packages/flet/lib/src/controls/circle_avatar.dart index 0fa9ea87d..ff8b85672 100644 --- a/packages/flet/lib/src/controls/circle_avatar.dart +++ b/packages/flet/lib/src/controls/circle_avatar.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; import 'create_control.dart'; @@ -9,13 +10,15 @@ class CircleAvatarControl extends StatelessWidget { final Control control; final List children; final bool parentDisabled; + final FletControlBackend backend; const CircleAvatarControl( {super.key, this.parent, required this.control, required this.children, - required this.parentDisabled}); + required this.parentDisabled, + required this.backend}); @override Widget build(BuildContext context) { @@ -40,6 +43,12 @@ class CircleAvatarControl extends StatelessWidget { radius: control.attrDouble("radius"), minRadius: control.attrDouble("minRadius"), maxRadius: control.attrDouble("maxRadius"), + onBackgroundImageError: (object, trace) { + backend.triggerControlEvent(control.id, "imageError"); + }, + onForegroundImageError: (object, trace) { + backend.triggerControlEvent(control.id, "imageError"); + }, child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled) : null); diff --git a/packages/flet/lib/src/controls/create_control.dart b/packages/flet/lib/src/controls/create_control.dart index 0a9627123..c6b385191 100644 --- a/packages/flet/lib/src/controls/create_control.dart +++ b/packages/flet/lib/src/controls/create_control.dart @@ -296,7 +296,8 @@ Widget createWidget( parent: parent, control: controlView.control, children: controlView.children, - parentDisabled: parentDisabled); + parentDisabled: parentDisabled, + backend: backend); case "chip": return ChipControl( key: key, @@ -533,7 +534,8 @@ Widget createWidget( control: controlView.control, children: controlView.children, parentDisabled: parentDisabled, - parentAdaptive: parentAdaptive); + parentAdaptive: parentAdaptive, + backend: backend); case "dragtarget": return DragTargetControl( key: key, diff --git a/packages/flet/lib/src/controls/divider.dart b/packages/flet/lib/src/controls/divider.dart index 7187ad518..6079c2159 100644 --- a/packages/flet/lib/src/controls/divider.dart +++ b/packages/flet/lib/src/controls/divider.dart @@ -15,6 +15,8 @@ class DividerControl extends StatelessWidget { debugPrint("Divider build: ${control.id}"); var height = control.attrDouble("height"); + var indent = control.attrDouble("indent"); + var endIndent = control.attrDouble("endIndent"); var thickness = control.attrDouble("thickness"); var color = HexColor.fromString( Theme.of(context), control.attrString("color", "")!); @@ -25,6 +27,8 @@ class DividerControl extends StatelessWidget { height: height, thickness: thickness, color: color, + indent: indent, + endIndent: endIndent, ), parent, control); diff --git a/packages/flet/lib/src/controls/drag_target.dart b/packages/flet/lib/src/controls/drag_target.dart index db41b26d6..b1125bb31 100644 --- a/packages/flet/lib/src/controls/drag_target.dart +++ b/packages/flet/lib/src/controls/drag_target.dart @@ -70,6 +70,18 @@ class DragTargetControl extends StatelessWidget { "DragTarget.builder ${control.id}: accepted=${accepted.length}, rejected=${rejected.length}"); return child; }, + onMove: (details) { + var data = details.data; + debugPrint("DragTarget.onMove ${control.id}: $data"); + var jd = json.decode(data); + var srcId = jd["id"] as String; + backend.triggerControlEvent( + control.id, + "move", + json.encode(DragTargetAcceptEvent( + srcId: srcId, x: details.offset.dx, y: details.offset.dy) + .toJson())); + }, onWillAcceptWithDetails: (details) { var data = details.data; debugPrint("DragTarget.onWillAcceptWithDetails ${control.id}: $data"); diff --git a/packages/flet/lib/src/controls/draggable.dart b/packages/flet/lib/src/controls/draggable.dart index dcf36ccd7..c6fe6490b 100644 --- a/packages/flet/lib/src/controls/draggable.dart +++ b/packages/flet/lib/src/controls/draggable.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; +import '../flet_control_backend.dart'; import '../models/control.dart'; import 'create_control.dart'; import 'error.dart'; @@ -12,6 +13,7 @@ class DraggableControl extends StatelessWidget { final List children; final bool parentDisabled; final bool? parentAdaptive; + final FletControlBackend backend; const DraggableControl( {super.key, @@ -19,7 +21,8 @@ class DraggableControl extends StatelessWidget { required this.control, required this.children, required this.parentDisabled, - required this.parentAdaptive}); + required this.parentAdaptive, + required this.backend}); @override Widget build(BuildContext context) { @@ -62,15 +65,18 @@ class DraggableControl extends StatelessWidget { cursor: SystemMouseCursors.grabbing, child: childFeedback ?? Opacity(opacity: 0.5, child: child), ), + onDragStarted: () { + debugPrint("Draggable.onDragStarted ${control.id}"); + backend.triggerControlEvent(control.id, "dragStarted"); + }, + onDragCompleted: () { + debugPrint("Draggable.onDragCompleted ${control.id}"); + backend.triggerControlEvent(control.id, "dragCompleted"); + }, child: MouseRegion( cursor: SystemMouseCursors.grab, child: child, ), - // dragAnchorStrategy: (d, context, offset) { - // debugPrint("dragAnchorStrategy: ${offset.dx}, ${offset.dy}"); - // return offset; - // } - //feedbackOffset: const Offset(-30, -30), ); } } From fe3d122187a187fcb6c748a51c81b7be312b8def Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 14:19:10 +0100 Subject: [PATCH 002/103] Pass data to Control.__init__ Fixes #2826 --- .../packages/flet-core/src/flet_core/popup_menu_button.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 17595f384..0d1c17dd8 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -26,14 +26,14 @@ def __init__( checked: Optional[bool] = None, content: Optional[Control] = None, on_click=None, - data: Any = None, # # Control # ref: Optional[Ref] = None, disabled: Optional[bool] = None, + data: Any = None, ): - Control.__init__(self, ref=ref, disabled=disabled) + Control.__init__(self, ref=ref, disabled=disabled, data=data) self.checked = checked self.icon = icon From d25f41c5339a3264e5aa2dcf120eb31c48b55469 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:08:33 +0100 Subject: [PATCH 003/103] CircleAvatar: on_image_error --- packages/flet/lib/src/controls/circle_avatar.dart | 4 ++-- .../packages/flet-core/src/flet_core/circle_avatar.py | 11 +++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/circle_avatar.dart b/packages/flet/lib/src/controls/circle_avatar.dart index ff8b85672..5ef07ece9 100644 --- a/packages/flet/lib/src/controls/circle_avatar.dart +++ b/packages/flet/lib/src/controls/circle_avatar.dart @@ -44,10 +44,10 @@ class CircleAvatarControl extends StatelessWidget { minRadius: control.attrDouble("minRadius"), maxRadius: control.attrDouble("maxRadius"), onBackgroundImageError: (object, trace) { - backend.triggerControlEvent(control.id, "imageError"); + backend.triggerControlEvent(control.id, "imageError", "background"); }, onForegroundImageError: (object, trace) { - backend.triggerControlEvent(control.id, "imageError"); + backend.triggerControlEvent(control.id, "imageError", "foreground"); }, child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled) diff --git a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py index 4cd8750ac..9efa93e76 100644 --- a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py +++ b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py @@ -78,6 +78,7 @@ def __init__( radius: OptionalNumber = None, min_radius: OptionalNumber = None, max_radius: OptionalNumber = None, + on_image_error=None, # # ConstrainedControl # @@ -148,6 +149,7 @@ def __init__( self.color = color self.bgcolor = bgcolor self.content = content + self.on_image_error = on_image_error def _get_control_name(self): return "circleavatar" @@ -229,3 +231,12 @@ def content(self) -> Optional[Control]: @content.setter def content(self, value: Optional[Control]): self.__content = value + + # on_image_error + @property + def on_image_error(self): + return self._get_event_handler("imageError") + + @on_image_error.setter + def on_image_error(self, handler): + self._add_event_handler("imageError", handler) From 1dd103ff90437e43a29478f4a966ea2e47988444 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:09:51 +0100 Subject: [PATCH 004/103] Card: clip_behavior, is_semantic_container, show_border_on_foreground --- packages/flet/lib/src/controls/card.dart | 5 ++- .../packages/flet-core/src/flet_core/card.py | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/card.dart b/packages/flet/lib/src/controls/card.dart index 225ecda32..a0adcf0b8 100644 --- a/packages/flet/lib/src/controls/card.dart +++ b/packages/flet/lib/src/controls/card.dart @@ -42,8 +42,9 @@ class CardControl extends StatelessWidget { elevation: control.attrDouble("elevation"), shape: parseOutlinedBorder(control, "shape"), margin: parseEdgeInsets(control, "margin"), - semanticContainer: control.attrBool("semanticContainer", true)!, - borderOnForeground: control.attrBool("borderOnForeground", true)!, + semanticContainer: control.attrBool("isSemanticContainer", true)!, + borderOnForeground: + control.attrBool("showBorderOnForeground", true)!, clipBehavior: clipBehavior, color: HexColor.fromString( Theme.of(context), control.attrString("color", "")!), diff --git a/sdk/python/packages/flet-core/src/flet_core/card.py b/sdk/python/packages/flet-core/src/flet_core/card.py index 3bfe8e591..e354f9da3 100644 --- a/sdk/python/packages/flet-core/src/flet_core/card.py +++ b/sdk/python/packages/flet-core/src/flet_core/card.py @@ -7,6 +7,7 @@ from flet_core.ref import Ref from flet_core.types import ( AnimationValue, + ClipBehavior, MarginValue, OffsetValue, ResponsiveNumber, @@ -67,6 +68,9 @@ def __init__( shadow_color: Optional[str] = None, surface_tint_color: Optional[str] = None, shape: Optional[OutlinedBorder] = None, + clip_behavior: Optional[ClipBehavior] = None, + is_semantic_container: Optional[bool] = None, + show_border_on_foreground: Optional[bool] = None, # # ConstrainedControl and AdaptiveControl # @@ -139,6 +143,9 @@ def __init__( self.shadow_color = shadow_color self.surface_tint_color = surface_tint_color self.shape = shape + self.clip_behavior = clip_behavior + self.is_semantic_container = is_semantic_container + self.show_border_on_foreground = show_border_on_foreground def _get_control_name(self): return "card" @@ -217,3 +224,36 @@ def content(self) -> Optional[Control]: @content.setter def content(self, value: Optional[Control]): self.__content = value + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", + value.value if isinstance(value, ClipBehavior) else value, + ) + + # is_semantic_container + @property + def is_semantic_container(self) -> Optional[bool]: + return self._get_attr("isSemanticContainer", data_type="bool", def_value=True) + + @is_semantic_container.setter + def is_semantic_container(self, value): + self._set_attr("isSemanticContainer", value) + + # show_border_on_foreground + @property + def show_border_on_foreground(self) -> Optional[bool]: + return self._get_attr( + "showBorderOnForeground", data_type="bool", def_value=True + ) + + @show_border_on_foreground.setter + def show_border_on_foreground(self, value): + self._set_attr("showBorderOnForeground", value) From 962c208df5c7e67f68005a3c5121525da67eaaf0 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:12:52 +0100 Subject: [PATCH 005/103] Checkbox: semantics_label, shape, splash_radius, border_side, is_error --- packages/flet/lib/src/controls/checkbox.dart | 4 +- .../flet-core/src/flet_core/checkbox.py | 60 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index 7e342354b..7761e46de 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -119,9 +119,11 @@ class _CheckboxControlState extends State with FletStoreMixin { autofocus: autofocus, focusNode: _focusNode, value: _value, - isError: widget.control.attrBool("error", false)!, + isError: widget.control.attrBool("isError", false)!, semanticLabel: widget.control.attrString("semanticsLabel"), shape: parseOutlinedBorder(widget.control, "shape"), + side: + parseBorderSide(Theme.of(context), widget.control, "borderSide"), splashRadius: widget.control.attrDouble("splashRadius"), activeColor: HexColor.fromString( Theme.of(context), widget.control.attrString("activeColor", "")!), diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index bfe7847bf..0ea80cf0d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -2,6 +2,8 @@ from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl +from flet_core.border import BorderSide +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import OptionalNumber from flet_core.ref import Ref @@ -65,6 +67,11 @@ def __init__( active_color: Optional[str] = None, hover_color: Optional[str] = None, focus_color: Optional[str] = None, + semantics_label: Optional[str] = None, + shape: Optional[OutlinedBorder] = None, + splash_radius: OptionalNumber = None, + border_side: Optional[BorderSide] = None, + is_error: Optional[bool] = None, on_change=None, on_focus=None, on_blur=None, @@ -145,6 +152,11 @@ def __init__( self.hover_color = hover_color self.overlay_color = overlay_color self.active_color = active_color + self.semantics_label = semantics_label + self.shape = shape + self.splash_radius = splash_radius + self.border_side = border_side + self.is_error = is_error self.on_change = on_change self.on_focus = on_focus self.on_blur = on_blur @@ -156,8 +168,11 @@ def before_update(self): super().before_update() self._set_attr_json("fillColor", self.__fill_color) self._set_attr_json("overlayColor", self.__overlay_color) + self._set_attr_json("shape", self.__shape) if dataclasses.is_dataclass(self.__label_style): self._set_attr_json("labelStyle", self.__label_style) + if dataclasses.is_dataclass(self.__border_side): + self._set_attr_json("borderSide", self.__border_side) # value @property @@ -272,6 +287,51 @@ def label_style(self) -> Optional[TextStyle]: def label_style(self, value: Optional[TextStyle]): self.__label_style = value + # semantics_label + @property + def semantics_label(self) -> Optional[str]: + return self._get_attr("semanticsLabel") + + @semantics_label.setter + def semantics_label(self, value: Optional[str]): + self._set_attr("semanticsLabel", value) + + # shape + @property + def shape(self) -> Optional[OutlinedBorder]: + return self.__shape + + @shape.setter + def shape(self, value: Optional[OutlinedBorder]): + self.__shape = value + + # splash_radius + @property + def splash_radius(self) -> Optional[float]: + return self._get_attr("splashRadius", data_type="float") + + @splash_radius.setter + def splash_radius(self, value: OptionalNumber): + self._set_attr("splashRadius", value) + + # is_error + @property + def is_error(self) -> Optional[bool]: + return self._get_attr("isError", data_type="bool", def_value=False) + + @is_error.setter + def is_error(self, value: Optional[bool]): + self._set_attr("isError", value) + + # border_side + @property + def border_side(self) -> Optional[BorderSide]: + return self.__border_side + + @border_side.setter + def border_side(self, value: Optional[BorderSide]): + self.__border_side = value + # on_change @property def on_change(self): From 45eb2246e81846b31cddc5357376d6e8547467fe Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:15:46 +0100 Subject: [PATCH 006/103] DragTarget: on_move, deprecated DragTargetAcceptEvent in favour of DragTargetEvent --- .../flet/lib/src/controls/drag_target.dart | 8 ++--- .../flet-core/src/flet_core/drag_target.py | 35 ++++++++++++++++--- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/packages/flet/lib/src/controls/drag_target.dart b/packages/flet/lib/src/controls/drag_target.dart index b1125bb31..f9d23c6ba 100644 --- a/packages/flet/lib/src/controls/drag_target.dart +++ b/packages/flet/lib/src/controls/drag_target.dart @@ -7,12 +7,12 @@ import '../models/control.dart'; import 'create_control.dart'; import 'error.dart'; -class DragTargetAcceptEvent { +class DragTargetEvent { final String srcId; final double x; final double y; - DragTargetAcceptEvent({ + DragTargetEvent({ required this.srcId, required this.x, required this.y, @@ -78,7 +78,7 @@ class DragTargetControl extends StatelessWidget { backend.triggerControlEvent( control.id, "move", - json.encode(DragTargetAcceptEvent( + json.encode(DragTargetEvent( srcId: srcId, x: details.offset.dx, y: details.offset.dy) .toJson())); }, @@ -101,7 +101,7 @@ class DragTargetControl extends StatelessWidget { backend.triggerControlEvent( control.id, "accept", - json.encode(DragTargetAcceptEvent( + json.encode(DragTargetEvent( srcId: srcId, x: details.offset.dx, y: details.offset.dy) .toJson())); }, diff --git a/sdk/python/packages/flet-core/src/flet_core/drag_target.py b/sdk/python/packages/flet-core/src/flet_core/drag_target.py index 17efeac46..44b55db7b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/drag_target.py +++ b/sdk/python/packages/flet-core/src/flet_core/drag_target.py @@ -1,5 +1,6 @@ import json from typing import Any, Optional +from warnings import warn from flet_core.control import Control from flet_core.control_event import ControlEvent @@ -26,7 +27,7 @@ def drag_will_accept(e): ) e.control.update() - def drag_accept(e): + def drag_accept(e: ft.DragTargetEvent): src = page.get_control(e.src_id) e.control.content.bgcolor = src.content.bgcolor e.control.content.border = None @@ -108,6 +109,7 @@ def __init__( on_will_accept=None, on_accept=None, on_leave=None, + on_move=None, # # Control # @@ -125,12 +127,14 @@ def __init__( data=data, ) - def convert_accept_event_data(e): + def convert_event_data(e): d = json.loads(e.data) - return DragTargetAcceptEvent(**d) + return DragTargetEvent(**d) - self.__on_accept = EventHandler(convert_accept_event_data) + self.__on_accept = EventHandler(convert_event_data) + self.__on_move = EventHandler(convert_event_data) self._add_event_handler("accept", self.__on_accept.get_handler()) + self._add_event_handler("move", self.__on_move.get_handler()) self.__content: Optional[Control] = None @@ -139,6 +143,7 @@ def convert_accept_event_data(e): self.on_will_accept = on_will_accept self.on_accept = on_accept self.on_leave = on_leave + self.on_move = on_move def _get_control_name(self): return "dragtarget" @@ -195,8 +200,30 @@ def on_leave(self): def on_leave(self, handler): self._add_event_handler("leave", handler) + # on_move + @property + def on_move(self): + return self.__on_move + + @on_move.setter + def on_move(self, handler): + self.__on_move.subscribe(handler) + class DragTargetAcceptEvent(ControlEvent): + def __init__(self, src_id, x, y) -> None: + warn( + f"{self.__class__.__name__} is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use DragTargetEvent instead.", + category=DeprecationWarning, + stacklevel=2, + ) + self.src_id: float = src_id + self.x: float = x + self.y: float = y + + +class DragTargetEvent(ControlEvent): def __init__(self, src_id, x, y) -> None: self.src_id: float = src_id self.x: float = x From d635f0e9aa8159fe8f41c13cfafa8bc14ee8cd22 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:16:53 +0100 Subject: [PATCH 007/103] Draggable: on_drag_start, on_drag_end --- packages/flet/lib/src/controls/draggable.dart | 4 ++-- .../flet-core/src/flet_core/draggable.py | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/draggable.dart b/packages/flet/lib/src/controls/draggable.dart index c6fe6490b..51946134b 100644 --- a/packages/flet/lib/src/controls/draggable.dart +++ b/packages/flet/lib/src/controls/draggable.dart @@ -67,11 +67,11 @@ class DraggableControl extends StatelessWidget { ), onDragStarted: () { debugPrint("Draggable.onDragStarted ${control.id}"); - backend.triggerControlEvent(control.id, "dragStarted"); + backend.triggerControlEvent(control.id, "dragStart"); }, onDragCompleted: () { debugPrint("Draggable.onDragCompleted ${control.id}"); - backend.triggerControlEvent(control.id, "dragCompleted"); + backend.triggerControlEvent(control.id, "dragEnd"); }, child: MouseRegion( cursor: SystemMouseCursors.grab, diff --git a/sdk/python/packages/flet-core/src/flet_core/draggable.py b/sdk/python/packages/flet-core/src/flet_core/draggable.py index 3c7f70c1e..137fb2cf2 100644 --- a/sdk/python/packages/flet-core/src/flet_core/draggable.py +++ b/sdk/python/packages/flet-core/src/flet_core/draggable.py @@ -117,6 +117,8 @@ def __init__( content: Optional[Control] = None, content_when_dragging: Optional[Control] = None, content_feedback: Optional[Control] = None, + on_drag_start=None, + on_drag_end=None, # # Control # @@ -142,6 +144,8 @@ def __init__( self.content = content self.content_when_dragging = content_when_dragging self.content_feedback = content_feedback + self.on_drag_start = on_drag_start + self.on_drag_end = on_drag_end def _get_control_name(self): return "draggable" @@ -196,3 +200,21 @@ def content_feedback(self): @content_feedback.setter def content_feedback(self, value): self.__content_feedback = value + + # on_drag_start + @property + def on_drag_start(self): + return self._get_event_handler("dragStart") + + @on_drag_start.setter + def on_drag_start(self, handler): + self._add_event_handler("dragStart", handler) + + # on_drag_end + @property + def on_drag_end(self): + return self._get_event_handler("dragEnd") + + @on_drag_end.setter + def on_drag_end(self, handler): + self._add_event_handler("dragEnd", handler) From 293045e000e37d336d1c3afe59e0a3a2ec64f646 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:21:25 +0100 Subject: [PATCH 008/103] More types --- .../flet-core/src/flet_core/checkbox.py | 24 +++++------ .../flet-core/src/flet_core/circle_avatar.py | 42 +++++++++---------- .../src/flet_core/cupertino_icons.py | 4 +- .../flet_core/cupertino_segmented_button.py | 12 +++--- .../flet-core/src/flet_core/divider.py | 4 +- .../flet-core/src/flet_core/drag_target.py | 8 ++-- .../packages/flet-core/src/flet_core/icons.py | 4 +- .../flet-core/src/flet_core/search_bar.py | 12 ++++-- .../packages/flet-core/src/flet_core/text.py | 4 +- 9 files changed, 61 insertions(+), 53 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index 0ea80cf0d..52c899c9b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -196,20 +196,20 @@ def tristate(self, value: Optional[bool]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value @@ -226,38 +226,38 @@ def autofocus(self, value: Optional[bool]): # check_color @property - def check_color(self): + def check_color(self) -> Optional[str]: return self._get_attr("checkColor") @check_color.setter - def check_color(self, value): + def check_color(self, value: Optional[str]): self._set_attr("checkColor", value) # active_color @property - def active_color(self): + def active_color(self) -> Optional[str]: return self._get_attr("activeColor") @active_color.setter - def active_color(self, value): + def active_color(self, value: Optional[str]): self._set_attr("activeColor", value) # focus_color @property - def focus_color(self): + def focus_color(self) -> Optional[str]: return self._get_attr("focusColor") @focus_color.setter - def focus_color(self, value): + def focus_color(self, value: Optional[str]): self._set_attr("focusColor", value) # hover_color @property - def hover_color(self): + def hover_color(self) -> Optional[str]: return self._get_attr("hoverColor") @hover_color.setter - def hover_color(self, value): + def hover_color(self, value: Optional[str]): self._set_attr("hoverColor", value) # fill_color diff --git a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py index 9efa93e76..a4dd6d75d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py +++ b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py @@ -155,72 +155,72 @@ def _get_control_name(self): return "circleavatar" def _get_children(self): - if self.__content is None: - return [] - self.__content._set_attr_internal("n", "content") - return [self.__content] + if self.__content is not None: + self.__content._set_attr_internal("n", "content") + return [self.__content] + return [] # foreground_image_url @property - def foreground_image_url(self): + def foreground_image_url(self) -> Optional[str]: return self._get_attr("foregroundImageUrl") @foreground_image_url.setter - def foreground_image_url(self, value): + def foreground_image_url(self, value: Optional[str]): self._set_attr("foregroundImageUrl", value) # background_image_url @property - def background_image_url(self): + def background_image_url(self) -> Optional[str]: return self._get_attr("backgroundImageUrl") @background_image_url.setter - def background_image_url(self, value): + def background_image_url(self, value: Optional[str]): self._set_attr("backgroundImageUrl", value) # radius @property - def radius(self): - return self._get_attr("radius") + def radius(self) -> OptionalNumber: + return self._get_attr("radius", data_type="float") @radius.setter - def radius(self, value): + def radius(self, value: OptionalNumber): self._set_attr("radius", value) # min_radius @property - def min_radius(self): - return self._get_attr("minRadius") + def min_radius(self) -> OptionalNumber: + return self._get_attr("minRadius", data_type="float") @min_radius.setter - def min_radius(self, value): + def min_radius(self, value: OptionalNumber): self._set_attr("minRadius", value) # max_radius @property - def max_radius(self): - return self._get_attr("maxRadius") + def max_radius(self) -> OptionalNumber: + return self._get_attr("maxRadius", data_type="float") @max_radius.setter - def max_radius(self, value): + def max_radius(self, value: OptionalNumber): self._set_attr("maxRadius", value) # color @property - def color(self): + def color(self) -> Optional[str]: return self._get_attr("color") @color.setter - def color(self, value): + def color(self, value: Optional[str]): self._set_attr("color", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) # content diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_icons.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_icons.py index 7a1db46ba..f9c764e45 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_icons.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_icons.py @@ -1,5 +1,7 @@ """ -To generate update the list run: +Flet Cupertino Icons + +To generate/update these values run: sh ci/generate_cupertino_icons_python.sh """ diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py index 5d2419087..e579a4e64 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py @@ -121,11 +121,11 @@ def controls(self, value: List[Control]): # border_color @property - def border_color(self): + def border_color(self) -> Optional[str]: return self._get_attr("borderColor") @border_color.setter - def border_color(self, value): + def border_color(self, value: Optional[str]): self._set_attr("borderColor", value) # selected_index @@ -135,17 +135,17 @@ def selected_index(self) -> Optional[int]: @selected_index.setter def selected_index(self, value: Optional[int]): - if value is not None: - assert 0 <= value <= len(self.controls) - 1, "selected_index out of range" + if value is not None and (0 <= value <= len(self.controls) - 1): + raise IndexError("selected_index out of range") self._set_attr("selectedIndex", value) # selected_color @property - def selected_color(self): + def selected_color(self) -> Optional[str]: return self._get_attr("selectedColor") @selected_color.setter - def selected_color(self, value): + def selected_color(self, value: Optional[str]): self._set_attr("selectedColor", value) # unselected_color diff --git a/sdk/python/packages/flet-core/src/flet_core/divider.py b/sdk/python/packages/flet-core/src/flet_core/divider.py index 947916e3d..76036df1c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/divider.py +++ b/sdk/python/packages/flet-core/src/flet_core/divider.py @@ -94,9 +94,9 @@ def thickness(self, value: OptionalNumber): # color @property - def color(self): + def color(self) -> Optional[str]: return self._get_attr("color") @color.setter - def color(self, value): + def color(self, value: Optional[str]): self._set_attr("color", value) diff --git a/sdk/python/packages/flet-core/src/flet_core/drag_target.py b/sdk/python/packages/flet-core/src/flet_core/drag_target.py index 44b55db7b..7ecbd3e30 100644 --- a/sdk/python/packages/flet-core/src/flet_core/drag_target.py +++ b/sdk/python/packages/flet-core/src/flet_core/drag_target.py @@ -157,20 +157,20 @@ def _get_children(self): # group @property - def group(self): + def group(self) -> Optional[str]: return self._get_attr("group") @group.setter - def group(self, value): + def group(self, value: Optional[str]): self._set_attr("group", value) # content @property - def content(self): + def content(self) -> Optional[Control]: return self.__content @content.setter - def content(self, value): + def content(self, value: Optional[Control]): self.__content = value # on_will_accept diff --git a/sdk/python/packages/flet-core/src/flet_core/icons.py b/sdk/python/packages/flet-core/src/flet_core/icons.py index a9e58aabe..4f4ebffd7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/icons.py +++ b/sdk/python/packages/flet-core/src/flet_core/icons.py @@ -1,5 +1,7 @@ """ -To generate update the list run: +Flet Material Icons + +To generate/update these values run: sh ci/generate_material_icons_python.sh """ diff --git a/sdk/python/packages/flet-core/src/flet_core/search_bar.py b/sdk/python/packages/flet-core/src/flet_core/search_bar.py index 5cbe3cf73..ba1dce5c0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/search_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/search_bar.py @@ -1,7 +1,8 @@ import time from typing import Any, Dict, List, Optional, Union -from flet_core import BorderSide, OutlinedBorder +from flet_core.border import BorderSide +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref @@ -136,9 +137,12 @@ def before_update(self): self._set_attr_json("barBgcolor", self.__bar_bgcolor) self._set_attr_json("barOverlayColor", self.__bar_overlay_color) self._set_attr_json("viewShape", self.__view_shape) - self._set_attr_json("viewHeaderTextStyle", self.__view_header_text_style) - self._set_attr_json("viewHintTextStyle", self.__view_hint_text_style) - self._set_attr_json("viewSide", self.__view_side) + if isinstance(self.__view_header_text_style, TextStyle): + self._set_attr_json("viewHeaderTextStyle", self.__view_header_text_style) + if isinstance(self.__view_hint_text_style, TextStyle): + self._set_attr_json("viewHintTextStyle", self.__view_hint_text_style) + if isinstance(self.__view_side, BorderSide): + self._set_attr_json("viewSide", self.__view_side) def _get_children(self): children = [] diff --git a/sdk/python/packages/flet-core/src/flet_core/text.py b/sdk/python/packages/flet-core/src/flet_core/text.py index 2e14ae74a..3b78f6b0d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/text.py +++ b/sdk/python/packages/flet-core/src/flet_core/text.py @@ -352,9 +352,9 @@ def bgcolor(self, value): # semantics_label @property - def semantics_label(self): + def semantics_label(self) -> Optional[str]: return self._get_attr("semanticsLabel") @semantics_label.setter - def semantics_label(self, value): + def semantics_label(self, value: Optional[str]): self._set_attr("semanticsLabel", value) From 0ea62fbd0ca196a2c9b423424da6340138e95862 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:21:50 +0100 Subject: [PATCH 009/103] Divider: indent, end_indent --- .../flet-core/src/flet_core/divider.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sdk/python/packages/flet-core/src/flet_core/divider.py b/sdk/python/packages/flet-core/src/flet_core/divider.py index 76036df1c..49bba205f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/divider.py +++ b/sdk/python/packages/flet-core/src/flet_core/divider.py @@ -50,6 +50,8 @@ def __init__( height: OptionalNumber = None, thickness: OptionalNumber = None, color: Optional[str] = None, + indent: OptionalNumber = None, + end_indent: OptionalNumber = None, # # Control # @@ -70,6 +72,8 @@ def __init__( self.height = height self.thickness = thickness self.color = color + self.indent = indent + self.end_indent = end_indent def _get_control_name(self): return "divider" @@ -100,3 +104,21 @@ def color(self) -> Optional[str]: @color.setter def color(self, value: Optional[str]): self._set_attr("color", value) + + # indent + @property + def indent(self) -> OptionalNumber: + return self._get_attr("indent") + + @indent.setter + def indent(self, value: OptionalNumber): + self._set_attr("indent", value) + + # end_indent + @property + def end_indent(self) -> OptionalNumber: + return self._get_attr("endIndent") + + @end_indent.setter + def end_indent(self, value: OptionalNumber): + self._set_attr("endIndent", value) From ad1c65bbfb1133f0c1642f849f1d97e38fcaafe8 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 9 Mar 2024 16:31:01 +0100 Subject: [PATCH 010/103] Fix #2839 --- packages/flet/lib/src/controls/expansion_tile.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/expansion_tile.dart b/packages/flet/lib/src/controls/expansion_tile.dart index 6bdbc7ace..2e236122b 100644 --- a/packages/flet/lib/src/controls/expansion_tile.dart +++ b/packages/flet/lib/src/controls/expansion_tile.dart @@ -47,7 +47,7 @@ class ExpansionTileControl extends StatelessWidget { bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; bool onchange = control.attrBool("onchange", false)!; bool maintainState = control.attrBool("maintainState", false)!; - bool initiallyExpanded = control.attrBool("maintainState", false)!; + bool initiallyExpanded = control.attrBool("initiallyExpanded", false)!; var iconColor = HexColor.fromString( Theme.of(context), control.attrString("iconColor", "")!); From 334da3ef0b004e1f38e81de444c3998ee600117e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sun, 10 Mar 2024 03:19:45 +0100 Subject: [PATCH 011/103] Stack: alignment, fit --- packages/flet/lib/src/controls/stack.dart | 25 ++++++++++----- .../flet-core/src/flet_core/__init__.py | 2 +- .../packages/flet-core/src/flet_core/stack.py | 31 +++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/packages/flet/lib/src/controls/stack.dart b/packages/flet/lib/src/controls/stack.dart index 0b0d22d22..8b0d0c0a2 100644 --- a/packages/flet/lib/src/controls/stack.dart +++ b/packages/flet/lib/src/controls/stack.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import '../models/control.dart'; +import '../utils/alignment.dart'; import 'create_control.dart'; class StackControl extends StatelessWidget { @@ -21,6 +22,8 @@ class StackControl extends StatelessWidget { @override Widget build(BuildContext context) { debugPrint("Stack build: ${control.id}"); + bool disabled = control.isDisabled || parentDisabled; + bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; var clipBehavior = Clip.values.firstWhere( (e) => @@ -28,17 +31,25 @@ class StackControl extends StatelessWidget { control.attrString("clipBehavior", "")!.toLowerCase(), orElse: () => Clip.hardEdge); - bool disabled = control.isDisabled || parentDisabled; - bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; + StackFit fit = StackFit.values.firstWhere( + (e) => + e.name.toLowerCase() == + control.attrString("fit", "")!.toLowerCase(), + orElse: () => StackFit.loose); + var ctrls = children + .where((c) => c.isVisible) + .map((c) => + createControl(control, c.id, disabled, parentAdaptive: adaptive)) + .toList(); + return constrainedControl( context, Stack( clipBehavior: clipBehavior, - children: children - .where((c) => c.isVisible) - .map((c) => createControl(control, c.id, disabled, - parentAdaptive: adaptive)) - .toList(), + fit: fit, + alignment: parseAlignment(control, "alignment") ?? + AlignmentDirectional.topStart, + children: ctrls, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index a62c46b91..47670fc77 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -222,7 +222,7 @@ from flet_core.shake_detector import ShakeDetector from flet_core.slider import Slider from flet_core.snack_bar import DismissDirection, SnackBar, SnackBarBehavior -from flet_core.stack import Stack +from flet_core.stack import Stack, StackFit from flet_core.submenu_button import SubmenuButton from flet_core.switch import Switch from flet_core.tabs import Tab, Tabs diff --git a/sdk/python/packages/flet-core/src/flet_core/stack.py b/sdk/python/packages/flet-core/src/flet_core/stack.py index 4946ec562..3d9fb4b71 100644 --- a/sdk/python/packages/flet-core/src/flet_core/stack.py +++ b/sdk/python/packages/flet-core/src/flet_core/stack.py @@ -1,6 +1,8 @@ +from enum import Enum from typing import Any, List, Optional, Union from flet_core.adaptive_control import AdaptiveControl +from flet_core.alignment import Alignment from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref @@ -14,6 +16,12 @@ ) +class StackFit(Enum): + LOOSE = "loose" + EXPAND = "expand" + PASS_THROUGH = "passThrough" + + class Stack(ConstrainedControl, AdaptiveControl): """ A control that positions its children on top of each other. @@ -67,6 +75,8 @@ def __init__( self, controls: Optional[List[Control]] = None, clip_behavior: Optional[ClipBehavior] = None, + alignment: Optional[Alignment] = None, + fit: Optional[StackFit] = None, # # ConstrainedControl and AdaptiveControl # @@ -133,6 +143,8 @@ def __init__( self.__controls: List[Control] = [] self.controls = controls self.clip_behavior = clip_behavior + self.alignment = alignment + self.fit = fit def _get_control_name(self): return "stack" @@ -160,3 +172,22 @@ def clip_behavior(self, value: Optional[ClipBehavior]): self._set_attr( "clipBehavior", value.value if isinstance(value, ClipBehavior) else value ) + + # alignment + @property + def alignment(self) -> Optional[Alignment]: + return self.__alignment + + @alignment.setter + def alignment(self, value: Optional[Alignment]): + self.__alignment = value + + # fit + @property + def fit(self) -> Optional[StackFit]: + return self.__fit + + @fit.setter + def fit(self, value: Optional[StackFit]): + self.__fit = value + self._set_attr("fit", value.value if isinstance(value, StackFit) else value) From 184fb04c390c9fe67d5c5159a4dc08719b1735da Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 01:30:51 +0100 Subject: [PATCH 012/103] Divider: rename indent to leading_indent and end_indent to trailing_indent --- packages/flet/lib/src/controls/divider.dart | 8 ++--- .../flet-core/src/flet_core/divider.py | 30 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/flet/lib/src/controls/divider.dart b/packages/flet/lib/src/controls/divider.dart index 6079c2159..e0021da58 100644 --- a/packages/flet/lib/src/controls/divider.dart +++ b/packages/flet/lib/src/controls/divider.dart @@ -15,8 +15,8 @@ class DividerControl extends StatelessWidget { debugPrint("Divider build: ${control.id}"); var height = control.attrDouble("height"); - var indent = control.attrDouble("indent"); - var endIndent = control.attrDouble("endIndent"); + var leadingIndent = control.attrDouble("leadingIndent"); + var trailingIndent = control.attrDouble("trailingIndent"); var thickness = control.attrDouble("thickness"); var color = HexColor.fromString( Theme.of(context), control.attrString("color", "")!); @@ -27,8 +27,8 @@ class DividerControl extends StatelessWidget { height: height, thickness: thickness, color: color, - indent: indent, - endIndent: endIndent, + indent: leadingIndent, + endIndent: trailingIndent, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/divider.py b/sdk/python/packages/flet-core/src/flet_core/divider.py index 49bba205f..43a5cb1b6 100644 --- a/sdk/python/packages/flet-core/src/flet_core/divider.py +++ b/sdk/python/packages/flet-core/src/flet_core/divider.py @@ -50,8 +50,8 @@ def __init__( height: OptionalNumber = None, thickness: OptionalNumber = None, color: Optional[str] = None, - indent: OptionalNumber = None, - end_indent: OptionalNumber = None, + leading_indent: OptionalNumber = None, + trailing_indent: OptionalNumber = None, # # Control # @@ -72,8 +72,8 @@ def __init__( self.height = height self.thickness = thickness self.color = color - self.indent = indent - self.end_indent = end_indent + self.leading_indent = leading_indent + self.trailing_indent = trailing_indent def _get_control_name(self): return "divider" @@ -107,18 +107,18 @@ def color(self, value: Optional[str]): # indent @property - def indent(self) -> OptionalNumber: - return self._get_attr("indent") + def leading_indent(self) -> OptionalNumber: + return self._get_attr("leadingIndent") - @indent.setter - def indent(self, value: OptionalNumber): - self._set_attr("indent", value) + @leading_indent.setter + def leading_indent(self, value: OptionalNumber): + self._set_attr("leadingIndent", value) - # end_indent + # trailing_indent @property - def end_indent(self) -> OptionalNumber: - return self._get_attr("endIndent") + def trailing_indent(self) -> OptionalNumber: + return self._get_attr("trailingIndent") - @end_indent.setter - def end_indent(self, value: OptionalNumber): - self._set_attr("endIndent", value) + @trailing_indent.setter + def trailing_indent(self, value: OptionalNumber): + self._set_attr("trailingIndent", value) From 7ad5296ecf3faf1cc3c06b8b71690fa82fc1a3fb Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 01:46:19 +0100 Subject: [PATCH 013/103] Draggable: rename on_drag_end to on_drag_complete --- packages/flet/lib/src/controls/draggable.dart | 2 +- .../flet-core/src/flet_core/draggable.py | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/flet/lib/src/controls/draggable.dart b/packages/flet/lib/src/controls/draggable.dart index 51946134b..5fa926241 100644 --- a/packages/flet/lib/src/controls/draggable.dart +++ b/packages/flet/lib/src/controls/draggable.dart @@ -71,7 +71,7 @@ class DraggableControl extends StatelessWidget { }, onDragCompleted: () { debugPrint("Draggable.onDragCompleted ${control.id}"); - backend.triggerControlEvent(control.id, "dragEnd"); + backend.triggerControlEvent(control.id, "dragComplete"); }, child: MouseRegion( cursor: SystemMouseCursors.grab, diff --git a/sdk/python/packages/flet-core/src/flet_core/draggable.py b/sdk/python/packages/flet-core/src/flet_core/draggable.py index 137fb2cf2..de13edb3b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/draggable.py +++ b/sdk/python/packages/flet-core/src/flet_core/draggable.py @@ -118,7 +118,7 @@ def __init__( content_when_dragging: Optional[Control] = None, content_feedback: Optional[Control] = None, on_drag_start=None, - on_drag_end=None, + on_drag_complete=None, # # Control # @@ -145,7 +145,7 @@ def __init__( self.content_when_dragging = content_when_dragging self.content_feedback = content_feedback self.on_drag_start = on_drag_start - self.on_drag_end = on_drag_end + self.on_drag_complete = on_drag_complete def _get_control_name(self): return "draggable" @@ -210,11 +210,11 @@ def on_drag_start(self): def on_drag_start(self, handler): self._add_event_handler("dragStart", handler) - # on_drag_end + # on_drag_complete @property - def on_drag_end(self): - return self._get_event_handler("dragEnd") + def on_drag_complete(self): + return self._get_event_handler("dragComplete") - @on_drag_end.setter - def on_drag_end(self, handler): - self._add_event_handler("dragEnd", handler) + @on_drag_complete.setter + def on_drag_complete(self, handler): + self._add_event_handler("dragComplete", handler) From b92ce300a156ae0d47b8031abc1e8e66b6564d48 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 01:51:56 +0100 Subject: [PATCH 014/103] Checkbox: rename border_side to border --- packages/flet/lib/src/controls/checkbox.dart | 3 +-- .../flet-core/src/flet_core/checkbox.py | 23 +++++++++---------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index 7761e46de..f223c1b8f 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -122,8 +122,7 @@ class _CheckboxControlState extends State with FletStoreMixin { isError: widget.control.attrBool("isError", false)!, semanticLabel: widget.control.attrString("semanticsLabel"), shape: parseOutlinedBorder(widget.control, "shape"), - side: - parseBorderSide(Theme.of(context), widget.control, "borderSide"), + side: parseBorderSide(Theme.of(context), widget.control, "border"), splashRadius: widget.control.attrDouble("splashRadius"), activeColor: HexColor.fromString( Theme.of(context), widget.control.attrString("activeColor", "")!), diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index 52c899c9b..3d131d442 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -1,4 +1,3 @@ -import dataclasses from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -70,7 +69,7 @@ def __init__( semantics_label: Optional[str] = None, shape: Optional[OutlinedBorder] = None, splash_radius: OptionalNumber = None, - border_side: Optional[BorderSide] = None, + border: Optional[BorderSide] = None, is_error: Optional[bool] = None, on_change=None, on_focus=None, @@ -155,7 +154,7 @@ def __init__( self.semantics_label = semantics_label self.shape = shape self.splash_radius = splash_radius - self.border_side = border_side + self.border = border self.is_error = is_error self.on_change = on_change self.on_focus = on_focus @@ -169,10 +168,10 @@ def before_update(self): self._set_attr_json("fillColor", self.__fill_color) self._set_attr_json("overlayColor", self.__overlay_color) self._set_attr_json("shape", self.__shape) - if dataclasses.is_dataclass(self.__label_style): + if isinstance(self.__label_style, TextStyle): self._set_attr_json("labelStyle", self.__label_style) - if dataclasses.is_dataclass(self.__border_side): - self._set_attr_json("borderSide", self.__border_side) + if isinstance(self.__border, BorderSide): + self._set_attr_json("borderSide", self.__border) # value @property @@ -323,14 +322,14 @@ def is_error(self) -> Optional[bool]: def is_error(self, value: Optional[bool]): self._set_attr("isError", value) - # border_side + # border @property - def border_side(self) -> Optional[BorderSide]: - return self.__border_side + def border(self) -> Optional[BorderSide]: + return self.__border - @border_side.setter - def border_side(self, value: Optional[BorderSide]): - self.__border_side = value + @border.setter + def border(self, value: Optional[BorderSide]): + self.__border = value # on_change @property From b34b589d99450595876d2a14fad092a5a9ab83bb Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 01:59:28 +0100 Subject: [PATCH 015/103] Revert "Checkbox: rename border_side to border" This reverts commit b92ce300a156ae0d47b8031abc1e8e66b6564d48. --- packages/flet/lib/src/controls/checkbox.dart | 3 ++- .../flet-core/src/flet_core/checkbox.py | 23 ++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index f223c1b8f..7761e46de 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -122,7 +122,8 @@ class _CheckboxControlState extends State with FletStoreMixin { isError: widget.control.attrBool("isError", false)!, semanticLabel: widget.control.attrString("semanticsLabel"), shape: parseOutlinedBorder(widget.control, "shape"), - side: parseBorderSide(Theme.of(context), widget.control, "border"), + side: + parseBorderSide(Theme.of(context), widget.control, "borderSide"), splashRadius: widget.control.attrDouble("splashRadius"), activeColor: HexColor.fromString( Theme.of(context), widget.control.attrString("activeColor", "")!), diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index 3d131d442..52c899c9b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -1,3 +1,4 @@ +import dataclasses from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -69,7 +70,7 @@ def __init__( semantics_label: Optional[str] = None, shape: Optional[OutlinedBorder] = None, splash_radius: OptionalNumber = None, - border: Optional[BorderSide] = None, + border_side: Optional[BorderSide] = None, is_error: Optional[bool] = None, on_change=None, on_focus=None, @@ -154,7 +155,7 @@ def __init__( self.semantics_label = semantics_label self.shape = shape self.splash_radius = splash_radius - self.border = border + self.border_side = border_side self.is_error = is_error self.on_change = on_change self.on_focus = on_focus @@ -168,10 +169,10 @@ def before_update(self): self._set_attr_json("fillColor", self.__fill_color) self._set_attr_json("overlayColor", self.__overlay_color) self._set_attr_json("shape", self.__shape) - if isinstance(self.__label_style, TextStyle): + if dataclasses.is_dataclass(self.__label_style): self._set_attr_json("labelStyle", self.__label_style) - if isinstance(self.__border, BorderSide): - self._set_attr_json("borderSide", self.__border) + if dataclasses.is_dataclass(self.__border_side): + self._set_attr_json("borderSide", self.__border_side) # value @property @@ -322,14 +323,14 @@ def is_error(self) -> Optional[bool]: def is_error(self, value: Optional[bool]): self._set_attr("isError", value) - # border + # border_side @property - def border(self) -> Optional[BorderSide]: - return self.__border + def border_side(self) -> Optional[BorderSide]: + return self.__border_side - @border.setter - def border(self, value: Optional[BorderSide]): - self.__border = value + @border_side.setter + def border_side(self, value: Optional[BorderSide]): + self.__border_side = value # on_change @property From 56f9d29b0506f590c306d7b1fabcdfe2e7e28ee6 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 02:17:55 +0100 Subject: [PATCH 016/103] Card: variant --- packages/flet/lib/src/controls/card.dart | 93 ++++++++++++++----- .../flet-core/src/flet_core/__init__.py | 2 +- .../packages/flet-core/src/flet_core/card.py | 21 +++++ 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/packages/flet/lib/src/controls/card.dart b/packages/flet/lib/src/controls/card.dart index a0adcf0b8..5cabf1b12 100644 --- a/packages/flet/lib/src/controls/card.dart +++ b/packages/flet/lib/src/controls/card.dart @@ -7,6 +7,8 @@ import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; +enum CardVariant { normal, filled, outlined } + class CardControl extends StatelessWidget { final Control? parent; final Control control; @@ -25,6 +27,8 @@ class CardControl extends StatelessWidget { @override Widget build(BuildContext context) { debugPrint("Card build: ${control.id}"); + bool disabled = control.isDisabled || parentDisabled; + bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); @@ -33,30 +37,71 @@ class CardControl extends StatelessWidget { e.name.toLowerCase() == control.attrString("clipBehavior", "")!.toLowerCase(), ); - bool disabled = control.isDisabled || parentDisabled; - bool? adaptive = control.attrBool("adaptive") ?? parentAdaptive; - return constrainedControl( - context, - Card( - elevation: control.attrDouble("elevation"), - shape: parseOutlinedBorder(control, "shape"), - margin: parseEdgeInsets(control, "margin"), - semanticContainer: control.attrBool("isSemanticContainer", true)!, - borderOnForeground: - control.attrBool("showBorderOnForeground", true)!, - clipBehavior: clipBehavior, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString( - Theme.of(context), control.attrString("surfaceTintColor", "")!), - child: contentCtrls.isNotEmpty - ? createControl(control, contentCtrls.first.id, disabled, - parentAdaptive: adaptive) - : null), - parent, - control); + Widget? card; + + CardVariant variant = CardVariant.values.firstWhere( + (v) => + v.name.toLowerCase() == + control.attrString("variant", "")!.toLowerCase(), + orElse: () => CardVariant.normal); + + if (variant == CardVariant.outlined) { + card = Card.outlined( + elevation: control.attrDouble("elevation"), + shape: parseOutlinedBorder(control, "shape"), + margin: parseEdgeInsets(control, "margin"), + semanticContainer: control.attrBool("isSemanticContainer", true)!, + borderOnForeground: control.attrBool("showBorderOnForeground", true)!, + clipBehavior: clipBehavior, + color: HexColor.fromString( + Theme.of(context), control.attrString("color", "")!), + shadowColor: HexColor.fromString( + Theme.of(context), control.attrString("shadowColor", "")!), + surfaceTintColor: HexColor.fromString( + Theme.of(context), control.attrString("surfaceTintColor", "")!), + child: contentCtrls.isNotEmpty + ? createControl(control, contentCtrls.first.id, disabled, + parentAdaptive: adaptive) + : null); + } else if (variant == CardVariant.filled) { + card = Card.filled( + elevation: control.attrDouble("elevation"), + shape: parseOutlinedBorder(control, "shape"), + margin: parseEdgeInsets(control, "margin"), + semanticContainer: control.attrBool("isSemanticContainer", true)!, + borderOnForeground: control.attrBool("showBorderOnForeground", true)!, + clipBehavior: clipBehavior, + color: HexColor.fromString( + Theme.of(context), control.attrString("color", "")!), + shadowColor: HexColor.fromString( + Theme.of(context), control.attrString("shadowColor", "")!), + surfaceTintColor: HexColor.fromString( + Theme.of(context), control.attrString("surfaceTintColor", "")!), + child: contentCtrls.isNotEmpty + ? createControl(control, contentCtrls.first.id, disabled, + parentAdaptive: adaptive) + : null); + } else { + card = Card( + elevation: control.attrDouble("elevation"), + shape: parseOutlinedBorder(control, "shape"), + margin: parseEdgeInsets(control, "margin"), + semanticContainer: control.attrBool("isSemanticContainer", true)!, + borderOnForeground: control.attrBool("showBorderOnForeground", true)!, + clipBehavior: clipBehavior, + color: HexColor.fromString( + Theme.of(context), control.attrString("color", "")!), + shadowColor: HexColor.fromString( + Theme.of(context), control.attrString("shadowColor", "")!), + surfaceTintColor: HexColor.fromString( + Theme.of(context), control.attrString("surfaceTintColor", "")!), + child: contentCtrls.isNotEmpty + ? createControl(control, contentCtrls.first.id, disabled, + parentAdaptive: adaptive) + : null); + } + + return constrainedControl(context, card, parent, control); } } diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index 47670fc77..8e7a74542 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -39,7 +39,7 @@ RoundedRectangleBorder, StadiumBorder, ) -from flet_core.card import Card +from flet_core.card import Card, CardVariant from flet_core.charts.bar_chart import BarChart, BarChartEvent from flet_core.charts.bar_chart_group import BarChartGroup from flet_core.charts.bar_chart_rod import BarChartRod diff --git a/sdk/python/packages/flet-core/src/flet_core/card.py b/sdk/python/packages/flet-core/src/flet_core/card.py index e354f9da3..593772555 100644 --- a/sdk/python/packages/flet-core/src/flet_core/card.py +++ b/sdk/python/packages/flet-core/src/flet_core/card.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from flet_core import OutlinedBorder @@ -16,6 +17,12 @@ ) +class CardVariant(Enum): + NORMAL = "normal" + FILLED = "filled" + OUTLINED = "outlined" + + class Card(ConstrainedControl, AdaptiveControl): """ A material design card: a panel with slightly rounded corners and an elevation shadow. @@ -71,6 +78,7 @@ def __init__( clip_behavior: Optional[ClipBehavior] = None, is_semantic_container: Optional[bool] = None, show_border_on_foreground: Optional[bool] = None, + variant: Optional[CardVariant] = None, # # ConstrainedControl and AdaptiveControl # @@ -146,6 +154,7 @@ def __init__( self.clip_behavior = clip_behavior self.is_semantic_container = is_semantic_container self.show_border_on_foreground = show_border_on_foreground + self.variant = variant def _get_control_name(self): return "card" @@ -257,3 +266,15 @@ def show_border_on_foreground(self) -> Optional[bool]: @show_border_on_foreground.setter def show_border_on_foreground(self, value): self._set_attr("showBorderOnForeground", value) + + # variant + @property + def variant(self) -> Optional[CardVariant]: + return self.__variant + + @variant.setter + def variant(self, value: Optional[CardVariant]): + self.__variant = value + self._set_attr( + "variant", value.value if isinstance(value, CardVariant) else value + ) From d762c7c31bde86cfd936c45682ffb6f55e01abeb Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 02:35:33 +0100 Subject: [PATCH 017/103] VerticalDivider: leading_indent, trailing_indent --- .../lib/src/controls/vertical_divider.dart | 4 ++++ .../flet-core/src/flet_core/divider.py | 2 +- .../src/flet_core/vertical_divider.py | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/vertical_divider.dart b/packages/flet/lib/src/controls/vertical_divider.dart index 1f3669861..15351b604 100644 --- a/packages/flet/lib/src/controls/vertical_divider.dart +++ b/packages/flet/lib/src/controls/vertical_divider.dart @@ -17,6 +17,8 @@ class VerticalDividerControl extends StatelessWidget { var width = control.attrDouble("width"); var thickness = control.attrDouble("thickness"); + var leadingIndent = control.attrDouble("leadingIndent"); + var trailingIndent = control.attrDouble("trailingIndent"); var color = HexColor.fromString( Theme.of(context), control.attrString("color", "")!); @@ -26,6 +28,8 @@ class VerticalDividerControl extends StatelessWidget { width: width, thickness: thickness, color: color, + indent: leadingIndent, + endIndent: trailingIndent, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/divider.py b/sdk/python/packages/flet-core/src/flet_core/divider.py index 43a5cb1b6..039570292 100644 --- a/sdk/python/packages/flet-core/src/flet_core/divider.py +++ b/sdk/python/packages/flet-core/src/flet_core/divider.py @@ -105,7 +105,7 @@ def color(self) -> Optional[str]: def color(self, value: Optional[str]): self._set_attr("color", value) - # indent + # leading_indent @property def leading_indent(self) -> OptionalNumber: return self._get_attr("leadingIndent") diff --git a/sdk/python/packages/flet-core/src/flet_core/vertical_divider.py b/sdk/python/packages/flet-core/src/flet_core/vertical_divider.py index 3466ae568..285c47b0a 100644 --- a/sdk/python/packages/flet-core/src/flet_core/vertical_divider.py +++ b/sdk/python/packages/flet-core/src/flet_core/vertical_divider.py @@ -50,6 +50,8 @@ def __init__( width: OptionalNumber = None, thickness: OptionalNumber = None, color: Optional[str] = None, + leading_indent: OptionalNumber = None, + trailing_indent: OptionalNumber = None, # # Control # @@ -70,6 +72,8 @@ def __init__( self.width = width self.thickness = thickness self.color = color + self.leading_indent = leading_indent + self.trailing_indent = trailing_indent def _get_control_name(self): return "verticaldivider" @@ -100,3 +104,21 @@ def color(self): @color.setter def color(self, value): self._set_attr("color", value) + + # leading_indent + @property + def leading_indent(self) -> OptionalNumber: + return self._get_attr("leadingIndent") + + @leading_indent.setter + def leading_indent(self, value: OptionalNumber): + self._set_attr("leadingIndent", value) + + # trailing_indent + @property + def trailing_indent(self) -> OptionalNumber: + return self._get_attr("trailingIndent") + + @trailing_indent.setter + def trailing_indent(self, value: OptionalNumber): + self._set_attr("trailingIndent", value) From a626e21dd6914cbb589c3566ee945544d564a8f9 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 02:47:21 +0100 Subject: [PATCH 018/103] Tooltip: exclude_from_semantics, enable_tap_to_dismiss --- packages/flet/lib/src/controls/tooltip.dart | 2 ++ .../flet-core/src/flet_core/tooltip.py | 26 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/tooltip.dart b/packages/flet/lib/src/controls/tooltip.dart index 0f5ef8ede..f0c2d23d1 100644 --- a/packages/flet/lib/src/controls/tooltip.dart +++ b/packages/flet/lib/src/controls/tooltip.dart @@ -67,6 +67,8 @@ class TooltipControl extends StatelessWidget { Tooltip( decoration: decoration, enableFeedback: control.attrBool("enableFeedback"), + enableTapToDismiss: control.attrBool("enableTapToDismiss", true)!, + excludeFromSemantics: control.attrBool("excludeFromSemantics"), height: control.attrDouble("height"), margin: parseEdgeInsets(control, "margin"), padding: parseEdgeInsets(control, "padding"), diff --git a/sdk/python/packages/flet-core/src/flet_core/tooltip.py b/sdk/python/packages/flet-core/src/flet_core/tooltip.py index 53ced42a4..1797127a9 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tooltip.py +++ b/sdk/python/packages/flet-core/src/flet_core/tooltip.py @@ -81,6 +81,8 @@ def __init__( prefer_below: Optional[bool] = None, show_duration: Optional[int] = None, wait_duration: Optional[int] = None, + enable_tap_to_dismiss: Optional[bool] = None, + exclude_from_semantics: Optional[bool] = None, # # Control # @@ -114,6 +116,8 @@ def __init__( self.prefer_below = prefer_below self.show_duration = show_duration self.wait_duration = wait_duration + self.enable_tap_to_dismiss = enable_tap_to_dismiss + self.exclude_from_semantics = exclude_from_semantics def _get_control_name(self): return "tooltip" @@ -137,12 +141,32 @@ def _get_children(self): # enable_feedback @property def enable_feedback(self) -> Optional[bool]: - return self._get_attr("enableFeedback", data_type="bool", def_value=False) + return self._get_attr("enableFeedback", data_type="bool", def_value=True) @enable_feedback.setter def enable_feedback(self, value: Optional[bool]): self._set_attr("enableFeedback", value) + # enable_tap_to_dismiss + @property + def enable_tap_to_dismiss(self) -> Optional[bool]: + return self._get_attr("enableTapToDismiss", data_type="bool", def_value=True) + + @enable_tap_to_dismiss.setter + def enable_tap_to_dismiss(self, value: Optional[bool]): + self._set_attr("enableTapToDismiss", value) + + # exclude_from_semantics + @property + def exclude_from_semantics(self) -> Optional[bool]: + return self._get_attr( + "excludeFromSemantics", data_type="bool", def_value=False + ) + + @exclude_from_semantics.setter + def exclude_from_semantics(self, value: Optional[bool]): + self._set_attr("excludeFromSemantics", value) + # margin @property def margin(self) -> MarginValue: From b7a91d75a3cc64047126d72abb5aa099c40ab8f5 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 02:58:27 +0100 Subject: [PATCH 019/103] Reformat _set_attr calls --- .../packages/flet-core/src/flet_core/canvas/points.py | 4 +++- .../packages/flet-core/src/flet_core/canvas/text.py | 4 +++- .../packages/flet-core/src/flet_core/container.py | 7 ++++--- .../flet-core/src/flet_core/cupertino_timer_picker.py | 5 ++++- .../flet-core/src/flet_core/gesture_detector.py | 4 +++- sdk/python/packages/flet-core/src/flet_core/tabs.py | 4 +++- sdk/python/packages/flet-core/src/flet_core/tooltip.py | 10 ++++------ 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/canvas/points.py b/sdk/python/packages/flet-core/src/flet_core/canvas/points.py index 56a1591f8..2cb5cf030 100644 --- a/sdk/python/packages/flet-core/src/flet_core/canvas/points.py +++ b/sdk/python/packages/flet-core/src/flet_core/canvas/points.py @@ -48,7 +48,9 @@ def point_mode(self) -> Optional[PointMode]: @point_mode.setter def point_mode(self, value: Optional[PointMode]): self.__point_mode = value - self._set_attr("pointMode", value.value if value is not None else None) + self._set_attr( + "pointMode", value.value if isinstance(value, PointMode) else value + ) # points @property diff --git a/sdk/python/packages/flet-core/src/flet_core/canvas/text.py b/sdk/python/packages/flet-core/src/flet_core/canvas/text.py index c92b76d65..1ed06b6d1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/canvas/text.py +++ b/sdk/python/packages/flet-core/src/flet_core/canvas/text.py @@ -119,7 +119,9 @@ def text_align(self) -> Optional[TextAlign]: @text_align.setter def text_align(self, value: Optional[TextAlign]): self.__text_align = value - self._set_attr("textAlign", value.value if value is not None else None) + self._set_attr( + "textAlign", value.value if isinstance(value, TextAlign) else value + ) # max_lines @property diff --git a/sdk/python/packages/flet-core/src/flet_core/container.py b/sdk/python/packages/flet-core/src/flet_core/container.py index 90cf7999d..16e885b4f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/container.py +++ b/sdk/python/packages/flet-core/src/flet_core/container.py @@ -390,7 +390,7 @@ def shape(self): @shape.setter def shape(self, value: Optional[BoxShape]): self.__shape = value - self._set_attr("shape", value.value if value is not None else None) + self._set_attr("shape", value.value if isinstance(value, BoxShape) else value) # clip_behavior @property @@ -466,7 +466,9 @@ def theme_mode(self) -> Optional[ThemeMode]: @theme_mode.setter def theme_mode(self, value: Optional[ThemeMode]): self.__theme_mode = value - self._set_attr("themeMode", value.value if value is not None else None) + self._set_attr( + "themeMode", value.value if isinstance(value, ThemeMode) else value + ) # on_click @property @@ -478,7 +480,6 @@ def on_click(self, handler): self.__on_click.subscribe(handler) self._set_attr("onClick", True if handler is not None else None) - # on_long_press @property def on_long_press(self): diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py index ee37edd66..efb2ae411 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py @@ -154,7 +154,10 @@ def mode(self) -> Optional[CupertinoTimerPickerMode]: @mode.setter def mode(self, value: Optional[CupertinoTimerPickerMode]): self.__mode = value - self._set_attr("mode", value.value if value is not None else None) + self._set_attr( + "mode", + value.value if isinstance(value, CupertinoTimerPickerMode) else value, + ) # on_change @property diff --git a/sdk/python/packages/flet-core/src/flet_core/gesture_detector.py b/sdk/python/packages/flet-core/src/flet_core/gesture_detector.py index 066273635..b7978cc84 100644 --- a/sdk/python/packages/flet-core/src/flet_core/gesture_detector.py +++ b/sdk/python/packages/flet-core/src/flet_core/gesture_detector.py @@ -416,7 +416,9 @@ def mouse_cursor(self): @mouse_cursor.setter def mouse_cursor(self, value: Optional[MouseCursor]): self.__mouse_cursor = value - self._set_attr("mouseCursor", value.value if value is not None else None) + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) # drag_interval @property diff --git a/sdk/python/packages/flet-core/src/flet_core/tabs.py b/sdk/python/packages/flet-core/src/flet_core/tabs.py index 64f35f1ba..74db8b732 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tabs.py +++ b/sdk/python/packages/flet-core/src/flet_core/tabs.py @@ -293,7 +293,9 @@ def tab_alignment(self) -> Optional[TabAlignment]: @tab_alignment.setter def tab_alignment(self, value: Optional[TabAlignment]): self.__tab_alignment = value - self._set_attr("tabAlignment", value.value if value is not None else None) + self._set_attr( + "tabAlignment", value.value if isinstance(value, TabAlignment) else value + ) # animation_duration @property diff --git a/sdk/python/packages/flet-core/src/flet_core/tooltip.py b/sdk/python/packages/flet-core/src/flet_core/tooltip.py index 1797127a9..efa64e81e 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tooltip.py +++ b/sdk/python/packages/flet-core/src/flet_core/tooltip.py @@ -159,9 +159,7 @@ def enable_tap_to_dismiss(self, value: Optional[bool]): # exclude_from_semantics @property def exclude_from_semantics(self) -> Optional[bool]: - return self._get_attr( - "excludeFromSemantics", data_type="bool", def_value=False - ) + return self._get_attr("excludeFromSemantics", data_type="bool", def_value=False) @exclude_from_semantics.setter def exclude_from_semantics(self, value: Optional[bool]): @@ -223,13 +221,13 @@ def border_radius(self, value: BorderRadiusValue): # shape @property - def shape(self): + def shape(self) -> Optional[BoxShape]: return self.__shape @shape.setter def shape(self, value: Optional[BoxShape]): self.__shape = value - self._set_attr("shape", value.value if value is not None else None) + self._set_attr("shape", value.value if isinstance(value, BoxShape) else value) # message @property @@ -254,7 +252,7 @@ def text_align(self, value: TextAlign): # text_style @property - def text_style(self): + def text_style(self) -> Optional[TextStyle]: return self.__text_style @text_style.setter From 6afc0fc16d0b97433e60ad6c33cbea91b5284152 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Tue, 12 Mar 2024 02:59:02 +0100 Subject: [PATCH 020/103] TimePicker: orientation --- .../flet/lib/src/controls/time_picker.dart | 5 +++++ .../flet-core/src/flet_core/__init__.py | 1 + .../flet-core/src/flet_core/time_picker.py | 19 +++++++++++++++++-- .../packages/flet-core/src/flet_core/types.py | 5 +++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/time_picker.dart b/packages/flet/lib/src/controls/time_picker.dart index a63655d3b..b3a88e176 100644 --- a/packages/flet/lib/src/controls/time_picker.dart +++ b/packages/flet/lib/src/controls/time_picker.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; @@ -45,6 +46,9 @@ class _TimePickerControlState extends State { .attrString("timePickerEntryMode", "")! .toLowerCase(), orElse: () => TimePickerEntryMode.dial); + Orientation? orientation = Orientation.values.firstWhereOrNull((a) => + a.name.toLowerCase() == + widget.control.attrString("orientation", "")!.toLowerCase()); void onClosed(TimeOfDay? timeValue) { String stringValue; @@ -77,6 +81,7 @@ class _TimePickerControlState extends State { minuteLabelText: minuteLabelText, errorInvalidText: errorInvalidText, initialEntryMode: timePickerEntryMode, + orientation: orientation, ); return dialog; diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index 8e7a74542..2d5b5560b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -269,6 +269,7 @@ MainAxisAlignment, MaterialState, NotchShape, + Orientation, PaddingValue, PagePlatform, ScrollMode, diff --git a/sdk/python/packages/flet-core/src/flet_core/time_picker.py b/sdk/python/packages/flet-core/src/flet_core/time_picker.py index 3e0e4fa95..258c1fe26 100644 --- a/sdk/python/packages/flet-core/src/flet_core/time_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/time_picker.py @@ -4,7 +4,7 @@ from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.types import ResponsiveNumber +from flet_core.types import Orientation, ResponsiveNumber from flet_core.utils import deprecated @@ -73,6 +73,7 @@ def __init__( cancel_text: Optional[str] = None, confirm_text: Optional[str] = None, error_invalid_text: Optional[str] = None, + orientation: Optional[Orientation] = None, on_change=None, on_dismiss=None, # @@ -108,6 +109,7 @@ def __init__( self.hour_label_text = hour_label_text self.minute_label_text = minute_label_text self.time_picker_entry_mode = time_picker_entry_mode + self.orientation = orientation self.on_change = on_change self.on_dismiss = on_dismiss self.open = open @@ -218,7 +220,20 @@ def time_picker_entry_mode(self) -> Optional[TimePickerEntryMode]: def time_picker_entry_mode(self, value: Optional[TimePickerEntryMode]): self.__time_picker_entry_mode = value self._set_attr( - "timePickerEntryMode", value.value if value is not None else None + "timePickerEntryMode", + value.value if isinstance(value, TimePickerEntryMode) else value, + ) + + # orientation + @property + def orientation(self) -> Optional[Orientation]: + return self.__orientation + + @orientation.setter + def orientation(self, value: Optional[Orientation]): + self.__orientation = value + self._set_attr( + "orientation", value.value if isinstance(value, Orientation) else value ) # on_change diff --git a/sdk/python/packages/flet-core/src/flet_core/types.py b/sdk/python/packages/flet-core/src/flet_core/types.py index 687f4e1f5..c244fcdd3 100644 --- a/sdk/python/packages/flet-core/src/flet_core/types.py +++ b/sdk/python/packages/flet-core/src/flet_core/types.py @@ -219,6 +219,11 @@ class Brightness(Enum): DARK = "dark" +class Orientation(Enum): + PORTRAIT = "portrait" + LANDSCAPE = "landscape" + + class FloatingActionButtonLocation(Enum): CENTER_DOCKED = "centerDocked" CENTER_FLOAT = "centerFloat" From e93ce7e9b05903fc03bb32fe5be7d5f4f607aae5 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Wed, 13 Mar 2024 07:24:38 +0100 Subject: [PATCH 021/103] FAB - dart: colors, elevation, enableFeedback --- .../src/controls/floating_action_button.dart | 114 ++++++++---------- packages/flet/lib/src/controls/page.dart | 2 +- packages/flet/lib/src/controls/pagelet.dart | 2 +- packages/flet/lib/src/utils/buttons.dart | 66 ++++++++++ 4 files changed, 116 insertions(+), 68 deletions(-) diff --git a/packages/flet/lib/src/controls/floating_action_button.dart b/packages/flet/lib/src/controls/floating_action_button.dart index 0563936c0..017081ab2 100644 --- a/packages/flet/lib/src/controls/floating_action_button.dart +++ b/packages/flet/lib/src/controls/floating_action_button.dart @@ -6,7 +6,6 @@ import '../utils/borders.dart'; import '../utils/colors.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; -import '../utils/transforms.dart'; import 'create_control.dart'; import 'error.dart'; @@ -35,13 +34,25 @@ class FloatingActionButtonControl extends StatelessWidget { IconData? icon = parseIcon(control.attrString("icon", "")!); String url = control.attrString("url", "")!; String? urlTarget = control.attrString("urlTarget"); + double? disabledElevation = control.attrDouble("disabledElevation"); + double? elevation = control.attrDouble("elevation"); + double? hoverElevation = control.attrDouble("hoverElevation"); + double? highlightElevation = control.attrDouble("highlightElevation"); + double? focusElevation = control.attrDouble("focusElevation"); Color? bgColor = HexColor.fromString( Theme.of(context), control.attrString("bgColor", "")!); + Color? foregroundColor = HexColor.fromString( + Theme.of(context), control.attrString("foregroundColor", "")!); + Color? splashColor = HexColor.fromString( + Theme.of(context), control.attrString("splashColor", "")!); + Color? hoverColor = HexColor.fromString( + Theme.of(context), control.attrString("hoverColor", "")!); OutlinedBorder? shape = parseOutlinedBorder(control, "shape"); var contentCtrls = children.where((c) => c.name == "content"); var tooltip = control.attrString("tooltip"); bool autofocus = control.attrBool("autofocus", false)!; bool mini = control.attrBool("mini", false)!; + bool? enableFeedback = control.attrBool("enableFeedback"); bool disabled = control.isDisabled || parentDisabled; Function()? onPressed = disabled @@ -66,6 +77,15 @@ class FloatingActionButtonControl extends StatelessWidget { autofocus: autofocus, onPressed: onPressed, backgroundColor: bgColor, + foregroundColor: foregroundColor, + hoverColor: hoverColor, + splashColor: splashColor, + elevation: elevation, + disabledElevation: disabledElevation, + focusElevation: focusElevation, + hoverElevation: hoverElevation, + highlightElevation: highlightElevation, + enableFeedback: enableFeedback, tooltip: tooltip, shape: shape, mini: mini, @@ -77,6 +97,15 @@ class FloatingActionButtonControl extends StatelessWidget { autofocus: autofocus, onPressed: onPressed, backgroundColor: bgColor, + foregroundColor: foregroundColor, + hoverColor: hoverColor, + splashColor: splashColor, + elevation: elevation, + disabledElevation: disabledElevation, + focusElevation: focusElevation, + hoverElevation: hoverElevation, + highlightElevation: highlightElevation, + enableFeedback: enableFeedback, tooltip: tooltip, shape: shape, mini: mini, @@ -87,6 +116,15 @@ class FloatingActionButtonControl extends StatelessWidget { autofocus: autofocus, onPressed: onPressed, backgroundColor: bgColor, + foregroundColor: foregroundColor, + hoverColor: hoverColor, + splashColor: splashColor, + elevation: elevation, + disabledElevation: disabledElevation, + focusElevation: focusElevation, + hoverElevation: hoverElevation, + highlightElevation: highlightElevation, + enableFeedback: enableFeedback, tooltip: tooltip, shape: shape, mini: mini, @@ -100,6 +138,15 @@ class FloatingActionButtonControl extends StatelessWidget { label: Text(text), icon: Icon(icon), backgroundColor: bgColor, + foregroundColor: foregroundColor, + hoverColor: hoverColor, + splashColor: splashColor, + elevation: elevation, + disabledElevation: disabledElevation, + focusElevation: focusElevation, + hoverElevation: hoverElevation, + highlightElevation: highlightElevation, + enableFeedback: enableFeedback, tooltip: tooltip, shape: shape, ); @@ -110,68 +157,3 @@ class FloatingActionButtonControl extends StatelessWidget { return constrainedControl(context, button, parent, control); } } - -FloatingActionButtonLocation parseFloatingActionButtonLocation( - Control control, String propName, FloatingActionButtonLocation defValue) { - List fabLocations = [ - FloatingActionButtonLocation.centerDocked, - FloatingActionButtonLocation.centerFloat, - FloatingActionButtonLocation.centerTop, - FloatingActionButtonLocation.endContained, - FloatingActionButtonLocation.endDocked, - FloatingActionButtonLocation.endFloat, - FloatingActionButtonLocation.endTop, - FloatingActionButtonLocation.miniCenterDocked, - FloatingActionButtonLocation.miniCenterFloat, - FloatingActionButtonLocation.miniCenterTop, - FloatingActionButtonLocation.miniEndFloat, - FloatingActionButtonLocation.miniEndTop, - FloatingActionButtonLocation.miniStartDocked, - FloatingActionButtonLocation.miniStartFloat, - FloatingActionButtonLocation.miniStartTop, - FloatingActionButtonLocation.startDocked, - FloatingActionButtonLocation.startFloat, - FloatingActionButtonLocation.startTop - ]; - - try { - OffsetDetails? fabLocationOffsetDetails = parseOffset(control, propName); - if (fabLocationOffsetDetails != null) { - return CustomFloatingActionButtonLocation( - dx: fabLocationOffsetDetails.x, dy: fabLocationOffsetDetails.y); - } else { - return defValue; - } - } catch (e) { - return fabLocations.firstWhere( - (l) => - l.toString().split('.').last.toLowerCase() == - control.attrString(propName, "")!.toLowerCase(), - orElse: () => defValue); - } -} - -class CustomFloatingActionButtonLocation extends FloatingActionButtonLocation { - final double dx; - final double dy; - - CustomFloatingActionButtonLocation({required this.dx, required this.dy}); - - @override - Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { - return Offset(scaffoldGeometry.scaffoldSize.width - dx, - scaffoldGeometry.scaffoldSize.height - dy); - } - - @override - bool operator ==(Object other) => - other is CustomFloatingActionButtonLocation && - other.dx == dx && - other.dy == dy; - - @override - int get hashCode => dx.hashCode + dy.hashCode; - - @override - String toString() => 'CustomFloatingActionButtonLocation'; -} diff --git a/packages/flet/lib/src/controls/page.dart b/packages/flet/lib/src/controls/page.dart index b48172cb9..ab9414587 100644 --- a/packages/flet/lib/src/controls/page.dart +++ b/packages/flet/lib/src/controls/page.dart @@ -21,6 +21,7 @@ import '../routing/route_parser.dart'; import '../routing/route_state.dart'; import '../routing/router_delegate.dart'; import '../utils/alignment.dart'; +import '../utils/buttons.dart'; import '../utils/colors.dart'; import '../utils/desktop.dart'; import '../utils/edge_insets.dart'; @@ -35,7 +36,6 @@ import 'app_bar.dart'; import 'create_control.dart'; import 'cupertino_app_bar.dart'; import 'flet_store_mixin.dart'; -import 'floating_action_button.dart'; import 'navigation_drawer.dart'; import 'scroll_notification_control.dart'; import 'scrollable_control.dart'; diff --git a/packages/flet/lib/src/controls/pagelet.dart b/packages/flet/lib/src/controls/pagelet.dart index cd5297ff4..a25537e7c 100644 --- a/packages/flet/lib/src/controls/pagelet.dart +++ b/packages/flet/lib/src/controls/pagelet.dart @@ -7,13 +7,13 @@ import '../flet_control_backend.dart'; import '../models/app_state.dart'; import '../models/control.dart'; import '../models/controls_view_model.dart'; +import '../utils/buttons.dart'; import '../utils/colors.dart'; import 'app_bar.dart'; import 'create_control.dart'; import 'cupertino_app_bar.dart'; import 'error.dart'; import 'flet_store_mixin.dart'; -import 'floating_action_button.dart'; import 'navigation_drawer.dart'; import 'page.dart'; diff --git a/packages/flet/lib/src/utils/buttons.dart b/packages/flet/lib/src/utils/buttons.dart index 57845f8bc..9c9a72264 100644 --- a/packages/flet/lib/src/utils/buttons.dart +++ b/packages/flet/lib/src/utils/buttons.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:flet/src/utils/transforms.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; @@ -84,3 +85,68 @@ ButtonStyle? buttonStyleFromJSON( shape: getMaterialStateProperty( json["shape"], (jv) => outlinedBorderFromJSON(jv), defaultShape)); } + +FloatingActionButtonLocation parseFloatingActionButtonLocation( + Control control, String propName, FloatingActionButtonLocation defValue) { + List fabLocations = [ + FloatingActionButtonLocation.centerDocked, + FloatingActionButtonLocation.centerFloat, + FloatingActionButtonLocation.centerTop, + FloatingActionButtonLocation.endContained, + FloatingActionButtonLocation.endDocked, + FloatingActionButtonLocation.endFloat, + FloatingActionButtonLocation.endTop, + FloatingActionButtonLocation.miniCenterDocked, + FloatingActionButtonLocation.miniCenterFloat, + FloatingActionButtonLocation.miniCenterTop, + FloatingActionButtonLocation.miniEndFloat, + FloatingActionButtonLocation.miniEndTop, + FloatingActionButtonLocation.miniStartDocked, + FloatingActionButtonLocation.miniStartFloat, + FloatingActionButtonLocation.miniStartTop, + FloatingActionButtonLocation.startDocked, + FloatingActionButtonLocation.startFloat, + FloatingActionButtonLocation.startTop + ]; + + try { + OffsetDetails? fabLocationOffsetDetails = parseOffset(control, propName); + if (fabLocationOffsetDetails != null) { + return CustomFloatingActionButtonLocation( + dx: fabLocationOffsetDetails.x, dy: fabLocationOffsetDetails.y); + } else { + return defValue; + } + } catch (e) { + return fabLocations.firstWhere( + (l) => + l.toString().split('.').last.toLowerCase() == + control.attrString(propName, "")!.toLowerCase(), + orElse: () => defValue); + } +} + +class CustomFloatingActionButtonLocation extends FloatingActionButtonLocation { + final double dx; + final double dy; + + CustomFloatingActionButtonLocation({required this.dx, required this.dy}); + + @override + Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) { + return Offset(scaffoldGeometry.scaffoldSize.width - dx, + scaffoldGeometry.scaffoldSize.height - dy); + } + + @override + bool operator ==(Object other) => + other is CustomFloatingActionButtonLocation && + other.dx == dx && + other.dy == dy; + + @override + int get hashCode => dx.hashCode + dy.hashCode; + + @override + String toString() => 'CustomFloatingActionButtonLocation'; +} From 7e433ead8a166114278ada169b9fc0e4fa617119 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:14:52 +0100 Subject: [PATCH 022/103] ProgressRing: stroke_cap, stroke_align, semantics_label, semantics_value --- .../flet/lib/src/controls/progress_ring.dart | 13 ++++++- .../flet-core/src/flet_core/__init__.py | 2 +- .../flet-core/src/flet_core/progress_ring.py | 36 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/progress_ring.dart b/packages/flet/lib/src/controls/progress_ring.dart index d7edf6c73..6952d5e15 100644 --- a/packages/flet/lib/src/controls/progress_ring.dart +++ b/packages/flet/lib/src/controls/progress_ring.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; @@ -15,7 +16,13 @@ class ProgressRingControl extends StatelessWidget { Widget build(BuildContext context) { debugPrint("ProgressRing build: ${control.id}"); - var value = control.attrDouble("value", null); + var value = control.attrDouble("value"); + var semanticsValue = control.attrDouble("semanticsValue"); + var strokeAlign = control.attrDouble("strokeAlign", 0)!; + var semanticsLabel = control.attrString("semanticsLabel"); + var strokeCap = StrokeCap.values.firstWhereOrNull((e) => + e.name.toLowerCase() == + control.attrString("strokeCap", "")!.toLowerCase()); var strokeWidth = control.attrDouble("strokeWidth", 4)!; var color = HexColor.fromString( Theme.of(context), control.attrString("color", "")!); @@ -29,6 +36,10 @@ class ProgressRingControl extends StatelessWidget { strokeWidth: strokeWidth, color: color, backgroundColor: bgColor, + semanticsLabel: semanticsLabel, + strokeCap: strokeCap, + semanticsValue: semanticsValue.toString(), + strokeAlign: strokeAlign, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index 2d5b5560b..cf7daa62b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -201,7 +201,7 @@ PopupMenuPosition, ) from flet_core.progress_bar import ProgressBar -from flet_core.progress_ring import ProgressRing +from flet_core.progress_ring import ProgressRing, StrokeCap from flet_core.pubsub import PubSubClient, PubSubHub from flet_core.querystring import QueryString from flet_core.radio import Radio diff --git a/sdk/python/packages/flet-core/src/flet_core/progress_ring.py b/sdk/python/packages/flet-core/src/flet_core/progress_ring.py index 41a183c19..d5e177ae5 100644 --- a/sdk/python/packages/flet-core/src/flet_core/progress_ring.py +++ b/sdk/python/packages/flet-core/src/flet_core/progress_ring.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from flet_core.constrained_control import ConstrainedControl @@ -12,6 +13,12 @@ ) +class StrokeCap(Enum): + ROUND = "round" + SQUARE = "square" + BUTT = "butt" + + class ProgressRing(ConstrainedControl): """ A material design circular progress indicator, which spins to indicate that the application is busy. @@ -56,6 +63,10 @@ def __init__( stroke_width: OptionalNumber = None, color: Optional[str] = None, bgcolor: Optional[str] = None, + stroke_align: OptionalNumber = None, + stroke_cap: Optional[StrokeCap] = None, + semantics_label: Optional[str] = None, + semantics_value: OptionalNumber = None, # # ConstrainedControl # @@ -121,6 +132,10 @@ def __init__( self.stroke_width = stroke_width self.color = color self.bgcolor = bgcolor + self.semantics_label = semantics_label + self.semantics_value = semantics_value + self.stroke_align = stroke_align + self.stroke_cap = stroke_cap def _get_control_name(self): return "progressring" @@ -143,6 +158,27 @@ def stroke_width(self) -> OptionalNumber: def stroke_width(self, value: OptionalNumber): self._set_attr("strokeWidth", value) + # stroke_align + @property + def stroke_align(self) -> OptionalNumber: + return self._get_attr("strokeAlign", data_type="float", def_value=0.0) + + @stroke_align.setter + def stroke_align(self, value: OptionalNumber): + self._set_attr("strokeAlign", value) + + # stroke_cap + @property + def stroke_cap(self) -> OptionalNumber: + return self.__stroke_cap + + @stroke_cap.setter + def stroke_cap(self, value: OptionalNumber): + self.__stroke_cap = value + self._set_attr( + "strokeCap", value.value if isinstance(value, StrokeCap) else value + ) + # color @property def color(self): From 1b22c5cba5fc1df6a3c4fe05131e74c59614c85a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:15:24 +0100 Subject: [PATCH 023/103] ProgressBar: border_radius, semantics_label, semantics_value --- .../flet/lib/src/controls/progress_bar.dart | 9 +++- .../flet-core/src/flet_core/progress_bar.py | 46 +++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/packages/flet/lib/src/controls/progress_bar.dart b/packages/flet/lib/src/controls/progress_bar.dart index 43e7ed14d..c633e4ce9 100644 --- a/packages/flet/lib/src/controls/progress_bar.dart +++ b/packages/flet/lib/src/controls/progress_bar.dart @@ -1,3 +1,4 @@ +import 'package:flet/src/utils/borders.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; @@ -15,7 +16,9 @@ class ProgressBarControl extends StatelessWidget { Widget build(BuildContext context) { debugPrint("ProgressBar build: ${control.id}"); - var value = control.attrDouble("value", null); + var value = control.attrDouble("value"); + var semanticsValue = control.attrDouble("semanticsValue"); + var semanticsLabel = control.attrString("semanticsLabel"); var barHeight = control.attrDouble("barHeight", 4)!; var color = HexColor.fromString( Theme.of(context), control.attrString("color", "")!); @@ -29,6 +32,10 @@ class ProgressBarControl extends StatelessWidget { minHeight: barHeight, color: color, backgroundColor: bgColor, + semanticsLabel: semanticsLabel, + semanticsValue: semanticsValue.toString(), + borderRadius: + parseBorderRadius(control, "borderRadius") ?? BorderRadius.zero, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/progress_bar.py b/sdk/python/packages/flet-core/src/flet_core/progress_bar.py index 6fe1128a8..d35fc7038 100644 --- a/sdk/python/packages/flet-core/src/flet_core/progress_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/progress_bar.py @@ -5,6 +5,7 @@ from flet_core.ref import Ref from flet_core.types import ( AnimationValue, + BorderRadiusValue, OffsetValue, ResponsiveNumber, RotateValue, @@ -54,6 +55,9 @@ def __init__( bar_height: OptionalNumber = None, color: Optional[str] = None, bgcolor: Optional[str] = None, + border_radius: BorderRadiusValue = None, + semantics_label: Optional[str] = None, + semantics_value: OptionalNumber = None, # # ConstrainedControl # @@ -119,10 +123,17 @@ def __init__( self.bar_height = bar_height self.color = color self.bgcolor = bgcolor + self.border_radius = border_radius + self.semantics_label = semantics_label + self.semantics_value = semantics_value def _get_control_name(self): return "progressbar" + def before_update(self): + super().before_update() + self._set_attr_json("borderRadius", self.__border_radius) + # value @property def value(self) -> OptionalNumber: @@ -135,11 +146,20 @@ def value(self, value: OptionalNumber): # bar_height @property def bar_height(self) -> OptionalNumber: - return self._get_attr("barheight") + return self._get_attr("barHeight") @bar_height.setter def bar_height(self, value: OptionalNumber): - self._set_attr("barheight", value) + self._set_attr("barHeight", value) + + # semantics_value + @property + def semantics_value(self) -> OptionalNumber: + return self._get_attr("semanticsValue") + + @semantics_value.setter + def semantics_value(self, value: OptionalNumber): + self._set_attr("semanticsValue", value) # color @property @@ -147,14 +167,32 @@ def color(self): return self._get_attr("color") @color.setter - def color(self, value): + def color(self, value: Optional[str]): self._set_attr("color", value) + # semantics_label + @property + def semantics_label(self): + return self._get_attr("semanticsLabel") + + @semantics_label.setter + def semantics_label(self, value: Optional[str]): + self._set_attr("semanticsLabel", value) + # bgcolor @property def bgcolor(self): return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) + + # border_radius + @property + def border_radius(self) -> BorderRadiusValue: + return self.__border_radius + + @border_radius.setter + def border_radius(self, value: BorderRadiusValue): + self.__border_radius = value From 3417cf077662379c5a33859ac9b3cf12f584df18 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:17:44 +0100 Subject: [PATCH 024/103] OutlinedButton: clip_behavior --- .../flet/lib/src/controls/outlined_button.dart | 11 +++++++++-- .../flet-core/src/flet_core/outlined_button.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/outlined_button.dart b/packages/flet/lib/src/controls/outlined_button.dart index 5502d40e7..ba9036745 100644 --- a/packages/flet/lib/src/controls/outlined_button.dart +++ b/packages/flet/lib/src/controls/outlined_button.dart @@ -59,6 +59,7 @@ class _OutlinedButtonControlState extends State @override Widget build(BuildContext context) { debugPrint("Button build: ${widget.control.id}"); + bool disabled = widget.control.isDisabled || widget.parentDisabled; String text = widget.control.attrString("text", "")!; IconData? icon = parseIcon(widget.control.attrString("icon", "")!); @@ -70,8 +71,11 @@ class _OutlinedButtonControlState extends State 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; - + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.none); Function()? onPressed = !disabled ? () { debugPrint("Button ${widget.control.id} clicked!"); @@ -143,6 +147,7 @@ class _OutlinedButtonControlState extends State focusNode: _focusNode, onPressed: onPressed, onLongPress: onLongPressHandler, + clipBehavior: clipBehavior, style: style, icon: Icon( icon, @@ -155,6 +160,7 @@ class _OutlinedButtonControlState extends State focusNode: _focusNode, onPressed: onPressed, onLongPress: onLongPressHandler, + clipBehavior: clipBehavior, onHover: onHoverHandler, style: style, child: @@ -166,6 +172,7 @@ class _OutlinedButtonControlState extends State style: style, onPressed: onPressed, onLongPress: onLongPressHandler, + clipBehavior: clipBehavior, onHover: onHoverHandler, child: Text(text)); } diff --git a/sdk/python/packages/flet-core/src/flet_core/outlined_button.py b/sdk/python/packages/flet-core/src/flet_core/outlined_button.py index 184e3c5a9..7832814df 100644 --- a/sdk/python/packages/flet-core/src/flet_core/outlined_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/outlined_button.py @@ -8,6 +8,7 @@ from flet_core.ref import Ref from flet_core.types import ( AnimationValue, + ClipBehavior, OffsetValue, ResponsiveNumber, RotateValue, @@ -47,6 +48,7 @@ def __init__( content: Optional[Control] = None, style: Optional[ButtonStyle] = None, autofocus: Optional[bool] = None, + clip_behavior: Optional[ClipBehavior] = None, url: Optional[str] = None, url_target: Optional[str] = None, on_click=None, @@ -126,6 +128,7 @@ def __init__( self.autofocus = autofocus self.url = url self.url_target = url_target + self.clip_behavior = clip_behavior self.on_click = on_click self.on_long_press = on_long_press self.on_hover = on_hover @@ -252,6 +255,17 @@ def autofocus(self) -> Optional[bool]: def autofocus(self, value: Optional[bool]): self._set_attr("autofocus", value) + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + # on_hover @property def on_hover(self): From 1cc4a4cebe8c5b3f612e6ece10c46c28da5eca29 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:19:46 +0100 Subject: [PATCH 025/103] NavBar: animation_duration --- packages/flet/lib/src/controls/navigation_bar.dart | 4 ++++ .../flet-core/src/flet_core/navigation_bar.py | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/packages/flet/lib/src/controls/navigation_bar.dart b/packages/flet/lib/src/controls/navigation_bar.dart index 981db53fd..8ee4b26ff 100644 --- a/packages/flet/lib/src/controls/navigation_bar.dart +++ b/packages/flet/lib/src/controls/navigation_bar.dart @@ -68,6 +68,7 @@ class _NavigationBarControlState extends State if (_selectedIndex != selectedIndex) { _selectedIndex = selectedIndex; } + var animationDuration = widget.control.attrInt("animationDuration"); NavigationDestinationLabelBehavior? labelBehavior = NavigationDestinationLabelBehavior.values.firstWhereOrNull((a) => @@ -81,6 +82,9 @@ class _NavigationBarControlState extends State return NavigationBar( labelBehavior: labelBehavior, height: widget.control.attrDouble("height"), + animationDuration: animationDuration != null + ? Duration(milliseconds: animationDuration) + : null, elevation: widget.control.attrDouble("elevation"), shadowColor: HexColor.fromString(Theme.of(context), widget.control.attrString("shadowColor", "")!), diff --git a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py index 2a43292b5..29133a96c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py @@ -168,6 +168,7 @@ def __init__( indicator_shape: Optional[OutlinedBorder] = None, surface_tint_color: Optional[str] = None, border: Optional[Border] = None, + animation_duration: Optional[int] = None, on_change=None, # # ConstrainedControl and AdaptiveControl @@ -241,6 +242,7 @@ def __init__( self.surface_tint_color = surface_tint_color self.border = border self.on_change = on_change + self.animation_duration = animation_duration def _get_control_name(self): return "navigationbar" @@ -349,6 +351,15 @@ def border(self) -> Optional[Border]: def border(self, value: Optional[Border]): self.__border = value + # animation_duration + @property + def animation_duration(self): + return self._get_attr("animationDuration", data_type="int") + + @animation_duration.setter + def animation_duration(self, value: OptionalNumber): + self._set_attr("animationDuration", value) + # on_change @property def on_change(self): From 593addbef1b362ae622bb5c88efd00c42436784a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:22:49 +0100 Subject: [PATCH 026/103] AlertDialog: action_button_padding, clip_behavior, icon_padding, shadow_color, surface_tint_color --- .../flet/lib/src/controls/alert_dialog.dart | 12 ++++ .../flet-core/src/flet_core/alert_dialog.py | 63 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/alert_dialog.dart b/packages/flet/lib/src/controls/alert_dialog.dart index 058e5e03a..d30167841 100644 --- a/packages/flet/lib/src/controls/alert_dialog.dart +++ b/packages/flet/lib/src/controls/alert_dialog.dart @@ -53,6 +53,11 @@ class _AlertDialogControlState extends State if (titleCtrls.isEmpty && contentCtrls.isEmpty && actionCtrls.isEmpty) { return const ErrorControl("AlertDialog does not have any content."); } + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.none); return AlertDialog( title: titleCtrls.isNotEmpty @@ -76,9 +81,16 @@ class _AlertDialogControlState extends State semanticLabel: widget.control.attrString("semanticsLabel"), insetPadding: parseEdgeInsets(widget.control, "insetPadding") ?? const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0), + iconPadding: parseEdgeInsets(widget.control, "iconPadding"), backgroundColor: HexColor.fromString( Theme.of(context), widget.control.attrString("bgcolor", "")!), + buttonPadding: parseEdgeInsets(widget.control, "actionButtonPadding"), + surfaceTintColor: HexColor.fromString(Theme.of(context), + widget.control.attrString("surfaceTintColor", "")!), + shadowColor: HexColor.fromString( + Theme.of(context), widget.control.attrString("shadowColor", "")!), elevation: widget.control.attrDouble("elevation"), + clipBehavior: clipBehavior, icon: iconCtrls.isNotEmpty ? createControl(widget.control, iconCtrls.first.id, disabled, parentAdaptive: adaptive) diff --git a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py index ebde98645..bbad8b29f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py +++ b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py @@ -4,7 +4,7 @@ from flet_core.buttons import OutlinedBorder from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.types import MainAxisAlignment, PaddingValue +from flet_core.types import ClipBehavior, MainAxisAlignment, PaddingValue class AlertDialog(AdaptiveControl): @@ -76,6 +76,11 @@ def __init__( actions_alignment: MainAxisAlignment = MainAxisAlignment.NONE, shape: Optional[OutlinedBorder] = None, inset_padding: PaddingValue = None, + icon_padding: PaddingValue = None, + action_button_padding: PaddingValue = None, + surface_tint_color: Optional[str] = None, + shadow_color: Optional[str] = None, + clip_behavior: Optional[ClipBehavior] = None, semantics_label: Optional[str] = None, adaptive: Optional[bool] = None, on_dismiss=None, @@ -118,6 +123,11 @@ def __init__( self.inset_padding = inset_padding self.semantics_label = semantics_label self.on_dismiss = on_dismiss + self.clip_behavior = clip_behavior + self.action_button_padding = action_button_padding + self.shadow_color = shadow_color + self.surface_tint_color = surface_tint_color + self.icon_padding = icon_padding def _get_control_name(self): return "alertdialog" @@ -129,6 +139,8 @@ def before_update(self): self._set_attr_json("titlePadding", self.__title_padding) self._set_attr_json("shape", self.__shape) self._set_attr_json("insetPadding", self.__inset_padding) + self._set_attr_json("iconPadding", self.__icon_padding) + self._set_attr_json("actionButtonPadding", self.__action_button_padding) def _get_children(self): children = [] @@ -161,9 +173,27 @@ def bgcolor(self): return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) + # shadow_color + @property + def shadow_color(self): + return self._get_attr("shadowColor") + + @shadow_color.setter + def shadow_color(self, value: Optional[str]): + self._set_attr("shadowColor", value) + + # surface_tint_color + @property + def surface_tint_color(self): + return self._get_attr("surfaceTintColor") + + @surface_tint_color.setter + def surface_tint_color(self, value: Optional[str]): + self._set_attr("surfaceTintColor", value) + # elevation @property def elevation(self) -> OptionalNumber: @@ -276,6 +306,24 @@ def inset_padding(self) -> PaddingValue: def inset_padding(self, value: PaddingValue): self.__inset_padding = value + # icon_padding + @property + def icon_padding(self) -> PaddingValue: + return self.__icon_padding + + @icon_padding.setter + def icon_padding(self, value: PaddingValue): + self.__icon_padding = value + + # action_button_padding + @property + def action_button_padding(self) -> PaddingValue: + return self.__action_button_padding + + @action_button_padding.setter + def action_button_padding(self, value: PaddingValue): + self.__action_button_padding = value + # semantics_label @property def semantics_label(self): @@ -285,6 +333,17 @@ def semantics_label(self): def semantics_label(self, value): self._set_attr("semanticsLabel", value) + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + # on_dismiss @property def on_dismiss(self): From f68b5dc74dcdbd85f5a464df8268a933b11722f8 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:24:01 +0100 Subject: [PATCH 027/103] ListTile: enable_feedback, horizontal_spacing, min_leading_width, min_vertical_padding, selected_color, selected_tile_color, splash_color, style --- packages/flet/lib/src/controls/list_tile.dart | 14 +++ .../flet-core/src/flet_core/__init__.py | 2 +- .../flet-core/src/flet_core/list_tile.py | 90 ++++++++++++++++++- 3 files changed, 103 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/list_tile.dart b/packages/flet/lib/src/controls/list_tile.dart index 161d7d3c1..c801448d2 100644 --- a/packages/flet/lib/src/controls/list_tile.dart +++ b/packages/flet/lib/src/controls/list_tile.dart @@ -76,6 +76,10 @@ class ListTileControl extends StatelessWidget with FletStoreMixin { bool onclick = control.attrBool("onclick", false)!; bool toggleInputs = control.attrBool("toggleInputs", false)!; bool onLongPressDefined = control.attrBool("onLongPress", false)!; + bool? enableFeedback = control.attrBool("enableFeedback"); + double? horizontalSpacing = control.attrDouble("horizontalSpacing"); + double? minLeadingWidth = control.attrDouble("minLeadingWidth"); + double? minVerticalPadding = control.attrDouble("minVerticalPadding"); String url = control.attrString("url", "")!; String? urlTarget = control.attrString("urlTarget"); bool disabled = control.isDisabled || parentDisabled; @@ -112,6 +116,16 @@ class ListTileControl extends StatelessWidget with FletStoreMixin { onTap: onPressed, onLongPress: onLongPress, enabled: !disabled, + horizontalTitleGap: horizontalSpacing, + enableFeedback: enableFeedback, + minLeadingWidth: minLeadingWidth, + minVerticalPadding: minVerticalPadding, + selectedTileColor: HexColor.fromString( + Theme.of(context), control.attrString("selectedTileColor", "")!), + selectedColor: HexColor.fromString( + Theme.of(context), control.attrString("selectedColor", "")!), + focusColor: HexColor.fromString( + Theme.of(context), control.attrString("focusColor", "")!), tileColor: HexColor.fromString( Theme.of(context), control.attrString("bgcolor", "")!), splashColor: HexColor.fromString( diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index cf7daa62b..b606c3a03 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -155,7 +155,7 @@ from flet_core.icon import Icon from flet_core.icon_button import IconButton from flet_core.image import Image -from flet_core.list_tile import ListTile +from flet_core.list_tile import ListTile, ListTileStyle from flet_core.list_view import ListView from flet_core.lottie import Lottie from flet_core.margin import Margin diff --git a/sdk/python/packages/flet-core/src/flet_core/list_tile.py b/sdk/python/packages/flet-core/src/flet_core/list_tile.py index f1140b1f8..85a7cdd3c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_tile.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -14,6 +15,11 @@ ) +class ListTileStyle(Enum): + LIST = "list" + DRAWER = "drawer" + + class ListTile(ConstrainedControl, AdaptiveControl): """ A single fixed-height row that typically contains some text as well as a leading or trailing icon. @@ -70,6 +76,13 @@ def __init__( dense: Optional[bool] = None, autofocus: Optional[bool] = None, toggle_inputs: Optional[bool] = None, + selected_color: Optional[str] = None, + selected_tile_color: Optional[str] = None, + style: Optional[ListTileStyle] = None, + enable_feedback: Optional[bool] = None, + horizontal_spacing: OptionalNumber = None, + min_leading_width: OptionalNumber = None, + min_vertical_padding: OptionalNumber = None, url: Optional[str] = None, url_target: Optional[str] = None, on_click=None, @@ -156,6 +169,13 @@ def __init__( self.hover_color = hover_color self.on_click = on_click self.on_long_press = on_long_press + self.style = style + self.selected_color = selected_color + self.selected_tile_color = selected_tile_color + self.enable_feedback = enable_feedback + self.horizontal_spacing = horizontal_spacing + self.min_leading_width = min_leading_width + self.min_vertical_padding = min_vertical_padding def _get_control_name(self): return "listtile" @@ -195,18 +215,54 @@ def bgcolor(self): return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) + # selected_color + @property + def selected_color(self): + return self._get_attr("selectedColor") + + @selected_color.setter + def selected_color(self, value: Optional[str]): + self._set_attr("selectedColor", value) + + # selected_tile_color + @property + def selected_tile_color(self): + return self._get_attr("selectedTileColor") + + @selected_tile_color.setter + def selected_tile_color(self, value: Optional[str]): + self._set_attr("selectedTileColor", value) + # bgcolor_activated @property def bgcolor_activated(self): return self._get_attr("bgcolorActivated") @bgcolor_activated.setter - def bgcolor_activated(self, value): + def bgcolor_activated(self, value: Optional[str]): self._set_attr("bgcolorActivated", value) + # min_leading_width + @property + def min_leading_width(self): + return self._get_attr("minLeadingWidth", data_type="float", def_value=40) + + @min_leading_width.setter + def min_leading_width(self, value: OptionalNumber): + self._set_attr("minLeadingWidth", value) + + # horizontal_spacing + @property + def horizontal_spacing(self): + return self._get_attr("horizontalSpacing", data_type="float", def_value=16) + + @horizontal_spacing.setter + def horizontal_spacing(self, value: OptionalNumber): + self._set_attr("horizontalSpacing", value) + # hover_color @property def hover_color(self): @@ -234,6 +290,15 @@ def title(self) -> Optional[Control]: def title(self, value: Optional[Control]): self.__title = value + # min_vertical_padding + @property + def min_vertical_padding(self) -> OptionalNumber: + return self._get_attr("minVerticalPadding", data_type="float", def_value=4.0) + + @min_vertical_padding.setter + def min_vertical_padding(self, value: OptionalNumber): + self._set_attr("minVerticalPadding", value) + # subtitle @property def subtitle(self) -> Optional[Control]: @@ -261,6 +326,27 @@ def is_three_line(self) -> Optional[bool]: def is_three_line(self, value: Optional[bool]): self._set_attr("isThreeLine", value) + # enable_feedback + @property + def enable_feedback(self) -> Optional[bool]: + return self._get_attr("enableFeedback", data_type="bool", def_value=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + + # style + @property + def style(self) -> Optional[ListTileStyle]: + return self.__style + + @style.setter + def style(self, value: Optional[ListTileStyle]): + self.__style = value + self._set_attr( + "style", value.value if isinstance(value, ListTileStyle) else value + ) + # selected @property def selected(self) -> Optional[bool]: From c0d10ab12d2181924ab30bd4fd1bff7200a2251d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:24:38 +0100 Subject: [PATCH 028/103] Image: exclude_from_semantics, filter_quality, semantics_label --- packages/flet/lib/src/controls/image.dart | 11 +++++++ .../packages/flet-core/src/flet_core/image.py | 30 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/image.dart b/packages/flet/lib/src/controls/image.dart index 55d980e22..f0fd712a4 100644 --- a/packages/flet/lib/src/controls/image.dart +++ b/packages/flet/lib/src/controls/image.dart @@ -54,6 +54,12 @@ class ImageControl extends StatelessWidget with FletStoreMixin { Theme.of(context), control.attrString("color", "")!); String? semanticsLabel = control.attrString("semanticsLabel"); var gaplessPlayback = control.attrBool("gaplessPlayback"); + var excludeFromSemantics = control.attrBool("excludeFromSemantics", false)!; + FilterQuality filterQuality = FilterQuality.values.firstWhere( + (e) => + e.name.toLowerCase() == + control.attrString("filterQuality", "")!.toLowerCase(), + orElse: () => FilterQuality.low); bool disabled = control.isDisabled || parentDisabled; var errorContentCtrls = children.where((c) => c.name == "error_content" && c.isVisible); @@ -117,6 +123,8 @@ class ImageControl extends StatelessWidget with FletStoreMixin { width: width, height: height, repeat: repeat, + filterQuality: filterQuality, + excludeFromSemantics: excludeFromSemantics, fit: fit, color: color, gaplessPlayback: gaplessPlayback ?? false, @@ -136,6 +144,7 @@ class ImageControl extends StatelessWidget with FletStoreMixin { image = SvgPicture.network(assetSrc.path, width: width, height: height, + excludeFromSemantics: excludeFromSemantics, fit: fit ?? BoxFit.contain, colorFilter: color != null ? ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn) @@ -146,6 +155,8 @@ class ImageControl extends StatelessWidget with FletStoreMixin { width: width, height: height, repeat: repeat, + filterQuality: filterQuality, + excludeFromSemantics: excludeFromSemantics, fit: fit, color: color, gaplessPlayback: gaplessPlayback ?? false, diff --git a/sdk/python/packages/flet-core/src/flet_core/image.py b/sdk/python/packages/flet-core/src/flet_core/image.py index fb60eb8cc..31c9aea93 100644 --- a/sdk/python/packages/flet-core/src/flet_core/image.py +++ b/sdk/python/packages/flet-core/src/flet_core/image.py @@ -14,6 +14,7 @@ RotateValue, ScaleValue, ) +from flet_core.video import FilterQuality try: from typing import Literal @@ -61,6 +62,8 @@ def __init__( color_blend_mode: BlendMode = BlendMode.NONE, gapless_playback: Optional[bool] = None, semantics_label: Optional[str] = None, + exclude_from_semantics: Optional[bool] = None, + filter_quality: Optional[FilterQuality] = None, # # ConstrainedControl # @@ -133,6 +136,8 @@ def __init__( self.color_blend_mode = color_blend_mode self.gapless_playback = gapless_playback self.semantics_label = semantics_label + self.exclude_from_semantics = exclude_from_semantics + self.filter_quality = filter_quality def _get_control_name(self): return "image" @@ -154,7 +159,7 @@ def src(self): return self._get_attr("src") @src.setter - def src(self, value): + def src(self, value: Optional[str]): self._set_attr("src", value) # src_base64 @@ -163,7 +168,7 @@ def src_base64(self): return self._get_attr("srcBase64") @src_base64.setter - def src_base64(self, value): + def src_base64(self, value: Optional[str]): self._set_attr("srcBase64", value) # fit @@ -176,6 +181,18 @@ def fit(self, value: Optional[ImageFit]): self.__fit = value self._set_attr("fit", value.value if isinstance(value, ImageFit) else value) + # filter_quality + @property + def filter_quality(self) -> Optional[FilterQuality]: + return self.__filter_quality + + @filter_quality.setter + def filter_quality(self, value: Optional[FilterQuality]): + self.__filter_quality = value + self._set_attr( + "filterQuality", value.value if isinstance(value, FilterQuality) else value + ) + # repeat @property def repeat(self) -> Optional[ImageRepeat]: @@ -227,6 +244,15 @@ def gapless_playback(self) -> Optional[bool]: def gapless_playback(self, value: Optional[bool]): self._set_attr("gaplessPlayback", value) + # exclude_from_semantics + @property + def exclude_from_semantics(self) -> Optional[bool]: + return self._get_attr("excludeFromSemantics", data_type="bool", def_value=False) + + @exclude_from_semantics.setter + def exclude_from_semantics(self, value: Optional[bool]): + self._set_attr("excludeFromSemantics", value) + # semantics_label @property def semantics_label(self): From 8d4d306e70d27e97e5eaf5f9d5299a2884f0052d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:25:41 +0100 Subject: [PATCH 029/103] SelectionArea: on_change --- packages/flet/lib/src/controls/selection_area.dart | 9 ++++++++- .../flet-core/src/flet_core/selection_area.py | 11 +++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/selection_area.dart b/packages/flet/lib/src/controls/selection_area.dart index 3d3ea077e..8cdbe2ff3 100644 --- a/packages/flet/lib/src/controls/selection_area.dart +++ b/packages/flet/lib/src/controls/selection_area.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../flet_control_backend.dart'; import '../models/control.dart'; import 'create_control.dart'; import 'error.dart'; @@ -10,6 +11,7 @@ class SelectionAreaControl extends StatelessWidget { final List children; final bool parentDisabled; final bool? parentAdaptive; + final FletControlBackend backend; const SelectionAreaControl( {super.key, @@ -17,7 +19,8 @@ class SelectionAreaControl extends StatelessWidget { required this.control, required this.children, required this.parentDisabled, - required this.parentAdaptive}); + required this.parentAdaptive, + required this.backend}); @override Widget build(BuildContext context) { @@ -38,6 +41,10 @@ class SelectionAreaControl extends StatelessWidget { context, SelectionArea( child: child, + onSelectionChanged: (selection) { + backend.triggerControlEvent( + control.id, "change", selection?.plainText ?? ""); + }, ), parent, control); diff --git a/sdk/python/packages/flet-core/src/flet_core/selection_area.py b/sdk/python/packages/flet-core/src/flet_core/selection_area.py index 25503da88..92cd9fee9 100644 --- a/sdk/python/packages/flet-core/src/flet_core/selection_area.py +++ b/sdk/python/packages/flet-core/src/flet_core/selection_area.py @@ -31,6 +31,7 @@ def main(page: ft.Page): def __init__( self, content: Control, + on_change=None, # # Control # @@ -44,6 +45,7 @@ def __init__( ) self.content = content + self.on_change = on_change def _get_control_name(self): return "selectionarea" @@ -63,3 +65,12 @@ def content(self) -> Control: @content.setter def content(self, value: Control): self.__content = value + + # on_change + @property + def on_change(self): + return self._get_event_handler("change") + + @on_change.setter + def on_change(self, handler): + self._add_event_handler("change", handler) From c8307bfe675e911b04e875a725a79bd7730c7821 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:26:40 +0100 Subject: [PATCH 030/103] ListView: semantic_child_count, clipBehavior --- packages/flet/lib/src/controls/list_view.dart | 9 +++++++ .../flet-core/src/flet_core/list_view.py | 25 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/packages/flet/lib/src/controls/list_view.dart b/packages/flet/lib/src/controls/list_view.dart index b247fdcc4..6e2031146 100644 --- a/packages/flet/lib/src/controls/list_view.dart +++ b/packages/flet/lib/src/controls/list_view.dart @@ -58,10 +58,16 @@ class _ListViewControlState extends State { final spacing = widget.control.attrDouble("spacing", 0)!; final dividerThickness = widget.control.attrDouble("dividerThickness", 0)!; final itemExtent = widget.control.attrDouble("itemExtent"); + final semanticChildCount = widget.control.attrInt("semanticChildCount"); final firstItemPrototype = widget.control.attrBool("firstItemPrototype", false)!; final padding = parseEdgeInsets(widget.control, "padding"); final reverse = widget.control.attrBool("reverse", false)!; + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.hardEdge); List visibleControls = widget.children.where((c) => c.isVisible).toList(); @@ -79,6 +85,7 @@ class _ListViewControlState extends State { ? ListView.separated( controller: _controller, reverse: reverse, + clipBehavior: clipBehavior, scrollDirection: horizontal ? Axis.horizontal : Axis.vertical, shrinkWrap: shrinkWrap, padding: padding, @@ -102,6 +109,8 @@ class _ListViewControlState extends State { ) : ListView.builder( controller: _controller, + clipBehavior: clipBehavior, + semanticChildCount: semanticChildCount, reverse: reverse, scrollDirection: horizontal ? Axis.horizontal : Axis.vertical, shrinkWrap: shrinkWrap, diff --git a/sdk/python/packages/flet-core/src/flet_core/list_view.py b/sdk/python/packages/flet-core/src/flet_core/list_view.py index 5801f521b..82d2afed7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_view.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_view.py @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, ) from flet_core.utils import deprecated @@ -64,6 +65,8 @@ def __init__( first_item_prototype: Optional[bool] = None, divider_thickness: OptionalNumber = None, padding: PaddingValue = None, + clip_behavior: Optional[ClipBehavior] = None, + semantic_child_count: Optional[int] = None, # # ScrollableControl specific # @@ -153,6 +156,8 @@ def __init__( self.item_extent = item_extent self.first_item_prototype = first_item_prototype self.padding = padding + self.clip_behavior = clip_behavior + self.semantic_child_count = semantic_child_count def _get_control_name(self): return "listview" @@ -238,3 +243,23 @@ def controls(self): @controls.setter def controls(self, value): self.__controls = value if value is not None else [] + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + + # semantic_child_count + @property + def semantic_child_count(self) -> Optional[int]: + return self._get_attr("semanticChildCount", data_type="int") + + @semantic_child_count.setter + def semantic_child_count(self, value: Optional[int]): + self._set_attr("semanticChildCount", value) From b7fe87df11da3a3e626b0b2546d463327ce4ad7b Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:27:19 +0100 Subject: [PATCH 031/103] FAB: colors, elevations, enable_feedback, clip_behavior --- .../src/controls/floating_action_button.dart | 15 +++ .../src/flet_core/floating_action_button.py | 103 ++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/packages/flet/lib/src/controls/floating_action_button.dart b/packages/flet/lib/src/controls/floating_action_button.dart index 017081ab2..cb688ea69 100644 --- a/packages/flet/lib/src/controls/floating_action_button.dart +++ b/packages/flet/lib/src/controls/floating_action_button.dart @@ -47,7 +47,14 @@ class FloatingActionButtonControl extends StatelessWidget { Theme.of(context), control.attrString("splashColor", "")!); Color? hoverColor = HexColor.fromString( Theme.of(context), control.attrString("hoverColor", "")!); + Color? focusColor = HexColor.fromString( + Theme.of(context), control.attrString("focusColor", "")!); OutlinedBorder? shape = parseOutlinedBorder(control, "shape"); + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.none); var contentCtrls = children.where((c) => c.name == "content"); var tooltip = control.attrString("tooltip"); bool autofocus = control.attrBool("autofocus", false)!; @@ -86,6 +93,8 @@ class FloatingActionButtonControl extends StatelessWidget { hoverElevation: hoverElevation, highlightElevation: highlightElevation, enableFeedback: enableFeedback, + clipBehavior: clipBehavior, + focusColor: focusColor, tooltip: tooltip, shape: shape, mini: mini, @@ -106,6 +115,8 @@ class FloatingActionButtonControl extends StatelessWidget { hoverElevation: hoverElevation, highlightElevation: highlightElevation, enableFeedback: enableFeedback, + clipBehavior: clipBehavior, + focusColor: focusColor, tooltip: tooltip, shape: shape, mini: mini, @@ -125,6 +136,8 @@ class FloatingActionButtonControl extends StatelessWidget { hoverElevation: hoverElevation, highlightElevation: highlightElevation, enableFeedback: enableFeedback, + clipBehavior: clipBehavior, + focusColor: focusColor, tooltip: tooltip, shape: shape, mini: mini, @@ -147,6 +160,8 @@ class FloatingActionButtonControl extends StatelessWidget { hoverElevation: hoverElevation, highlightElevation: highlightElevation, enableFeedback: enableFeedback, + clipBehavior: clipBehavior, + focusColor: focusColor, tooltip: tooltip, shape: shape, ); diff --git a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py index 9d3190571..cb4298d1f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py @@ -10,6 +10,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, ) @@ -71,6 +72,15 @@ def __init__( shape: Optional[OutlinedBorder] = None, autofocus: Optional[bool] = None, mini: Optional[bool] = None, + foreground_color: Optional[str] = None, + focus_color: Optional[str] = None, + clip_behavior: Optional[ClipBehavior] = None, + elevation: OptionalNumber = None, + disabled_elevation: OptionalNumber = None, + focus_elevation: OptionalNumber = None, + highlight_elevation: OptionalNumber = None, + hover_elevation: OptionalNumber = None, + enable_feedback: Optional[bool] = None, url: Optional[str] = None, url_target: Optional[str] = None, on_click=None, @@ -146,6 +156,15 @@ def __init__( self.url = url self.url_target = url_target self.on_click = on_click + self.foreground_color = foreground_color + self.focus_color = focus_color + self.clip_behavior = clip_behavior + self.elevation = elevation + self.disabled_elevation = disabled_elevation + self.focus_elevation = focus_elevation + self.highlight_elevation = highlight_elevation + self.hover_elevation = hover_elevation + self.enable_feedback = enable_feedback def _get_control_name(self): return "floatingactionbutton" @@ -249,3 +268,87 @@ def mini(self) -> Optional[bool]: @mini.setter def mini(self, value: Optional[bool]): self._set_attr("mini", value) + + # elevation + @property + def elevation(self): + return self._get_attr("elevation", data_type="float") + + @elevation.setter + def elevation(self, value: OptionalNumber): + self._set_attr("elevation", value) + + # disabled_elevation + @property + def disabled_elevation(self): + return self._get_attr("disabledElevation", data_type="float") + + @disabled_elevation.setter + def disabled_elevation(self, value: OptionalNumber): + self._set_attr("disabledElevation", value) + + # enable_feedback + @property + def enable_feedback(self): + return self._get_attr("enableFeedback", data_type="bool", def_value=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + + # focus_color + @property + def focus_color(self): + return self._get_attr("focusColor") + + @focus_color.setter + def focus_color(self, value: Optional[str]): + self._set_attr("focusColor", value) + + # focus_elevation + @property + def focus_elevation(self): + return self._get_attr("focusElevation", data_type="float") + + @focus_elevation.setter + def focus_elevation(self, value: OptionalNumber): + self._set_attr("focusElevation", value) + + # foreground_color + @property + def foreground_color(self): + return self._get_attr("foregroundColor") + + @foreground_color.setter + def foreground_color(self, value: Optional[str]): + self._set_attr("foregroundColor", value) + + # highlight_elevation + @property + def highlight_elevation(self): + return self._get_attr("highlightElevation", data_type="float") + + @highlight_elevation.setter + def highlight_elevation(self, value: OptionalNumber): + self._set_attr("highlightElevation", value) + + # hover_elevation + @property + def hover_elevation(self): + return self._get_attr("hoverElevation", data_type="float") + + @hover_elevation.setter + def hover_elevation(self, value: OptionalNumber): + self._set_attr("hoverElevation", value) + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) From 6cf8e839bf9e6a79f6035f03983e1a095452545e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 07:27:43 +0100 Subject: [PATCH 032/103] ElevatedButton: clip_behavior, --- .../flet/lib/src/controls/elevated_button.dart | 10 +++++++++- .../flet-core/src/flet_core/elevated_button.py | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/elevated_button.dart b/packages/flet/lib/src/controls/elevated_button.dart index 257ccc98b..ba4567fc6 100644 --- a/packages/flet/lib/src/controls/elevated_button.dart +++ b/packages/flet/lib/src/controls/elevated_button.dart @@ -60,6 +60,7 @@ class _ElevatedButtonControlState extends State @override Widget build(BuildContext context) { debugPrint("Button build: ${widget.control.id}"); + bool disabled = widget.control.isDisabled || widget.parentDisabled; return withPagePlatform((context, platform) { bool? adaptive = @@ -90,10 +91,14 @@ class _ElevatedButtonControlState extends State Color? iconColor = HexColor.fromString( Theme.of(context), widget.control.attrString("iconColor", "")!); var contentCtrls = widget.children.where((c) => c.name == "content"); + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.none); 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 ? () { @@ -152,6 +157,7 @@ class _ElevatedButtonControlState extends State onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, + clipBehavior: clipBehavior, icon: Icon( icon, color: iconColor, @@ -165,6 +171,7 @@ class _ElevatedButtonControlState extends State onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, + clipBehavior: clipBehavior, child: createControl( widget.control, contentCtrls.first.id, disabled, parentAdaptive: adaptive)); @@ -176,6 +183,7 @@ class _ElevatedButtonControlState extends State onPressed: onPressed, onLongPress: onLongPressHandler, onHover: onHoverHandler, + clipBehavior: clipBehavior, child: Text(text)); } 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 03870c649..5172af7c7 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 @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, ) from flet_core.utils import deprecated @@ -50,7 +51,7 @@ def __init__( elevation: OptionalNumber = None, style: Optional[ButtonStyle] = None, autofocus: Optional[bool] = None, - adaptive: Optional[bool] = None, + clip_behavior: Optional[ClipBehavior] = None, url: Optional[str] = None, url_target: Optional[str] = None, on_click=None, @@ -59,7 +60,7 @@ def __init__( on_focus=None, on_blur=None, # - # ConstrainedControl + # ConstrainedControl and AdaptiveControl # ref: Optional[Ref] = None, key: Optional[str] = None, @@ -88,6 +89,7 @@ def __init__( visible: Optional[bool] = None, disabled: Optional[bool] = None, data: Any = None, + adaptive: Optional[bool] = None, ): ConstrainedControl.__init__( self, @@ -142,6 +144,7 @@ def __init__( self.on_hover = on_hover self.on_focus = on_focus self.on_blur = on_blur + self.clip_behavior = clip_behavior def _get_control_name(self): return "elevatedbutton" @@ -316,6 +319,17 @@ def autofocus(self) -> Optional[bool]: def autofocus(self, value: Optional[bool]): self._set_attr("autofocus", value) + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + # on_hover @property def on_hover(self): From a859697a12b2ba64b34f0b54ca08aca679d1d759 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:35:53 +0100 Subject: [PATCH 033/103] SnackBar: clip_behavior, shape, on_visible --- packages/flet/lib/src/controls/snack_bar.dart | 14 ++++++- .../flet-core/src/flet_core/snack_bar.py | 40 ++++++++++++++++++- 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/snack_bar.dart b/packages/flet/lib/src/controls/snack_bar.dart index 5cd8382e9..fecc4aa8d 100644 --- a/packages/flet/lib/src/controls/snack_bar.dart +++ b/packages/flet/lib/src/controls/snack_bar.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; @@ -53,6 +54,11 @@ class _SnackBarControlState extends State { widget.backend.triggerControlEvent(widget.control.id, "action"); }) : null; + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.hardEdge); SnackBarBehavior? behavior = SnackBarBehavior.values.firstWhereOrNull((a) => a.name.toLowerCase() == @@ -66,6 +72,12 @@ class _SnackBarControlState extends State { return SnackBar( behavior: behavior, + clipBehavior: clipBehavior, + shape: parseOutlinedBorder(widget.control, "shape"), + onVisible: () { + debugPrint("SnackBar.onVisible(${widget.control.id})"); + widget.backend.triggerControlEvent(widget.control.id, "visible"); + }, dismissDirection: dismissDirection, showCloseIcon: widget.control.attrBool("showCloseIcon"), closeIconColor: HexColor.fromString(Theme.of(context), @@ -87,8 +99,6 @@ class _SnackBarControlState extends State { Widget build(BuildContext context) { debugPrint("SnackBar build: ${widget.control.id}"); - debugPrint("SnackBar build: ${widget.control.id}"); - var open = widget.control.attrBool("open", false)!; var removeCurrentSnackbar = true; diff --git a/sdk/python/packages/flet-core/src/flet_core/snack_bar.py b/sdk/python/packages/flet-core/src/flet_core/snack_bar.py index 58452626a..34f403017 100644 --- a/sdk/python/packages/flet-core/src/flet_core/snack_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/snack_bar.py @@ -1,9 +1,10 @@ from enum import Enum from typing import Any, Optional +from flet_core.buttons import OutlinedBorder from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.types import MarginValue, PaddingValue +from flet_core.types import MarginValue, PaddingValue, ClipBehavior class SnackBarBehavior(Enum): @@ -75,7 +76,10 @@ def __init__( padding: PaddingValue = None, width: OptionalNumber = None, elevation: OptionalNumber = None, + shape: Optional[OutlinedBorder] = None, + clip_behavior: Optional[ClipBehavior] = None, on_action=None, + on_visible=None, # # Control # @@ -107,6 +111,9 @@ def __init__( self.duration = duration self.elevation = elevation self.on_action = on_action + self.on_visible = on_visible + self.shape = shape + self.clip_behavior = clip_behavior def _get_control_name(self): return "snackbar" @@ -120,6 +127,7 @@ def _get_children(self): def before_update(self): super().before_update() + self._set_attr_json("shape", self.__shape) self._set_attr_json("margin", self.__margin) self._set_attr_json("padding", self.__padding) @@ -257,6 +265,27 @@ def elevation(self) -> OptionalNumber: def elevation(self, value: OptionalNumber): self._set_attr("elevation", value) + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + + # shape + @property + def shape(self) -> Optional[OutlinedBorder]: + return self.__shape + + @shape.setter + def shape(self, value: Optional[OutlinedBorder]): + self.__shape = value + # on_action @property def on_action(self): @@ -265,3 +294,12 @@ def on_action(self): @on_action.setter def on_action(self, handler): self._add_event_handler("action", handler) + + # on_visible + @property + def on_visible(self): + return self._get_event_handler("visible") + + @on_visible.setter + def on_visible(self, handler): + self._add_event_handler("visible", handler) From c9bd7bac812110bdf36bf925e257870d42b586eb Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:38:11 +0100 Subject: [PATCH 034/103] Slider: interaction, overlay_color --- packages/flet/lib/src/controls/slider.dart | 10 +++++ .../flet-core/src/flet_core/__init__.py | 2 +- .../flet-core/src/flet_core/slider.py | 40 ++++++++++++++++++- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/slider.dart b/packages/flet/lib/src/controls/slider.dart index 1040eebd7..bd796083c 100644 --- a/packages/flet/lib/src/controls/slider.dart +++ b/packages/flet/lib/src/controls/slider.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; @@ -90,6 +91,13 @@ class _SliderControlState extends State with FletStoreMixin { int? divisions = widget.control.attrInt("divisions"); int round = widget.control.attrInt("round", 0)!; + var interaction = SliderInteraction.values.firstWhereOrNull((e) => + e.name.toLowerCase() == + widget.control.attrString("interaction", "")!.toLowerCase()); + + var overlayColor = parseMaterialStateColor( + Theme.of(context), widget.control, "overlayColor"); + debugPrint("SliderControl build: ${widget.control.id}"); double value = widget.control.attrDouble("value", 0)!; @@ -116,6 +124,8 @@ class _SliderControlState extends State with FletStoreMixin { Theme.of(context), widget.control.attrString("activeColor", "")!), inactiveColor: HexColor.fromString(Theme.of(context), widget.control.attrString("inactiveColor", "")!), + overlayColor: overlayColor, + allowedInteraction: interaction, thumbColor: HexColor.fromString( Theme.of(context), widget.control.attrString("thumbColor", "")!), onChanged: !disabled diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index b606c3a03..a4500dadd 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -220,7 +220,7 @@ from flet_core.shader_mask import ShaderMask from flet_core.shadow import BoxShadow, ShadowBlurStyle from flet_core.shake_detector import ShakeDetector -from flet_core.slider import Slider +from flet_core.slider import Slider, SliderInteraction from flet_core.snack_bar import DismissDirection, SnackBar, SnackBarBehavior from flet_core.stack import Stack, StackFit from flet_core.submenu_button import SubmenuButton diff --git a/sdk/python/packages/flet-core/src/flet_core/slider.py b/sdk/python/packages/flet-core/src/flet_core/slider.py index 55aa8a218..c2012aee4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/slider.py +++ b/sdk/python/packages/flet-core/src/flet_core/slider.py @@ -1,4 +1,4 @@ -from typing import Any, Optional, Union +from typing import Any, Optional, Union, Dict from flet_core.adaptive_control import AdaptiveControl from flet_core.constrained_control import ConstrainedControl @@ -6,6 +6,7 @@ from flet_core.ref import Ref from flet_core.types import ( AnimationValue, + MaterialState, OffsetValue, ResponsiveNumber, RotateValue, @@ -13,6 +14,13 @@ ) +class SliderInteraction(Enum): + TAP_AND_SLIDE = "tapAndSlide" + TAP_ONLY = "tapOnly" + SLIDE_ONLY = "slideOnly" + SLIDE_THUMB = "slideThumb" + + class Slider(ConstrainedControl, AdaptiveControl): """ A slider provides a visual indication of adjustable content, as well as the current setting in the total range of content. @@ -50,6 +58,8 @@ def __init__( active_color: Optional[str] = None, inactive_color: Optional[str] = None, thumb_color: Optional[str] = None, + interaction: Optional[SliderInteraction] = None, + overlay_color: Union[None, str, Dict[MaterialState, str]] = None, on_change=None, on_change_start=None, on_change_end=None, @@ -130,6 +140,8 @@ def __init__( self.active_color = active_color self.inactive_color = inactive_color self.thumb_color = thumb_color + self.interaction = interaction + self.overlay_color = overlay_color self.on_change = on_change self.on_change_start = on_change_start self.on_change_end = on_change_end @@ -139,6 +151,10 @@ def __init__( def _get_control_name(self): return "slider" + def before_update(self): + super().before_update() + self._set_attr_json("overlayColor", self.__overlay_color) + # value @property def value(self) -> OptionalNumber: @@ -163,6 +179,19 @@ def label(self): def label(self, value): self._set_attr("label", value) + # interaction + @property + def interaction(self) -> Optional[SliderInteraction]: + return self.__interaction + + @interaction.setter + def interaction(self, value: Optional[SliderInteraction]): + self.__interaction = value + self._set_attr( + "interaction", + value.value if isinstance(value, SliderInteraction) else value, + ) + # min @property def min(self) -> OptionalNumber: @@ -199,6 +228,15 @@ def round(self) -> Optional[int]: def round(self, value: Optional[int]): self._set_attr("round", value) + # overlay_color + @property + def overlay_color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__overlay_color + + @overlay_color.setter + def overlay_color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__overlay_color = value + # autofocus @property def autofocus(self) -> Optional[bool]: From 092fdf8be55f75a2d8b240c47b97355965fdc99f Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:40:02 +0100 Subject: [PATCH 035/103] IconButton: alignment, disabled_color, enable_feedback, hover_color, padding --- .../flet/lib/src/controls/icon_button.dart | 30 ++++++ .../flet-core/src/flet_core/icon_button.py | 96 ++++++++++++++++++- 2 files changed, 124 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/icon_button.dart b/packages/flet/lib/src/controls/icon_button.dart index 5bc2a1f73..d2297da31 100644 --- a/packages/flet/lib/src/controls/icon_button.dart +++ b/packages/flet/lib/src/controls/icon_button.dart @@ -2,8 +2,10 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/alignment.dart'; import '../utils/buttons.dart'; import '../utils/colors.dart'; +import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -85,10 +87,22 @@ class _IconButtonControlState extends State widget.control.attrString("selectedIconColor", "")!); Color? bgColor = HexColor.fromString( Theme.of(context), widget.control.attrString("bgColor", "")!); + Color? disabledColor = HexColor.fromString( + Theme.of(context), widget.control.attrString("disabledColor", "")!); + Color? hoverColor = HexColor.fromString( + Theme.of(context), widget.control.attrString("hoverColor", "")!); + Color? splashColor = HexColor.fromString( + Theme.of(context), widget.control.attrString("splashColor", "")!); + Color? focusColor = HexColor.fromString( + Theme.of(context), widget.control.attrString("focusColor", "")!); double? iconSize = widget.control.attrDouble("iconSize"); + double? splashRadius = widget.control.attrDouble("splashRadius"); + var padding = parseEdgeInsets(widget.control, "padding"); + var alignment = parseAlignment(widget.control, "alignment"); var tooltip = widget.control.attrString("tooltip"); var contentCtrls = widget.children.where((c) => c.name == "content"); bool autofocus = widget.control.attrBool("autofocus", false)!; + bool enableFeedback = widget.control.attrBool("enableFeedback", true)!; bool selected = widget.control.attrBool("selected", false)!; String url = widget.control.attrString("url", "")!; String? urlTarget = widget.control.attrString("urlTarget"); @@ -126,6 +140,14 @@ class _IconButtonControlState extends State autofocus: autofocus, focusNode: _focusNode, highlightColor: highlightColor, + disabledColor: highlightColor, + hoverColor: highlightColor, + enableFeedback: enableFeedback, + padding: padding, + alignment: alignment, + focusColor: focusColor, + splashColor: splashColor, + splashRadius: splashRadius, icon: Icon( icon, color: iconColor, @@ -143,6 +165,14 @@ class _IconButtonControlState extends State autofocus: autofocus, focusNode: _focusNode, highlightColor: highlightColor, + disabledColor: highlightColor, + hoverColor: highlightColor, + enableFeedback: enableFeedback, + padding: padding, + alignment: alignment, + focusColor: focusColor, + splashColor: splashColor, + splashRadius: splashRadius, onPressed: onPressed, iconSize: iconSize, style: style, diff --git a/sdk/python/packages/flet-core/src/flet_core/icon_button.py b/sdk/python/packages/flet-core/src/flet_core/icon_button.py index 8dc6be178..6fb159220 100644 --- a/sdk/python/packages/flet-core/src/flet_core/icon_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/icon_button.py @@ -2,6 +2,7 @@ from typing import Any, Optional, Union from flet_core.adaptive_control import AdaptiveControl +from flet_core.alignment import Alignment from flet_core.buttons import ButtonStyle from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber @@ -12,6 +13,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + PaddingValue, ) from flet_core.utils import deprecated @@ -68,6 +70,14 @@ def __init__( style: Optional[ButtonStyle] = None, content: Optional[Control] = None, autofocus: Optional[bool] = None, + disabled_color: Optional[str] = None, + hover_color: Optional[str] = None, + focus_color: Optional[str] = None, + splash_color: Optional[str] = None, + splash_radius: OptionalNumber = None, + alignment: Optional[Alignment] = None, + padding: PaddingValue = None, + enable_feedback: Optional[bool] = None, url: Optional[str] = None, url_target: Optional[str] = None, on_click=None, @@ -148,6 +158,14 @@ def __init__( self.style = style self.content = content self.autofocus = autofocus + self.disabled_color = disabled_color + self.hover_color = hover_color + self.alignment = alignment + self.padding = padding + self.enable_feedback = enable_feedback + self.splash_color = splash_color + self.splash_radius = splash_radius + self.focus_color = focus_color self.url = url self.url_target = url_target self.on_click = on_click @@ -164,6 +182,8 @@ def before_update(self): self.__style.shape = self._wrap_attr_dict(self.__style.shape) self.__style.padding = self._wrap_attr_dict(self.__style.padding) self._set_attr_json("style", self.__style) + self._set_attr_json("alignment", self.__alignment) + self._set_attr_json("padding", self.__padding) def _get_children(self): if self.__content is None: @@ -207,16 +227,34 @@ def icon_size(self): return self._get_attr("iconSize") @icon_size.setter - def icon_size(self, value): + def icon_size(self, value: OptionalNumber): self._set_attr("iconSize", value) + # splash_radius + @property + def splash_radius(self): + return self._get_attr("splashRadius") + + @splash_radius.setter + def splash_radius(self, value: OptionalNumber): + self._set_attr("splashRadius", value) + + # splash_color + @property + def splash_color(self): + return self._get_attr("splashColor") + + @splash_color.setter + def splash_color(self, value: Optional[str]): + self._set_attr("splashColor", value) + # icon_color @property def icon_color(self): return self._get_attr("iconColor") @icon_color.setter - def icon_color(self, value): + def icon_color(self, value: Optional[str]): self._set_attr("iconColor", value) # highlight_color @@ -246,6 +284,42 @@ def bgcolor(self): def bgcolor(self, value): self._set_attr("bgcolor", value) + # hover_color + @property + def hover_color(self): + return self._get_attr("hoverColor") + + @hover_color.setter + def hover_color(self, value: Optional[str]): + self._set_attr("hoverColor", value) + + # focus_color + @property + def focus_color(self): + return self._get_attr("focusColor") + + @focus_color.setter + def focus_color(self, value: Optional[str]): + self._set_attr("focusColor", value) + + # disabled_color + @property + def disabled_color(self): + return self._get_attr("disabledColor") + + @disabled_color.setter + def disabled_color(self, value: Optional[str]): + self._set_attr("disabledColor", value) + + # padding + @property + def padding(self) -> PaddingValue: + return self.__padding + + @padding.setter + def padding(self, value: PaddingValue): + self.__padding = value + # selected @property def selected(self) -> Optional[bool]: @@ -255,6 +329,15 @@ def selected(self) -> Optional[bool]: def selected(self, value: Optional[bool]): self._set_attr("selected", value) + # enable_feedback + @property + def enable_feedback(self) -> Optional[bool]: + return self._get_attr("enableFeedback", data_type="bool", def_value=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + # style @property def style(self) -> Optional[ButtonStyle]: @@ -326,3 +409,12 @@ def on_blur(self): @on_blur.setter def on_blur(self, handler): self._add_event_handler("blur", handler) + + # alignment + @property + def alignment(self) -> Optional[Alignment]: + return self.__alignment + + @alignment.setter + def alignment(self, value: Optional[Alignment]): + self.__alignment = value From 04c2d6ff4f9e5db9a39f1c74b14b6ed888c910cd Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:42:24 +0100 Subject: [PATCH 036/103] Radio: focus_color, hover_color, overlay_color, splash_radius, toggleable, visual_density --- packages/flet/lib/src/controls/radio.dart | 12 ++++ .../packages/flet-core/src/flet_core/radio.py | 66 ++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/radio.dart b/packages/flet/lib/src/controls/radio.dart index 3009ffd1a..71321a3d0 100644 --- a/packages/flet/lib/src/controls/radio.dart +++ b/packages/flet/lib/src/controls/radio.dart @@ -1,3 +1,4 @@ +import 'package:flet/src/utils/theme.dart'; import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; @@ -83,6 +84,8 @@ class _RadioControlState extends State with FletStoreMixin { p.name.toLowerCase() == widget.control.attrString("labelPosition", "")!.toLowerCase(), orElse: () => LabelPosition.right); + VisualDensity? visualDensity = + parseVisualDensity(widget.control.attrString("visualDensity"), null); bool autofocus = widget.control.attrBool("autofocus", false)!; bool disabled = widget.control.isDisabled || widget.parentDisabled; @@ -111,8 +114,17 @@ class _RadioControlState extends State with FletStoreMixin { value: value, activeColor: HexColor.fromString(Theme.of(context), widget.control.attrString("activeColor", "")!), + focusColor: HexColor.fromString(Theme.of(context), + widget.control.attrString("activeColor", "")!), + hoverColor: HexColor.fromString(Theme.of(context), + widget.control.attrString("activeColor", "")!), + splashRadius: widget.control.attrDouble("splashRadius"), + toggleable: widget.control.attrBool("toggleable", false)!, fillColor: parseMaterialStateColor( Theme.of(context), widget.control, "fillColor"), + overlayColor: parseMaterialStateColor( + Theme.of(context), widget.control, "overlayColor"), + visualDensity: visualDensity, onChanged: !disabled ? (String? value) { _onChange(ancestorId, value); diff --git a/sdk/python/packages/flet-core/src/flet_core/radio.py b/sdk/python/packages/flet-core/src/flet_core/radio.py index fd606db8d..5e59260ba 100644 --- a/sdk/python/packages/flet-core/src/flet_core/radio.py +++ b/sdk/python/packages/flet-core/src/flet_core/radio.py @@ -1,4 +1,3 @@ -import dataclasses from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -6,6 +5,7 @@ from flet_core.control import OptionalNumber from flet_core.ref import Ref from flet_core.text_style import TextStyle +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, LabelPosition, @@ -61,6 +61,12 @@ def __init__( autofocus: Optional[bool] = None, fill_color: Union[None, str, Dict[MaterialState, str]] = None, active_color: Optional[str] = None, + overlay_color: Union[None, str, Dict[MaterialState, str]] = None, + hover_color: Optional[str] = None, + focus_color: Optional[str] = None, + splash_radius: OptionalNumber = None, + toggleable: Optional[bool] = None, + visual_density: Optional[ThemeVisualDensity] = None, on_focus=None, on_blur=None, # @@ -137,6 +143,12 @@ def __init__( self.active_color = active_color self.on_focus = on_focus self.on_blur = on_blur + self.overlay_color = overlay_color + self.hover_color = hover_color + self.focus_color = focus_color + self.splash_radius = splash_radius + self.toggleable = toggleable + self.visual_density = visual_density def _get_control_name(self): return "radio" @@ -144,7 +156,8 @@ def _get_control_name(self): def before_update(self): super().before_update() self._set_attr_json("fillColor", self.__fill_color) - if dataclasses.is_dataclass(self.__label_style): + self._set_attr_json("overlayColor", self.__overlay_color) + if isinstance(self.__label_style, TextStyle): self._set_attr_json("labelStyle", self.__label_style) # value @@ -165,6 +178,46 @@ def active_color(self) -> Optional[str]: def active_color(self, value: Optional[str]): self._set_attr("activeColor", value) + # focus_color + @property + def focus_color(self) -> Optional[str]: + return self._get_attr("focusColor") + + @focus_color.setter + def focus_color(self, value: Optional[str]): + self._set_attr("focusColor", value) + + # splash_radius + @property + def splash_radius(self) -> OptionalNumber: + return self._get_attr("splashRadius", data_type="float") + + @splash_radius.setter + def splash_radius(self, value: OptionalNumber): + self._set_attr("splashRadius", value) + + # toggleable + @property + def toggleable(self) -> Optional[bool]: + return self._get_attr("toggleable", data_type="bool", def_value=False) + + @toggleable.setter + def toggleable(self, value: Optional[bool]): + self._set_attr("toggleable", value) + + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + # label @property def label(self): @@ -204,6 +257,15 @@ def fill_color(self) -> Union[None, str, Dict[MaterialState, str]]: def fill_color(self, value: Union[None, str, Dict[MaterialState, str]]): self.__fill_color = value + # overlay_color + @property + def overlay_color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__overlay_color + + @overlay_color.setter + def overlay_color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__overlay_color = value + # on_focus @property def on_focus(self): From 00d541fab9a89af4ff16f3e4ee4de423eb528db2 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:43:48 +0100 Subject: [PATCH 037/103] GridView: semantic_child_count, clipBehavior --- packages/flet/lib/src/controls/grid_view.dart | 8 ++++++ .../flet-core/src/flet_core/grid_view.py | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/packages/flet/lib/src/controls/grid_view.dart b/packages/flet/lib/src/controls/grid_view.dart index f007a6a5a..ed3fa8aaf 100644 --- a/packages/flet/lib/src/controls/grid_view.dart +++ b/packages/flet/lib/src/controls/grid_view.dart @@ -58,10 +58,16 @@ class _GridViewControlState extends State { final runsCount = widget.control.attrInt("runsCount", 1)!; final maxExtent = widget.control.attrDouble("maxExtent"); final spacing = widget.control.attrDouble("spacing", 10)!; + final semanticChildCount = widget.control.attrInt("semanticChildCount"); final runSpacing = widget.control.attrDouble("runSpacing", 10)!; final padding = parseEdgeInsets(widget.control, "padding"); final childAspectRatio = widget.control.attrDouble("childAspectRatio", 1)!; final reverse = widget.control.attrBool("reverse", false)!; + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.hardEdge); List visibleControls = widget.children.where((c) => c.isVisible).toList(); @@ -90,7 +96,9 @@ class _GridViewControlState extends State { Widget child = GridView.builder( scrollDirection: horizontal ? Axis.horizontal : Axis.vertical, controller: _controller, + clipBehavior: clipBehavior, reverse: reverse, + semanticChildCount: semanticChildCount, shrinkWrap: shrinkWrap, padding: padding, gridDelegate: gridDelegate, diff --git a/sdk/python/packages/flet-core/src/flet_core/grid_view.py b/sdk/python/packages/flet-core/src/flet_core/grid_view.py index 2e0ecab0c..f6e6932de 100644 --- a/sdk/python/packages/flet-core/src/flet_core/grid_view.py +++ b/sdk/python/packages/flet-core/src/flet_core/grid_view.py @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, ) from flet_core.utils import deprecated @@ -73,6 +74,8 @@ def __init__( run_spacing: OptionalNumber = None, child_aspect_ratio: OptionalNumber = None, padding: PaddingValue = None, + clip_behavior: Optional[ClipBehavior] = None, + semantic_child_count: Optional[int] = None, # # ConstrainedControl # @@ -163,6 +166,8 @@ def __init__( self.run_spacing = run_spacing self.child_aspect_ratio = child_aspect_ratio self.padding = padding + self.clip_behavior = clip_behavior + self.semantic_child_count = semantic_child_count def _get_control_name(self): return "gridview" @@ -257,3 +262,23 @@ def controls(self): @controls.setter def controls(self, value): self.__controls = value if value is not None else [] + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + + # semantic_child_count + @property + def semantic_child_count(self) -> Optional[int]: + return self._get_attr("semanticChildCount", data_type="int") + + @semantic_child_count.setter + def semantic_child_count(self, value: Optional[int]): + self._set_attr("semanticChildCount", value) From f1083a33448e1cdf5eaad2b03bef2ec157bb0c55 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:48:47 +0100 Subject: [PATCH 038/103] Tabs: divider_height, enable_feedback, indicator_thickness --- packages/flet/lib/src/controls/tabs.dart | 16 ++-- .../packages/flet-core/src/flet_core/tabs.py | 81 +++++++++++++------ 2 files changed, 65 insertions(+), 32 deletions(-) diff --git a/packages/flet/lib/src/controls/tabs.dart b/packages/flet/lib/src/controls/tabs.dart index 30b992611..a29f08ac6 100644 --- a/packages/flet/lib/src/controls/tabs.dart +++ b/packages/flet/lib/src/controls/tabs.dart @@ -143,9 +143,12 @@ class _TabsControlState extends State tabAlignment: tabAlignment, controller: _tabController, isScrollable: isScrollable, - dividerColor: - HexColor.fromString(Theme.of(context), widget.control.attrString("dividerColor", "")!) ?? - TabBarTheme.of(context).dividerColor, + dividerHeight: widget.control.attrDouble("dividerHeight"), + enableFeedback: widget.control.attrBool("enableFeedback"), + indicatorWeight: + widget.control.attrDouble("indicatorThickness", 2.0)!, + dividerColor: HexColor.fromString(Theme.of(context), widget.control.attrString("dividerColor", "")!) ?? + TabBarTheme.of(context).dividerColor, indicatorSize: indicatorTabSize != null ? (indicatorTabSize ? TabBarIndicatorSize.tab @@ -174,10 +177,9 @@ class _TabsControlState extends State labelColor: HexColor.fromString(Theme.of(context), widget.control.attrString("labelColor", "")!) ?? TabBarTheme.of(context).labelColor ?? Theme.of(context).colorScheme.primary, - unselectedLabelColor: - HexColor.fromString(Theme.of(context), widget.control.attrString("unselectedLabelColor", "")!) ?? - TabBarTheme.of(context).unselectedLabelColor ?? - Theme.of(context).colorScheme.onSurface, + unselectedLabelColor: HexColor.fromString(Theme.of(context), widget.control.attrString("unselectedLabelColor", "")!) ?? + TabBarTheme.of(context).unselectedLabelColor ?? + Theme.of(context).colorScheme.onSurface, overlayColor: getMaterialStateProperty( overlayColor, (jv) => HexColor.fromString(Theme.of(context), jv as String), null) ?? TabBarTheme.of(context).overlayColor, diff --git a/sdk/python/packages/flet-core/src/flet_core/tabs.py b/sdk/python/packages/flet-core/src/flet_core/tabs.py index 74db8b732..7b6fba337 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tabs.py +++ b/sdk/python/packages/flet-core/src/flet_core/tabs.py @@ -61,7 +61,7 @@ def text(self): return self._get_attr("text") @text.setter - def text(self, value): + def text(self, value: Optional[str]): self._set_attr("text", value) # icon @@ -70,7 +70,7 @@ def icon(self): return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) # tab_content @@ -79,7 +79,7 @@ def tab_content(self): return self.__tab_content @tab_content.setter - def tab_content(self, value): + def tab_content(self, value: Optional[Control]): self.__tab_content = value # content @@ -88,7 +88,7 @@ def content(self): return self.__content @content.setter - def content(self, value): + def content(self, value: Optional[Control]): self.__content = value @@ -140,6 +140,27 @@ def main(page: ft.Page): def __init__( self, + tabs: Optional[List[Tab]] = None, + selected_index: Optional[int] = None, + scrollable: Optional[bool] = None, + tab_alignment: Optional[TabAlignment] = None, + animation_duration: Optional[int] = None, + divider_color: Optional[str] = None, + indicator_color: Optional[str] = None, + indicator_border_radius: BorderRadiusValue = None, + indicator_border_side: Optional[BorderSide] = None, + indicator_padding: PaddingValue = None, + indicator_tab_size: Optional[bool] = None, + label_color: Optional[str] = None, + unselected_label_color: Optional[str] = None, + overlay_color: Union[None, str, Dict[MaterialState, str]] = None, + divider_height: OptionalNumber = None, + indicator_thickness: OptionalNumber = None, + enable_feedback: Optional[str] = None, + on_change=None, + # + # ConstrainedControl and AdaptiveControl + # ref: Optional[Ref] = None, key: Optional[str] = None, width: OptionalNumber = None, @@ -166,26 +187,6 @@ def __init__( visible: Optional[bool] = None, disabled: Optional[bool] = None, data: Any = None, - # - # Tabs-specific - tabs: Optional[List[Tab]] = None, - selected_index: Optional[int] = None, - scrollable: Optional[bool] = None, - tab_alignment: Optional[TabAlignment] = None, - animation_duration: Optional[int] = None, - divider_color: Optional[str] = None, - indicator_color: Optional[str] = None, - indicator_border_radius: BorderRadiusValue = None, - indicator_border_side: Optional[BorderSide] = None, - indicator_padding: PaddingValue = None, - indicator_tab_size: Optional[bool] = None, - label_color: Optional[str] = None, - unselected_label_color: Optional[str] = None, - overlay_color: Union[None, str, Dict[MaterialState, str]] = None, - on_change=None, - # - # Adaptive - # adaptive: Optional[bool] = None, ): ConstrainedControl.__init__( @@ -235,6 +236,9 @@ def __init__( self.indicator_tab_size = indicator_tab_size self.overlay_color = overlay_color self.on_change = on_change + self.divider_height = divider_height + self.indicator_thickness = indicator_thickness + self.enable_feedback = enable_feedback def _get_control_name(self): return "tabs" @@ -300,12 +304,39 @@ def tab_alignment(self, value: Optional[TabAlignment]): # animation_duration @property def animation_duration(self) -> Optional[int]: - return self._get_attr("animationDuration") + return self._get_attr("animationDuration", data_type="int") @animation_duration.setter def animation_duration(self, value: Optional[int]): self._set_attr("animationDuration", value) + # divider_height + @property + def divider_height(self): + return self._get_attr("dividerHeight", data_type="float", def_value=1.0) + + @divider_height.setter + def divider_height(self, value: OptionalNumber): + self._set_attr("dividerHeight", value) + + # enable_feedback + @property + def enable_feedback(self): + return self._get_attr("enableFeedback") + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + + # indicator_thickness + @property + def indicator_thickness(self): + return self._get_attr("indicatorThickness", data_type="float", def_value=3.0) + + @indicator_thickness.setter + def indicator_thickness(self, value: OptionalNumber): + self._set_attr("indicatorThickness", value) + # divider_color @property def divider_color(self) -> Optional[str]: From ea6feccc34a28ebb0c033d2eb4f3ca0f6e7d7831 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 16:50:42 +0100 Subject: [PATCH 039/103] Cleanup + Code Reformat --- .../flet/lib/src/controls/create_control.dart | 3 +- packages/flet/lib/src/utils/theme.dart | 5 +- packages/flet_video/lib/src/video.dart | 8 ++- .../flet-core/src/flet_core/container.py | 61 +++++++++---------- .../packages/flet-core/src/flet_core/theme.py | 3 +- 5 files changed, 41 insertions(+), 39 deletions(-) diff --git a/packages/flet/lib/src/controls/create_control.dart b/packages/flet/lib/src/controls/create_control.dart index 77003934a..b500cc768 100644 --- a/packages/flet/lib/src/controls/create_control.dart +++ b/packages/flet/lib/src/controls/create_control.dart @@ -269,7 +269,8 @@ Widget createWidget( control: controlView.control, children: controlView.children, parentDisabled: parentDisabled, - parentAdaptive: parentAdaptive); + parentAdaptive: parentAdaptive, + backend: backend); case "hapticfeedback": return HapticFeedbackControl( parent: parent, diff --git a/packages/flet/lib/src/utils/theme.dart b/packages/flet/lib/src/utils/theme.dart index 6a439fd15..ead05a5b1 100644 --- a/packages/flet/lib/src/utils/theme.dart +++ b/packages/flet/lib/src/utils/theme.dart @@ -249,7 +249,8 @@ TabBarTheme? parseTabBarTheme(ThemeData theme, Map? j) { ); } -VisualDensity parseVisualDensity(String? vd) { +VisualDensity? parseVisualDensity(String? vd, + [VisualDensity? defValue = VisualDensity.standard]) { switch (vd?.toLowerCase()) { case "adaptiveplatformdensity": return VisualDensity.adaptivePlatformDensity; @@ -258,7 +259,7 @@ VisualDensity parseVisualDensity(String? vd) { case "compact": return VisualDensity.compact; default: - return VisualDensity.standard; + return defValue; } } diff --git a/packages/flet_video/lib/src/video.dart b/packages/flet_video/lib/src/video.dart index 38b42691a..cf6834f3a 100644 --- a/packages/flet_video/lib/src/video.dart +++ b/packages/flet_video/lib/src/video.dart @@ -63,9 +63,11 @@ class _VideoControlState extends State with FletStoreMixin { Widget build(BuildContext context) { debugPrint("Video build: ${widget.control.id}"); - FilterQuality filterQuality = FilterQuality.values.firstWhere((e) => - e.name.toLowerCase() == - widget.control.attrString("filterQuality", "low")!.toLowerCase()); + FilterQuality filterQuality = FilterQuality.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("filterQuality", "")!.toLowerCase(), + orElse: () => FilterQuality.low); return withPageArgs((context, pageArgs) { SubtitleTrack? subtitleTrack; diff --git a/sdk/python/packages/flet-core/src/flet_core/container.py b/sdk/python/packages/flet-core/src/flet_core/container.py index 16e885b4f..ebb8567e1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/container.py +++ b/sdk/python/packages/flet-core/src/flet_core/container.py @@ -61,37 +61,6 @@ def main(page: ft.Page): def __init__( self, content: Optional[Control] = None, - ref: Optional[Ref] = None, - key: Optional[str] = None, - width: OptionalNumber = None, - height: OptionalNumber = None, - left: OptionalNumber = None, - top: OptionalNumber = None, - right: OptionalNumber = None, - bottom: OptionalNumber = None, - expand: Union[None, bool, int] = None, - expand_loose: Optional[bool] = None, - col: Optional[ResponsiveNumber] = None, - opacity: OptionalNumber = None, - rotate: RotateValue = None, - scale: ScaleValue = None, - offset: OffsetValue = None, - aspect_ratio: OptionalNumber = None, - animate_opacity: AnimationValue = None, - animate_size: AnimationValue = None, - animate_position: AnimationValue = None, - animate_rotation: AnimationValue = None, - animate_scale: AnimationValue = None, - animate_offset: AnimationValue = None, - on_animation_end=None, - tooltip: Optional[str] = None, - visible: Optional[bool] = None, - disabled: Optional[bool] = None, - data: Any = None, - rtl: Optional[bool] = None, - # - # Specific - # padding: PaddingValue = None, margin: MarginValue = None, alignment: Optional[Alignment] = None, @@ -122,8 +91,36 @@ def __init__( on_long_press=None, on_hover=None, # - # Adaptive + # ConstrainedControl and AdaptiveControl # + ref: Optional[Ref] = None, + key: Optional[str] = None, + width: OptionalNumber = None, + height: OptionalNumber = None, + left: OptionalNumber = None, + top: OptionalNumber = None, + right: OptionalNumber = None, + bottom: OptionalNumber = None, + expand: Union[None, bool, int] = None, + expand_loose: Optional[bool] = None, + col: Optional[ResponsiveNumber] = None, + opacity: OptionalNumber = None, + rotate: RotateValue = None, + scale: ScaleValue = None, + offset: OffsetValue = None, + aspect_ratio: OptionalNumber = None, + animate_opacity: AnimationValue = None, + animate_size: AnimationValue = None, + animate_position: AnimationValue = None, + animate_rotation: AnimationValue = None, + animate_scale: AnimationValue = None, + animate_offset: AnimationValue = None, + on_animation_end=None, + tooltip: Optional[str] = None, + visible: Optional[bool] = None, + disabled: Optional[bool] = None, + data: Any = None, + rtl: Optional[bool] = None, adaptive: Optional[bool] = None, ): ConstrainedControl.__init__( diff --git a/sdk/python/packages/flet-core/src/flet_core/theme.py b/sdk/python/packages/flet-core/src/flet_core/theme.py index 2af36bc9c..4b022fe5f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/theme.py +++ b/sdk/python/packages/flet-core/src/flet_core/theme.py @@ -23,7 +23,8 @@ class ThemeVisualDensityDeprecated(EnumMeta): def __getattribute__(self, item): if item == "ADAPTIVEPLATFORMDENSITY": warn( - "ADAPTIVEPLATFORMDENSITY is deprecated, use ADAPTIVE_PLATFORM_DENSITY instead.", + "ADAPTIVEPLATFORMDENSITY is deprecated and will be removed in v1.0. " + "Use ADAPTIVE_PLATFORM_DENSITY instead.", DeprecationWarning, stacklevel=2, ) From 1159733a802ce0710876071e5ef8d6aca7a37543 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 20:51:57 +0100 Subject: [PATCH 040/103] Fix CI: import enum --- sdk/python/packages/flet-core/src/flet_core/slider.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/python/packages/flet-core/src/flet_core/slider.py b/sdk/python/packages/flet-core/src/flet_core/slider.py index c2012aee4..29878c361 100644 --- a/sdk/python/packages/flet-core/src/flet_core/slider.py +++ b/sdk/python/packages/flet-core/src/flet_core/slider.py @@ -1,3 +1,4 @@ +from enum import Enum from typing import Any, Optional, Union, Dict from flet_core.adaptive_control import AdaptiveControl From aa82183256ceeb6f206bbba92d887a53df02023b Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 20:52:58 +0100 Subject: [PATCH 041/103] Reformat: replace is_dataclass with isinstance --- sdk/python/packages/flet-core/src/flet_core/checkbox.py | 5 ++--- sdk/python/packages/flet-core/src/flet_core/switch.py | 3 +-- sdk/python/packages/flet-core/src/flet_core/text.py | 5 +---- sdk/python/packages/flet-core/src/flet_core/video.py | 2 +- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index 52c899c9b..b3df740eb 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -1,4 +1,3 @@ -import dataclasses from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -169,9 +168,9 @@ def before_update(self): self._set_attr_json("fillColor", self.__fill_color) self._set_attr_json("overlayColor", self.__overlay_color) self._set_attr_json("shape", self.__shape) - if dataclasses.is_dataclass(self.__label_style): + if isinstance(self.__label_style, TextStyle): self._set_attr_json("labelStyle", self.__label_style) - if dataclasses.is_dataclass(self.__border_side): + if isinstance(self.__border_side, BorderSide): self._set_attr_json("borderSide", self.__border_side) # value diff --git a/sdk/python/packages/flet-core/src/flet_core/switch.py b/sdk/python/packages/flet-core/src/flet_core/switch.py index f3acfcf70..efc8bc80f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/switch.py +++ b/sdk/python/packages/flet-core/src/flet_core/switch.py @@ -1,4 +1,3 @@ -import dataclasses from typing import Any, Dict, Optional, Union from flet_core.adaptive_control import AdaptiveControl @@ -159,7 +158,7 @@ def before_update(self): self._set_attr_json("thumbColor", self.__thumb_color) self._set_attr_json("thumbIcon", self.__thumb_icon) self._set_attr_json("trackColor", self.__track_color) - if dataclasses.is_dataclass(self.__label_style): + if isinstance(self.__label_style, TextStyle): self._set_attr_json("labelStyle", self.__label_style) # value diff --git a/sdk/python/packages/flet-core/src/flet_core/text.py b/sdk/python/packages/flet-core/src/flet_core/text.py index 3b78f6b0d..77efc8ae7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/text.py +++ b/sdk/python/packages/flet-core/src/flet_core/text.py @@ -1,4 +1,3 @@ -import dataclasses from enum import Enum from typing import Any, List, Optional, Union from warnings import warn @@ -23,8 +22,6 @@ except ImportError: from typing_extensions import Literal -TextOverflowString = Literal[None, "clip", "ellipsis", "fade", "visible"] - class TextOverflow(Enum): NONE = None @@ -190,7 +187,7 @@ def _get_children(self): def before_update(self): super().before_update() - if dataclasses.is_dataclass(self.__style): + if isinstance(self.__style, TextStyle): self._set_attr_json("style", self.__style) # value diff --git a/sdk/python/packages/flet-core/src/flet_core/video.py b/sdk/python/packages/flet-core/src/flet_core/video.py index 0f975ea51..1383c8802 100644 --- a/sdk/python/packages/flet-core/src/flet_core/video.py +++ b/sdk/python/packages/flet-core/src/flet_core/video.py @@ -175,7 +175,7 @@ def before_update(self): super().before_update() self._set_attr_json("alignment", self.__alignment) self._set_attr_json("playlist", self.__playlist if self.__playlist else None) - if dataclasses.is_dataclass(self.__subtitle_configuration): + if isinstance(self.__subtitle_configuration, VideoSubtitleConfiguration): self._set_attr_json("subtitleConfiguration", self.__subtitle_configuration) def play(self): From 8ca57bf019656ec8a2b9fe71e867dc17e87db67e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 20:54:14 +0100 Subject: [PATCH 042/103] add kwargs in run_task --- sdk/python/packages/flet-core/src/flet_core/page.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/page.py b/sdk/python/packages/flet-core/src/flet_core/page.py index a71024195..182246f34 100644 --- a/sdk/python/packages/flet-core/src/flet_core/page.py +++ b/sdk/python/packages/flet-core/src/flet_core/page.py @@ -22,13 +22,10 @@ from flet_core.connection import Connection from flet_core.control import Control, OptionalNumber from flet_core.control_event import ControlEvent -from flet_core.cupertino_action_sheet import CupertinoActionSheet from flet_core.cupertino_alert_dialog import CupertinoAlertDialog from flet_core.cupertino_app_bar import CupertinoAppBar from flet_core.cupertino_bottom_sheet import CupertinoBottomSheet from flet_core.cupertino_navigation_bar import CupertinoNavigationBar -from flet_core.cupertino_picker import CupertinoPicker -from flet_core.cupertino_timer_picker import CupertinoTimerPicker from flet_core.event import Event from flet_core.event_handler import EventHandler from flet_core.floating_action_button import FloatingActionButton @@ -481,9 +478,9 @@ def __on_page_change_event(self, data): if name != "i": self._index[id]._set_attr(name, props[name], dirty=False) - def run_task(self, handler: Callable[..., Awaitable[Any]], *args): + def run_task(self, handler: Callable[..., Awaitable[Any]], *args, **kwargs): assert asyncio.iscoroutinefunction(handler) - return asyncio.run_coroutine_threadsafe(handler(*args), self.__loop) + return asyncio.run_coroutine_threadsafe(handler(*args, **kwargs), self.__loop) def run_thread(self, handler, *args): if is_pyodide(): From c973ef2b94049ad1a10a779b090343d49e377da3 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 22:04:51 +0100 Subject: [PATCH 043/103] Tabs: secondary --- packages/flet/lib/src/controls/tabs.dart | 192 +++++++++++------- .../packages/flet-core/src/flet_core/tabs.py | 11 + 2 files changed, 124 insertions(+), 79 deletions(-) diff --git a/packages/flet/lib/src/controls/tabs.dart b/packages/flet/lib/src/controls/tabs.dart index a29f08ac6..f44f7f6a1 100644 --- a/packages/flet/lib/src/controls/tabs.dart +++ b/packages/flet/lib/src/controls/tabs.dart @@ -67,6 +67,9 @@ class _TabsControlState extends State @override Widget build(BuildContext context) { debugPrint("TabsControl build: ${widget.control.id}"); + bool disabled = widget.control.isDisabled || widget.parentDisabled; + bool? adaptive = + widget.control.attrBool("adaptive") ?? widget.parentAdaptive; // keep only visible tabs widget.children.retainWhere((c) => c.isVisible); @@ -94,8 +97,6 @@ class _TabsControlState extends State _tabController!.addListener(_tabChanged); } - bool disabled = widget.control.isDisabled || widget.parentDisabled; - var selectedIndex = widget.control.attrInt("selectedIndex", 0)!; if (selectedIndex > -1 && @@ -112,7 +113,12 @@ class _TabsControlState extends State var overlayColorStr = widget.control.attrString("overlayColor"); dynamic overlayColor; if (overlayColorStr != null) { - overlayColor = json.decode(overlayColorStr); + overlayColor = getMaterialStateProperty( + json.decode(overlayColorStr), + (jv) => + HexColor.fromString(Theme.of(context), jv as String), + null) ?? + TabBarTheme.of(context).overlayColor; } var indicatorBorderRadius = @@ -126,91 +132,119 @@ class _TabsControlState extends State widget.control.attrString("indicatorColor", "")!) ?? TabBarTheme.of(context).indicatorColor ?? Theme.of(context).colorScheme.primary; + var labelColor = HexColor.fromString(Theme.of(context), + widget.control.attrString("labelColor", "")!) ?? + TabBarTheme.of(context).labelColor ?? + Theme.of(context).colorScheme.primary; + var unselectedLabelColor = HexColor.fromString(Theme.of(context), + widget.control.attrString("unselectedLabelColor", "")!) ?? + TabBarTheme.of(context).unselectedLabelColor ?? + Theme.of(context).colorScheme.onSurface; + var dividerColor = HexColor.fromString(Theme.of(context), + widget.control.attrString("dividerColor", "")!) ?? + TabBarTheme.of(context).dividerColor; var themeIndicator = TabBarTheme.of(context).indicator as UnderlineTabIndicator?; - var indicatorTabSize = widget.control.attrBool("indicatorTabSize"); - var isScrollable = widget.control.attrBool("scrollable", true)!; + var secondary = widget.control.attrBool("secondary", false)!; + var dividerHeight = widget.control.attrDouble("dividerHeight"); + var enableFeedback = widget.control.attrBool("enableFeedback"); + var indicatorWeight = + widget.control.attrDouble("indicatorThickness", 2.0)!; var tabAlignment = parseTabAlignment(widget.control, "tabAlignment", isScrollable ? TabAlignment.start : TabAlignment.fill); - bool? adaptive = - widget.control.attrBool("adaptive") ?? widget.parentAdaptive; - - var tabBar = TabBar( - tabAlignment: tabAlignment, - controller: _tabController, - isScrollable: isScrollable, - dividerHeight: widget.control.attrDouble("dividerHeight"), - enableFeedback: widget.control.attrBool("enableFeedback"), - indicatorWeight: - widget.control.attrDouble("indicatorThickness", 2.0)!, - dividerColor: HexColor.fromString(Theme.of(context), widget.control.attrString("dividerColor", "")!) ?? - TabBarTheme.of(context).dividerColor, - indicatorSize: indicatorTabSize != null - ? (indicatorTabSize - ? TabBarIndicatorSize.tab - : TabBarIndicatorSize.label) - : TabBarTheme.of(context).indicatorSize, - indicator: indicatorBorderRadius != null || - indicatorBorderSide != null || - indicatorPadding != null - ? UnderlineTabIndicator( - borderRadius: indicatorBorderRadius ?? - themeIndicator?.borderRadius ?? - const BorderRadius.only( - topLeft: Radius.circular(2), - topRight: Radius.circular(2)), - borderSide: indicatorBorderSide ?? - themeIndicator?.borderSide ?? - BorderSide( - width: themeIndicator?.borderSide.width ?? 2, - color: themeIndicator?.borderSide.color ?? - indicatorColor), - insets: indicatorPadding ?? - themeIndicator?.insets ?? - EdgeInsets.zero) - : TabBarTheme.of(context).indicator, - indicatorColor: indicatorColor, - labelColor: HexColor.fromString(Theme.of(context), widget.control.attrString("labelColor", "")!) ?? - TabBarTheme.of(context).labelColor ?? - Theme.of(context).colorScheme.primary, - unselectedLabelColor: HexColor.fromString(Theme.of(context), widget.control.attrString("unselectedLabelColor", "")!) ?? - TabBarTheme.of(context).unselectedLabelColor ?? - Theme.of(context).colorScheme.onSurface, - overlayColor: getMaterialStateProperty( - overlayColor, (jv) => HexColor.fromString(Theme.of(context), jv as String), null) ?? - TabBarTheme.of(context).overlayColor, - tabs: viewModel.controlViews.map((tabView) { - var text = tabView.control.attrString("text"); - var icon = parseIcon(tabView.control.attrString("icon", "")!); - var tabContentCtrls = tabView.children - .where((c) => c.name == "tab_content" && c.isVisible); - - Widget tabChild; - List widgets = []; - if (tabContentCtrls.isNotEmpty) { - tabChild = createControl( - widget.control, tabContentCtrls.first.id, disabled, - parentAdaptive: adaptive); - } else { - if (icon != null) { - widgets.add(Icon(icon)); - if (text != null) { - widgets.add(const SizedBox(width: 8)); - } - } - if (text != null) { - widgets.add(Text(text)); - } - tabChild = Row( - mainAxisAlignment: MainAxisAlignment.center, - children: widgets); + var indicator = indicatorBorderRadius != null || + indicatorBorderSide != null || + indicatorPadding != null + ? UnderlineTabIndicator( + borderRadius: indicatorBorderRadius ?? + themeIndicator?.borderRadius ?? + const BorderRadius.only( + topLeft: Radius.circular(2), + topRight: Radius.circular(2)), + borderSide: indicatorBorderSide ?? + themeIndicator?.borderSide ?? + BorderSide( + width: themeIndicator?.borderSide.width ?? 2, + color: themeIndicator?.borderSide.color ?? + indicatorColor), + insets: indicatorPadding ?? + themeIndicator?.insets ?? + EdgeInsets.zero) + : TabBarTheme.of(context).indicator; + var indicatorSize = indicatorTabSize != null + ? (indicatorTabSize + ? TabBarIndicatorSize.tab + : TabBarIndicatorSize.label) + : TabBarTheme.of(context).indicatorSize; + + var tabs = viewModel.controlViews.map((tabView) { + var text = tabView.control.attrString("text"); + var icon = parseIcon(tabView.control.attrString("icon", "")!); + var tabContentCtrls = tabView.children + .where((c) => c.name == "tab_content" && c.isVisible); + + Widget tabChild; + List widgets = []; + if (tabContentCtrls.isNotEmpty) { + tabChild = createControl( + widget.control, tabContentCtrls.first.id, disabled, + parentAdaptive: adaptive); + } else { + if (icon != null) { + widgets.add(Icon(icon)); + if (text != null) { + widgets.add(const SizedBox(width: 8)); } - return Tab(child: tabChild); - }).toList()); + } + if (text != null) { + widgets.add(Text(text)); + } + tabChild = Row( + mainAxisAlignment: MainAxisAlignment.center, + children: widgets); + } + return Tab(child: tabChild); + }).toList(); + + Widget? tabBar; + + if (secondary) { + tabBar = TabBar.secondary( + tabAlignment: tabAlignment, + controller: _tabController, + isScrollable: isScrollable, + dividerHeight: dividerHeight, + enableFeedback: enableFeedback, + indicatorWeight: indicatorWeight, + dividerColor: dividerColor, + indicatorSize: indicatorSize, + indicator: indicator, + indicatorColor: indicatorColor, + labelColor: labelColor, + unselectedLabelColor: unselectedLabelColor, + overlayColor: overlayColor, + tabs: tabs); + } else { + tabBar = TabBar( + tabAlignment: tabAlignment, + controller: _tabController, + isScrollable: isScrollable, + dividerHeight: dividerHeight, + enableFeedback: enableFeedback, + indicatorWeight: indicatorWeight, + dividerColor: dividerColor, + indicatorSize: indicatorSize, + indicator: indicator, + indicatorColor: indicatorColor, + labelColor: labelColor, + unselectedLabelColor: unselectedLabelColor, + overlayColor: overlayColor, + tabs: tabs); + } debugPrint("tabs.length: ${tabBar.tabs.length}"); diff --git a/sdk/python/packages/flet-core/src/flet_core/tabs.py b/sdk/python/packages/flet-core/src/flet_core/tabs.py index 7b6fba337..24890d906 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tabs.py +++ b/sdk/python/packages/flet-core/src/flet_core/tabs.py @@ -151,6 +151,7 @@ def __init__( indicator_border_side: Optional[BorderSide] = None, indicator_padding: PaddingValue = None, indicator_tab_size: Optional[bool] = None, + secondary: Optional[bool] = None, label_color: Optional[str] = None, unselected_label_color: Optional[str] = None, overlay_color: Union[None, str, Dict[MaterialState, str]] = None, @@ -239,6 +240,7 @@ def __init__( self.divider_height = divider_height self.indicator_thickness = indicator_thickness self.enable_feedback = enable_feedback + self.secondary = secondary def _get_control_name(self): return "tabs" @@ -289,6 +291,15 @@ def scrollable(self) -> Optional[bool]: def scrollable(self, value: Optional[bool]): self._set_attr("scrollable", value) + # secondary + @property + def secondary(self) -> Optional[bool]: + return self._get_attr("secondary", data_type="bool", def_value=False) + + @secondary.setter + def secondary(self, value: Optional[bool]): + self._set_attr("secondary", value) + # tab_alignment @property def tab_alignment(self) -> Optional[TabAlignment]: From 2adc9e9f862275e19a1282d0462c8c2bfb91a3e6 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 14 Mar 2024 22:21:29 +0100 Subject: [PATCH 044/103] Fix CI: typing error --- packages/flet/lib/src/controls/tabs.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/tabs.dart b/packages/flet/lib/src/controls/tabs.dart index f44f7f6a1..6e7547a61 100644 --- a/packages/flet/lib/src/controls/tabs.dart +++ b/packages/flet/lib/src/controls/tabs.dart @@ -210,7 +210,7 @@ class _TabsControlState extends State return Tab(child: tabChild); }).toList(); - Widget? tabBar; + TabBar? tabBar; if (secondary) { tabBar = TabBar.secondary( From 7f895095b56436236d551cfdacc5513bb42feb78 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 15 Mar 2024 17:02:56 +0100 Subject: [PATCH 045/103] Option: alignment, on_click --- packages/flet/lib/src/controls/dropdown.dart | 7 ++++ .../flet-core/src/flet_core/dropdown.py | 37 +++++++++++++++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/flet/lib/src/controls/dropdown.dart b/packages/flet/lib/src/controls/dropdown.dart index fdb95fe95..be6b22864 100644 --- a/packages/flet/lib/src/controls/dropdown.dart +++ b/packages/flet/lib/src/controls/dropdown.dart @@ -100,6 +100,13 @@ class _DropdownControlState extends State with FletStoreMixin { enabled: !(disabled || itemCtrl.isDisabled), value: itemCtrl.attrs["key"] ?? itemCtrl.attrs["text"] ?? itemCtrl.id, child: itemChild, + alignment: parseAlignment(itemCtrl, "alignment") ?? + AlignmentDirectional.centerStart, + onTap: !(disabled || itemCtrl.isDisabled) + ? () { + widget.backend.triggerControlEvent(itemCtrl.id, "click"); + } + : null, ); }).toList(); diff --git a/sdk/python/packages/flet-core/src/flet_core/dropdown.py b/sdk/python/packages/flet-core/src/flet_core/dropdown.py index b4972dae3..6334ca1c7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/dropdown.py +++ b/sdk/python/packages/flet-core/src/flet_core/dropdown.py @@ -23,19 +23,30 @@ def __init__( self, key: Optional[str] = None, text: Optional[str] = None, - visible: Optional[bool] = None, - disabled: Optional[bool] = None, + alignment: Optional[Alignment] = None, + on_click=None, + # + # Control + # ref=None, + disabled: Optional[bool] = None, + visible: Optional[bool] = None, + data: Any = None ): - Control.__init__(self, ref=ref, disabled=disabled, visible=visible) + Control.__init__(self, ref=ref, disabled=disabled, visible=visible, data=data) assert key is not None or text is not None, "key or text must be specified" self.key = key self.text = text - self.disabled = disabled + self.on_click = on_click + self.alignment = alignment def _get_control_name(self): return "dropdownoption" + def before_update(self): + super().before_update() + self._set_attr_json("alignment", self.__alignment) + # key @property def key(self): @@ -54,6 +65,24 @@ def text(self): def text(self, value): self._set_attr("text", value) + # alignment + @property + def alignment(self) -> Optional[Alignment]: + return self.__alignment + + @alignment.setter + def alignment(self, value: Optional[Alignment]): + self.__alignment = value + + # on_click + @property + def on_click(self): + return self._get_event_handler("click") + + @on_click.setter + def on_click(self, handler): + self._add_event_handler("click", handler) + class Dropdown(FormFieldControl): """ From b78bc0653009dd9b224a6a69cfc0fa1356db4e90 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 15 Mar 2024 17:10:28 +0100 Subject: [PATCH 046/103] Dropdown: hint_content, icon_content, elevation, item_height, max_menu_height, icon_size, enable_feedback, padding, icon_enabled_color, icon_disabled_color, on_click --- packages/flet/lib/src/controls/dropdown.dart | 46 +++++- .../flet-core/src/flet_core/dropdown.py | 145 +++++++++++++++++- 2 files changed, 180 insertions(+), 11 deletions(-) diff --git a/packages/flet/lib/src/controls/dropdown.dart b/packages/flet/lib/src/controls/dropdown.dart index be6b22864..84b207133 100644 --- a/packages/flet/lib/src/controls/dropdown.dart +++ b/packages/flet/lib/src/controls/dropdown.dart @@ -5,6 +5,7 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; import '../utils/colors.dart'; +import '../utils/edge_insets.dart'; import '../utils/text.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -13,6 +14,7 @@ import 'form_field.dart'; class DropdownControl extends StatefulWidget { final Control? parent; final Control control; + final List children; final bool parentDisabled; final bool? parentAdaptive; final FletControlBackend backend; @@ -21,6 +23,7 @@ class DropdownControl extends StatefulWidget { {super.key, this.parent, required this.control, + required this.children, required this.parentDisabled, required this.parentAdaptive, required this.backend}); @@ -68,11 +71,22 @@ class _DropdownControlState extends State with FletStoreMixin { bool disabled = widget.control.isDisabled || widget.parentDisabled; var textSize = widget.control.attrDouble("textSize"); + var alignment = parseAlignment(widget.control, "alignment"); + var iconCtrl = + widget.children.where((c) => c.name == "icon" && c.isVisible); + var hintCtrl = + widget.children.where((c) => c.name == "hint" && c.isVisible); var color = HexColor.fromString( Theme.of(context), widget.control.attrString("color", "")!); var focusedColor = HexColor.fromString( Theme.of(context), widget.control.attrString("focusedColor", "")!); + var bgcolor = HexColor.fromString( + Theme.of(context), widget.control.attrString("bgcolor", "")!); + var iconEnabledColor = HexColor.fromString(Theme.of(context), + widget.control.attrString("iconEnabledColor", "")!); + var iconDisabledColor = HexColor.fromString(Theme.of(context), + widget.control.attrString("iconDisabledColor", "")!); TextStyle? textStyle = parseTextStyle(Theme.of(context), widget.control, "textStyle"); @@ -83,8 +97,6 @@ class _DropdownControlState extends State with FletStoreMixin { Theme.of(context).colorScheme.onSurface); } - var alignment = parseAlignment(widget.control, "alignment"); - var items = itemsView.controlViews .map((v) => v.control) .where((c) => c.name == null && c.isVisible) @@ -92,16 +104,15 @@ class _DropdownControlState extends State with FletStoreMixin { Widget itemChild = Text( itemCtrl.attrs["text"] ?? itemCtrl.attrs["key"] ?? itemCtrl.id, ); - - if (alignment != null) { - itemChild = Container(alignment: alignment, child: itemChild); + var align = parseAlignment(itemCtrl, "alignment"); + if (align != null) { + itemChild = Container(alignment: align, child: itemChild); } return DropdownMenuItem( enabled: !(disabled || itemCtrl.isDisabled), value: itemCtrl.attrs["key"] ?? itemCtrl.attrs["text"] ?? itemCtrl.id, child: itemChild, - alignment: parseAlignment(itemCtrl, "alignment") ?? - AlignmentDirectional.centerStart, + alignment: align ?? AlignmentDirectional.centerStart, onTap: !(disabled || itemCtrl.isDisabled) ? () { widget.backend.triggerControlEvent(itemCtrl.id, "click"); @@ -137,9 +148,25 @@ class _DropdownControlState extends State with FletStoreMixin { autofocus: autofocus, focusNode: _focusNode, value: _value, + dropdownColor: bgcolor, + enableFeedback: widget.control.attrBool("enableFeedback"), + elevation: widget.control.attrInt("elevation", 8)!, + isDense: widget.control.attrBool("isDense", true)!, + padding: parseEdgeInsets(widget.control, "padding"), + itemHeight: widget.control.attrDouble("itemHeight"), + menuMaxHeight: widget.control.attrDouble("maxMenuHeight"), + iconEnabledColor: iconEnabledColor, + iconDisabledColor: iconDisabledColor, + iconSize: widget.control.attrDouble("iconSize", 24.0)!, borderRadius: borderRadius, alignment: alignment ?? AlignmentDirectional.centerStart, isExpanded: alignment != null, + icon: iconCtrl.isNotEmpty + ? createControl(widget.control, iconCtrl.first.id, disabled) + : null, + hint: iconCtrl.isNotEmpty + ? createControl(widget.control, hintCtrl.first.id, disabled) + : null, decoration: buildInputDecoration( context, widget.control, @@ -148,6 +175,11 @@ class _DropdownControlState extends State with FletStoreMixin { null, _focused, widget.parentAdaptive), + onTap: !disabled + ? () { + widget.backend.triggerControlEvent(widget.control.id, "click"); + } + : null, onChanged: disabled ? null : (String? value) { diff --git a/sdk/python/packages/flet-core/src/flet_core/dropdown.py b/sdk/python/packages/flet-core/src/flet_core/dropdown.py index 6334ca1c7..8fe871ac9 100644 --- a/sdk/python/packages/flet-core/src/flet_core/dropdown.py +++ b/sdk/python/packages/flet-core/src/flet_core/dropdown.py @@ -31,7 +31,7 @@ def __init__( ref=None, disabled: Optional[bool] = None, visible: Optional[bool] = None, - data: Any = None + data: Any = None, ): Control.__init__(self, ref=ref, disabled=disabled, visible=visible, data=data) assert key is not None or text is not None, "key or text must be specified" @@ -123,9 +123,20 @@ def __init__( options: Optional[List[Option]] = None, alignment: Optional[Alignment] = None, autofocus: Optional[bool] = None, + hint_content: Optional[Control] = None, + icon_content: Optional[Control] = None, + elevation: OptionalNumber = None, + item_height: OptionalNumber = None, + max_menu_height: OptionalNumber = None, + icon_size: OptionalNumber = None, + enable_feedback: Optional[bool] = None, + padding: PaddingValue = None, + icon_enabled_color: Optional[str] = None, + icon_disabled_color: Optional[str] = None, on_change=None, on_focus=None, on_blur=None, + on_click=None, # # FormField specific # @@ -259,21 +270,39 @@ def __init__( self.autofocus = autofocus self.options = options self.alignment = alignment + self.elevation = elevation + self.hint_content = hint_content + self.icon_content = icon_content + self.padding = padding + self.enable_feedback = enable_feedback self.on_focus = on_focus self.on_blur = on_blur self.on_change = on_change + self.item_height = item_height + self.max_menu_height = max_menu_height + self.icon_size = icon_size + self.icon_enabled_color = icon_enabled_color + self.icon_disabled_color = icon_disabled_color + self.on_click = on_click def _get_control_name(self): return "dropdown" def before_update(self): super().before_update() + self._set_attr_json("padding", self.__padding) self._set_attr_json("alignment", self.__alignment) def _get_children(self): - result = FormFieldControl._get_children(self) - result.extend(self.__options) - return result + children = FormFieldControl._get_children(self) + children.extend(self.__options) + if isinstance(self.__hint_content, Control): + self.__hint_content._set_attr_internal("n", "hint") + children.extend(self.__hint_content) + if isinstance(self.__icon_content, Control): + self.__icon_content._set_attr_internal("n", "icon") + children.extend(self.__icon_content) + return children def focus(self): self._set_attr_json("focus", str(time.time())) @@ -296,6 +325,24 @@ def options(self): def options(self, value): self.__options = value if value is not None else [] + # icon_content + @property + def icon_content(self) -> Optional[Control]: + return self.__icon_content + + @icon_content.setter + def icon_content(self, value: Optional[Control]): + self.__icon_content = value + + # hint_content + @property + def hint_content(self) -> Optional[Control]: + return self.__hint_content + + @hint_content.setter + def hint_content(self, value: Optional[Control]): + self.__hint_content = value + # value @property def value(self) -> Optional[str]: @@ -305,6 +352,60 @@ def value(self) -> Optional[str]: def value(self, value: Optional[str]): self._set_attr("value", value) + # icon_enabled_color + @property + def icon_enabled_color(self) -> Optional[str]: + return self._get_attr("iconEnabledColor") + + @icon_enabled_color.setter + def icon_enabled_color(self, value: Optional[str]): + self._set_attr("iconEnabledColor", value) + + # icon_disabled_color + @property + def icon_disabled_color(self) -> Optional[str]: + return self._get_attr("iconDisabledColor") + + @icon_disabled_color.setter + def icon_disabled_color(self, value: Optional[str]): + self._set_attr("iconDisabledColor", value) + + # item_height + @property + def item_height(self) -> OptionalNumber: + return self._get_attr("itemHeight", data_type="float") + + @item_height.setter + def item_height(self, value: OptionalNumber): + self._set_attr("itemHeight", value) + + # menu_max_height + @property + def menu_max_height(self) -> OptionalNumber: + return self._get_attr("menuMaxHeight", data_type="float") + + @menu_max_height.setter + def menu_max_height(self, value: OptionalNumber): + self._set_attr("menuMaxHeight", value) + + # icon_size + @property + def icon_size(self) -> OptionalNumber: + return self._get_attr("iconSize", data_type="float", def_value=24.0) + + @icon_size.setter + def icon_size(self, value: OptionalNumber): + self._set_attr("iconSize", value) + + # padding + @property + def padding(self) -> PaddingValue: + return self.__padding + + @padding.setter + def padding(self, value: PaddingValue): + self.__padding = value + # autofocus @property def autofocus(self) -> Optional[bool]: @@ -314,6 +415,33 @@ def autofocus(self) -> Optional[bool]: def autofocus(self, value: Optional[bool]): self._set_attr("autofocus", value) + # enable_feedback + @property + def enable_feedback(self) -> Optional[bool]: + return self._get_attr("enableFeedback", data_type="bool", def_value=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + + # dense + @property + def dense(self) -> Optional[bool]: + return self._get_attr("dense", data_type="bool", def_value=True) + + @dense.setter + def dense(self, value: Optional[bool]): + self._set_attr("dense", value) + + # elevation + @property + def elevation(self) -> OptionalNumber: + return self._get_attr("elevation", data_type="float", def_value=8) + + @elevation.setter + def elevation(self, value: OptionalNumber): + self._set_attr("elevation", value) + # alignment @property def alignment(self) -> Optional[Alignment]: @@ -349,3 +477,12 @@ def on_blur(self): @on_blur.setter def on_blur(self, handler): self._add_event_handler("blur", handler) + + # on_click + @property + def on_click(self): + return self._get_event_handler("click") + + @on_click.setter + def on_click(self, handler): + self._add_event_handler("click", handler) From 99588677fecc78e22a28eae960a2b3761c63a445 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 15 Mar 2024 17:16:25 +0100 Subject: [PATCH 047/103] Cleanup --- packages/flet/lib/src/controls/create_control.dart | 1 + packages/flet/lib/src/controls/icon_button.dart | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/create_control.dart b/packages/flet/lib/src/controls/create_control.dart index b500cc768..a069d80cb 100644 --- a/packages/flet/lib/src/controls/create_control.dart +++ b/packages/flet/lib/src/controls/create_control.dart @@ -808,6 +808,7 @@ Widget createWidget( key: key, parent: parent, control: controlView.control, + children: controlView.children, parentDisabled: parentDisabled, parentAdaptive: parentAdaptive, backend: backend); diff --git a/packages/flet/lib/src/controls/icon_button.dart b/packages/flet/lib/src/controls/icon_button.dart index d2297da31..22397cfd2 100644 --- a/packages/flet/lib/src/controls/icon_button.dart +++ b/packages/flet/lib/src/controls/icon_button.dart @@ -140,8 +140,8 @@ class _IconButtonControlState extends State autofocus: autofocus, focusNode: _focusNode, highlightColor: highlightColor, - disabledColor: highlightColor, - hoverColor: highlightColor, + disabledColor: disabledColor, + hoverColor: hoverColor, enableFeedback: enableFeedback, padding: padding, alignment: alignment, From f9384d71a480c149d3704f9fb91c3261f0c115c3 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 16 Mar 2024 12:37:49 +0100 Subject: [PATCH 048/103] PopupMenuButton: clip_behavior, splash_radius, elevation, enable_feedback, icon_size, surface_tint_color, shadow_color, bgcolor, icon_color, shape, padding --- .../lib/src/controls/popup_menu_button.dart | 61 ++++++- .../src/flet_core/popup_menu_button.py | 164 ++++++++++++++++-- 2 files changed, 208 insertions(+), 17 deletions(-) diff --git a/packages/flet/lib/src/controls/popup_menu_button.dart b/packages/flet/lib/src/controls/popup_menu_button.dart index bad6d611b..c3feda555 100644 --- a/packages/flet/lib/src/controls/popup_menu_button.dart +++ b/packages/flet/lib/src/controls/popup_menu_button.dart @@ -3,6 +3,9 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; +import '../utils/colors.dart'; +import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -27,7 +30,28 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { debugPrint("PopupMenuButton build: ${control.id}"); var icon = parseIcon(control.attrString("icon", "")!); - var tooltip = control.attrString("tooltip"); + var tooltip = control.attrString("tooltip", "")!; + var iconSize = control.attrDouble("iconSize"); + var splashRadius = control.attrDouble("splashRadius"); + var elevation = control.attrDouble("elevation"); + var enableFeedback = control.attrBool("enableFeedback"); + var shape = parseOutlinedBorder(control, "shape") ?? + (Theme.of(context).useMaterial3 + ? RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)) + : null); + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.none); + var bgcolor = HexColor.fromString( + Theme.of(context), control.attrString("bgcolor", "")!); + var iconColor = HexColor.fromString( + Theme.of(context), control.attrString("iconColor", "")!); + var shadowColor = HexColor.fromString( + Theme.of(context), control.attrString("shadowColor", "")!); + var surfaceTintColor = HexColor.fromString( + Theme.of(context), control.attrString("surfaceTintColor", "")!); var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); bool disabled = control.isDisabled || parentDisabled; @@ -48,11 +72,22 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { enabled: !disabled, icon: icon != null ? Icon(icon) : null, tooltip: tooltip, - shape: Theme.of(context).useMaterial3 - ? RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)) - : null, + iconSize: iconSize, + splashRadius: splashRadius, + shadowColor: shadowColor, + surfaceTintColor: surfaceTintColor, + iconColor: iconColor, + elevation: elevation, + enableFeedback: enableFeedback, + padding: parseEdgeInsets(control, "padding") ?? EdgeInsets.all(8), + color: bgcolor, + clipBehavior: clipBehavior, + shape: shape, onCanceled: () { - backend.triggerControlEvent(control.id, "cancelled"); + backend.triggerControlEvent(control.id, "cancel"); + }, + onOpened: () { + backend.triggerControlEvent(control.id, "open"); }, onSelected: (itemId) { backend.triggerControlEvent(itemId, "click"); @@ -88,10 +123,18 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { value: cv.control.id, checked: checked, enabled: !disabled, + onTap: () { + backend.triggerControlEvent(cv.control.id, "click"); + }, child: child, ) : PopupMenuItem( - value: cv.control.id, enabled: !disabled, child: child); + value: cv.control.id, + enabled: !disabled, + onTap: () { + backend.triggerControlEvent(cv.control.id, "click"); + }, + child: child); return child != null ? item @@ -100,6 +143,10 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { child: child); }); - return constrainedControl(context, popupButton, parent, control); + return constrainedControl( + context, + TooltipVisibility(visible: tooltip != "", child: popupButton), + parent, + control); } } diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 0d1c17dd8..7311feadc 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -1,12 +1,15 @@ from enum import Enum from typing import Any, List, Optional, Union +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref from flet_core.types import ( AnimationValue, + ClipBehavior, OffsetValue, + PaddingValue, ResponsiveNumber, RotateValue, ScaleValue, @@ -145,8 +148,20 @@ def __init__( content: Optional[Control] = None, items: Optional[List[PopupMenuItem]] = None, icon: Optional[str] = None, + bgcolor: Optional[str] = None, + icon_color: Optional[str] = None, + shadow_color: Optional[str] = None, + surface_tint_color: Optional[str] = None, + icon_size: OptionalNumber = None, + splash_radius: OptionalNumber = None, + elevation: OptionalNumber = None, menu_position: Optional[PopupMenuPosition] = None, - on_cancelled=None, + clip_behavior: Optional[ClipBehavior] = None, + enable_feedback: Optional[bool] = None, + shape: Optional[OutlinedBorder] = None, + padding: PaddingValue = None, + on_open=None, + on_cancel=None, # # ConstrainedControl # @@ -211,7 +226,19 @@ def __init__( self.items = items self.icon = icon - self.on_cancelled = on_cancelled + self.on_cancel = on_cancel + self.on_open = on_open + self.shape = shape + self.padding = padding + self.clip_behavior = clip_behavior + self.bgcolor = bgcolor + self.icon_color = icon_color + self.shadow_color = shadow_color + self.surface_tint_color = surface_tint_color + self.splash_radius = splash_radius + self.icon_size = icon_size + self.elevation = elevation + self.enable_feedback = enable_feedback self.__content: Optional[Control] = None self.content = content self.menu_position = menu_position @@ -227,6 +254,11 @@ def _get_children(self): children.extend(self.__items) return children + def before_update(self): + super().before_update() + self._set_attr_json("shape", self.__shape) + self._set_attr_json("padding", self.__padding) + # items @property def items(self) -> Optional[List[PopupMenuItem]]: @@ -236,24 +268,105 @@ def items(self) -> Optional[List[PopupMenuItem]]: def items(self, value: Optional[List[PopupMenuItem]]): self.__items = value if value is not None else [] - # on_cancelled + # shape + @property + def shape(self) -> Optional[OutlinedBorder]: + return self.__shape + + @shape.setter + def shape(self, value: Optional[OutlinedBorder]): + self.__shape = value + + # padding @property - def on_cancelled(self): - return self._get_event_handler("cancelled") + def padding(self) -> PaddingValue: + return self.__padding - @on_cancelled.setter - def on_cancelled(self, handler): - self._add_event_handler("cancelled", handler) + @padding.setter + def padding(self, value: PaddingValue): + self.__padding = value # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) + # icon_color + @property + def icon_color(self) -> Optional[str]: + return self._get_attr("iconColor") + + @icon_color.setter + def icon_color(self, value: Optional[str]): + self._set_attr("iconColor", value) + + # bgcolor + @property + def bgcolor(self) -> Optional[str]: + return self._get_attr("bgcolor") + + @bgcolor.setter + def bgcolor(self, value: Optional[str]): + self._set_attr("bgcolor", value) + + # shadow_color + @property + def shadow_color(self) -> Optional[str]: + return self._get_attr("shadowColor") + + @shadow_color.setter + def shadow_color(self, value: Optional[str]): + self._set_attr("shadowColor", value) + + # surface_tint_color + @property + def surface_tint_color(self) -> Optional[str]: + return self._get_attr("surfaceTintColor") + + @surface_tint_color.setter + def surface_tint_color(self, value: Optional[str]): + self._set_attr("surfaceTintColor", value) + + # icon_size + @property + def icon_size(self) -> OptionalNumber: + return self._get_attr("iconSize", data_type="float") + + @icon_size.setter + def icon_size(self, value: OptionalNumber): + self._set_attr("iconSize", value) + + # enable_feedback + @property + def enable_feedback(self) -> Optional[bool]: + return self._get_attr("enableFeedback", data_type="bool", def_val=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + + # elevation + @property + def elevation(self) -> OptionalNumber: + return self._get_attr("elevation", data_type="float", def_value=8) + + @elevation.setter + def elevation(self, value: OptionalNumber): + self._set_attr("elevation", value) + + # splash_radius + @property + def splash_radius(self) -> OptionalNumber: + return self._get_attr("splashRadius", data_type="float") + + @splash_radius.setter + def splash_radius(self, value: OptionalNumber): + self._set_attr("splashRadius", value) + # content @property def content(self) -> Optional[Control]: @@ -275,3 +388,34 @@ def menu_position(self, value: PopupMenuPosition): "menuPosition", value.value if isinstance(value, PopupMenuPosition) else value, ) + + # clip_behavior + @property + def clip_behavior(self) -> ClipBehavior: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: ClipBehavior): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", + value.value if isinstance(value, ClipBehavior) else value, + ) + + # on_cancel + @property + def on_cancel(self): + return self._get_event_handler("cancel") + + @on_cancel.setter + def on_cancel(self, handler): + self._add_event_handler("cancel", handler) + + # on_open + @property + def on_open(self): + return self._get_event_handler("open") + + @on_open.setter + def on_open(self, handler): + self._add_event_handler("open", handler) From 08fdce0ed7f2d497ea5082eee50a253292089bed Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 16 Mar 2024 14:45:30 +0100 Subject: [PATCH 049/103] Dropdown: remove dense getter and setter --- packages/flet/lib/src/controls/dropdown.dart | 1 - packages/flet/lib/src/controls/tooltip.dart | 4 +--- sdk/python/packages/flet-core/src/flet_core/dropdown.py | 9 --------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/flet/lib/src/controls/dropdown.dart b/packages/flet/lib/src/controls/dropdown.dart index 84b207133..72ef1305b 100644 --- a/packages/flet/lib/src/controls/dropdown.dart +++ b/packages/flet/lib/src/controls/dropdown.dart @@ -151,7 +151,6 @@ class _DropdownControlState extends State with FletStoreMixin { dropdownColor: bgcolor, enableFeedback: widget.control.attrBool("enableFeedback"), elevation: widget.control.attrInt("elevation", 8)!, - isDense: widget.control.attrBool("isDense", true)!, padding: parseEdgeInsets(widget.control, "padding"), itemHeight: widget.control.attrDouble("itemHeight"), menuMaxHeight: widget.control.attrDouble("maxMenuHeight"), diff --git a/packages/flet/lib/src/controls/tooltip.dart b/packages/flet/lib/src/controls/tooltip.dart index f0c2d23d1..598e97b88 100644 --- a/packages/flet/lib/src/controls/tooltip.dart +++ b/packages/flet/lib/src/controls/tooltip.dart @@ -82,9 +82,7 @@ class TooltipControl extends StatelessWidget { : null, verticalOffset: control.attrDouble("verticalOffset"), textStyle: parseTextStyle(Theme.of(context), control, "textStyle"), - textAlign: TextAlign.values.firstWhereOrNull((a) => - a.name.toLowerCase() == - control.attrString("textAlign", "")!.toLowerCase()), + textAlign: parseTextAlign(control.attrString("textAlign", "")!), child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled, parentAdaptive: parentAdaptive) diff --git a/sdk/python/packages/flet-core/src/flet_core/dropdown.py b/sdk/python/packages/flet-core/src/flet_core/dropdown.py index 8fe871ac9..95e4738b8 100644 --- a/sdk/python/packages/flet-core/src/flet_core/dropdown.py +++ b/sdk/python/packages/flet-core/src/flet_core/dropdown.py @@ -424,15 +424,6 @@ def enable_feedback(self) -> Optional[bool]: def enable_feedback(self, value: Optional[bool]): self._set_attr("enableFeedback", value) - # dense - @property - def dense(self) -> Optional[bool]: - return self._get_attr("dense", data_type="bool", def_value=True) - - @dense.setter - def dense(self, value: Optional[bool]): - self._set_attr("dense", value) - # elevation @property def elevation(self) -> OptionalNumber: From 7ab47a2b0b3382efd38eef088f5ba35e20296f82 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 18 Mar 2024 22:18:19 +0100 Subject: [PATCH 050/103] PopupMenuItem: padding, height --- .../lib/src/controls/popup_menu_button.dart | 9 ++++++- .../src/flet_core/popup_menu_button.py | 26 +++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/popup_menu_button.dart b/packages/flet/lib/src/controls/popup_menu_button.dart index c3feda555..41966a2d7 100644 --- a/packages/flet/lib/src/controls/popup_menu_button.dart +++ b/packages/flet/lib/src/controls/popup_menu_button.dart @@ -79,7 +79,8 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { iconColor: iconColor, elevation: elevation, enableFeedback: enableFeedback, - padding: parseEdgeInsets(control, "padding") ?? EdgeInsets.all(8), + padding: + parseEdgeInsets(control, "padding") ?? const EdgeInsets.all(8), color: bgcolor, clipBehavior: clipBehavior, shape: shape, @@ -98,6 +99,8 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { var itemIcon = parseIcon(cv.control.attrString("icon", "")!); var text = cv.control.attrString("text", "")!; var checked = cv.control.attrBool("checked"); + var height = cv.control.attrDouble("height", 48.0)!; + var padding = parseEdgeInsets(cv.control, "padding"); var disabled = cv.control.isDisabled || parentDisabled; var contentCtrls = cv.children.where((c) => c.name == "content"); @@ -122,6 +125,8 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { ? CheckedPopupMenuItem( value: cv.control.id, checked: checked, + height: height, + padding: padding, enabled: !disabled, onTap: () { backend.triggerControlEvent(cv.control.id, "click"); @@ -130,6 +135,8 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { ) : PopupMenuItem( value: cv.control.id, + height: height, + padding: padding, enabled: !disabled, onTap: () { backend.triggerControlEvent(cv.control.id, "click"); diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 7311feadc..d25e5a566 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -28,6 +28,8 @@ def __init__( icon: Optional[str] = None, checked: Optional[bool] = None, content: Optional[Control] = None, + height: OptionalNumber = None, + padding: PaddingValue = None, on_click=None, # # Control @@ -44,6 +46,8 @@ def __init__( self.__content: Optional[Control] = None self.content = content self.on_click = on_click + self.height = height + self.padding = padding def _get_control_name(self): return "popupmenuitem" @@ -75,13 +79,31 @@ def icon(self, value): # text @property - def text(self): + def text(self) -> Optional[str]: return self._get_attr("text") @text.setter - def text(self, value): + def text(self, value: Optional[str]): self._set_attr("text", value) + # height + @property + def height(self) -> OptionalNumber: + return self._get_attr("height", data_type="float", def_value=48) + + @height.setter + def height(self, value: OptionalNumber): + self._set_attr("height", value) + + # padding + @property + def padding(self) -> PaddingValue: + return self.__padding + + @padding.setter + def padding(self, value: PaddingValue): + self.__padding = value + # content @property def content(self): From e1438dc092ab0cefd0bd4d2e678ef00123a18a22 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 18 Mar 2024 22:30:52 +0100 Subject: [PATCH 051/103] Page: locale_configuration --- client/pubspec.lock | 5 ++ packages/flet/lib/src/controls/page.dart | 27 +++++++++- packages/flet/lib/src/utils/locale.dart | 52 +++++++++++++++++++ packages/flet/pubspec.yaml | 2 + .../flet-core/src/flet_core/__init__.py | 2 + .../packages/flet-core/src/flet_core/page.py | 27 +++++++++- 6 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 packages/flet/lib/src/utils/locale.dart diff --git a/client/pubspec.lock b/client/pubspec.lock index 0f62f2dd4..e083b2dad 100644 --- a/client/pubspec.lock +++ b/client/pubspec.lock @@ -293,6 +293,11 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_markdown: dependency: transitive description: diff --git a/packages/flet/lib/src/controls/page.dart b/packages/flet/lib/src/controls/page.dart index ab9414587..c80e0bdbf 100644 --- a/packages/flet/lib/src/controls/page.dart +++ b/packages/flet/lib/src/controls/page.dart @@ -2,10 +2,12 @@ import 'dart:convert'; import 'package:collection/collection.dart'; import 'package:equatable/equatable.dart'; +import 'package:flet/src/utils/locale.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; @@ -129,6 +131,7 @@ class _PageControlState extends State with FletStoreMixin { TargetPlatform _platform = defaultTargetPlatform; Brightness? _brightness; ThemeMode? _themeMode; + Map? _localeConfiguration; String? _windowTitle; Color? _windowBgcolor; double? _windowWidth; @@ -279,6 +282,9 @@ class _PageControlState extends State with FletStoreMixin { widget.control.attrString("themeMode", "")!.toLowerCase()) ?? FletAppContext.of(context)?.themeMode; + _localeConfiguration = + parseLocaleConfiguration(widget.control, "localeConfiguration"); + // keyboard handler var onKeyboardEvent = widget.control.attrBool("onKeyboardEvent", false)!; if (onKeyboardEvent && !_keyboardHandlerSubscribed) { @@ -565,8 +571,16 @@ class _PageControlState extends State with FletStoreMixin { : parseCupertinoTheme( widget.control, "theme", Brightness.dark), localizationsDelegates: const [ - DefaultMaterialLocalizations.delegate + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, ], + supportedLocales: _localeConfiguration != null + ? _localeConfiguration!["supportedLocales"] + : [const Locale('en', 'US')], + locale: _localeConfiguration != null + ? (_localeConfiguration?["locale"]) + : null, ) : MaterialApp.router( debugShowCheckedModeBanner: false, @@ -575,6 +589,17 @@ class _PageControlState extends State with FletStoreMixin { routerDelegate: _routerDelegate, routeInformationParser: _routeParser, title: windowTitle, + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: _localeConfiguration != null + ? _localeConfiguration!["supportedLocales"] + : [const Locale('en', 'US')], + locale: _localeConfiguration != null + ? (_localeConfiguration?["locale"]) + : null, theme: parseTheme( widget.control, "theme", Brightness.light), darkTheme: widget.control.attrString("darkTheme") == diff --git a/packages/flet/lib/src/utils/locale.dart b/packages/flet/lib/src/utils/locale.dart new file mode 100644 index 000000000..80a183a46 --- /dev/null +++ b/packages/flet/lib/src/utils/locale.dart @@ -0,0 +1,52 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import '../models/control.dart'; + +Map? parseLocaleConfiguration( + Control control, String propName) { + var v = control.attrString(propName, null); + if (v == null) { + return null; + } + + final j1 = json.decode(v); + return localeConfigurationFromJSON(j1); +} + +Map localeConfigurationFromJSON(dynamic json) { + List? supportedLocales; + var sl = json["supported_locales"]; + var locale = + json["used_locale"] != null ? parseLocale(json["used_locale"]) : null; + if (sl != null) { + supportedLocales = + sl.map((e) => parseLocale(e)).whereType().toList(); + } + + return { + "supportedLocales": supportedLocales != null && supportedLocales.isNotEmpty + ? supportedLocales + : [const Locale("en", "US")], + "locale": locale + }; +} + +Locale? parseLocale(value) { + var languageCode = value["language_code"]; + if (languageCode != null && languageCode.trim().isNotEmpty) { + var countryCode = value["country_code"]; + return Locale(languageCode, countryCode); + } + return null; +} + +Locale? localeFromJSON(dynamic json) { + String? languageCode = json["language_code"]; + if (languageCode != null && languageCode.trim().isNotEmpty) { + String? countryCode = json["country_code"]; + return Locale(languageCode, countryCode); + } + return null; +} diff --git a/packages/flet/pubspec.yaml b/packages/flet/pubspec.yaml index 4f4302308..8f47fd767 100644 --- a/packages/flet/pubspec.yaml +++ b/packages/flet/pubspec.yaml @@ -19,6 +19,8 @@ environment: dependencies: flutter: sdk: flutter + flutter_localizations: + sdk: flutter redux: ^5.0.0 flutter_redux: ^0.10.0 diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index a4500dadd..d1c57bda0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -178,6 +178,8 @@ from flet_core.page import ( AppLifecycleStateChangeEvent, KeyboardEvent, + Locale, + LocaleConfiguration, LoginEvent, Page, PageDisconnectedException, diff --git a/sdk/python/packages/flet-core/src/flet_core/page.py b/sdk/python/packages/flet-core/src/flet_core/page.py index 182246f34..44aae8bf7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/page.py +++ b/sdk/python/packages/flet-core/src/flet_core/page.py @@ -5,7 +5,7 @@ import time import uuid from concurrent.futures import ThreadPoolExecutor -from dataclasses import dataclass +from dataclasses import dataclass, field from datetime import datetime, timedelta from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple, Union, cast from urllib.parse import urlparse @@ -77,6 +77,18 @@ def __init__( pass +@dataclass +class Locale: + language_code: str = field(default="en") + country_code: Optional[str] = field(default=None) + + +@dataclass +class LocaleConfiguration: + supported_locales: Optional[List[Locale]] = field(default=None) + used_locale: Optional[Locale] = field(default=None) + + class PageDisconnectedException(Exception): def __init__(self, message): super().__init__(message) @@ -138,6 +150,7 @@ def __init__( self.__offstage = Offstage() self.__theme = None self.__dark_theme = None + self.__locale_configuration = None self.__theme_mode = ThemeMode.SYSTEM # Default Theme Mode self.__pubsub: PubSubClient = PubSubClient(conn.pubsubhub, session_id) self.__client_storage: ClientStorage = ClientStorage(self) @@ -232,6 +245,7 @@ def before_update(self): super().before_update() self._set_attr_json("fonts", self.__fonts) self._set_attr_json("theme", self.__theme) + self._set_attr_json("localeConfiguration", self.__locale_configuration) self._set_attr_json("darkTheme", self.__dark_theme) # keyboard event @@ -1233,7 +1247,7 @@ def platform(self, value: PagePlatform): # platform_brightness @property - def platform_brightness(self) -> ThemeMode: + def platform_brightness(self) -> Brightness: brightness = self._get_attr("platformBrightness") assert brightness is not None return Brightness(brightness) @@ -1498,6 +1512,15 @@ def dark_theme(self) -> Optional[Theme]: def dark_theme(self, value: Optional[Theme]): self.__dark_theme = value + # locale_configuration + @property + def locale_configuration(self) -> Optional[LocaleConfiguration]: + return self.__locale_configuration + + @locale_configuration.setter + def locale_configuration(self, value: Optional[LocaleConfiguration]): + self.__locale_configuration = value + # rtl @property def rtl(self) -> Optional[bool]: From 386a8961f3cc39a9cb5bcb7b8135d8b5fc8f6903 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Wed, 20 Mar 2024 07:31:43 +0100 Subject: [PATCH 052/103] Card: rename NORMAL to ELEVATED --- packages/flet/lib/src/controls/card.dart | 4 ++-- sdk/python/packages/flet-core/src/flet_core/card.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/card.dart b/packages/flet/lib/src/controls/card.dart index 5cabf1b12..1abb2eca9 100644 --- a/packages/flet/lib/src/controls/card.dart +++ b/packages/flet/lib/src/controls/card.dart @@ -7,7 +7,7 @@ import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; -enum CardVariant { normal, filled, outlined } +enum CardVariant { elevated, filled, outlined } class CardControl extends StatelessWidget { final Control? parent; @@ -44,7 +44,7 @@ class CardControl extends StatelessWidget { (v) => v.name.toLowerCase() == control.attrString("variant", "")!.toLowerCase(), - orElse: () => CardVariant.normal); + orElse: () => CardVariant.elevated); if (variant == CardVariant.outlined) { card = Card.outlined( diff --git a/sdk/python/packages/flet-core/src/flet_core/card.py b/sdk/python/packages/flet-core/src/flet_core/card.py index 593772555..92609e42d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/card.py +++ b/sdk/python/packages/flet-core/src/flet_core/card.py @@ -18,7 +18,7 @@ class CardVariant(Enum): - NORMAL = "normal" + ELEVATED = "elevated" FILLED = "filled" OUTLINED = "outlined" From faf14444e210a9350e4cd1f3a4cf62af397b0949 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Wed, 20 Mar 2024 07:49:00 +0100 Subject: [PATCH 053/103] CircleAvatar: rename foreground_image_url and background_image_url to *_src --- .../flet/lib/src/controls/circle_avatar.dart | 101 ++++++++++++------ .../flet-core/src/flet_core/circle_avatar.py | 56 +++++++++- 2 files changed, 122 insertions(+), 35 deletions(-) diff --git a/packages/flet/lib/src/controls/circle_avatar.dart b/packages/flet/lib/src/controls/circle_avatar.dart index 5ef07ece9..ad0736ef6 100644 --- a/packages/flet/lib/src/controls/circle_avatar.dart +++ b/packages/flet/lib/src/controls/circle_avatar.dart @@ -3,9 +3,11 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; +import '../utils/images.dart'; import 'create_control.dart'; +import 'flet_store_mixin.dart'; -class CircleAvatarControl extends StatelessWidget { +class CircleAvatarControl extends StatelessWidget with FletStoreMixin { final Control? parent; final Control control; final List children; @@ -23,36 +25,73 @@ class CircleAvatarControl extends StatelessWidget { @override Widget build(BuildContext context) { debugPrint("CircleAvatar build: ${control.id}"); - bool disabled = control.isDisabled || parentDisabled; - var foregroundImageUrl = control.attrString("foregroundImageUrl"); - var backgroundImageUrl = control.attrString("backgroundImageUrl"); - var contentCtrls = children.where((c) => c.name == "content"); - - var avatar = CircleAvatar( - foregroundImage: foregroundImageUrl != null - ? NetworkImage(foregroundImageUrl) - : null, - backgroundImage: backgroundImageUrl != null - ? NetworkImage(backgroundImageUrl) - : null, - backgroundColor: HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!), - foregroundColor: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), - radius: control.attrDouble("radius"), - minRadius: control.attrDouble("minRadius"), - maxRadius: control.attrDouble("maxRadius"), - onBackgroundImageError: (object, trace) { - backend.triggerControlEvent(control.id, "imageError", "background"); - }, - onForegroundImageError: (object, trace) { - backend.triggerControlEvent(control.id, "imageError", "foreground"); - }, - child: contentCtrls.isNotEmpty - ? createControl(control, contentCtrls.first.id, disabled) - : null); - - return constrainedControl(context, avatar, parent, control); + + return withPageArgs((context, pageArgs) { + // DEPRECATED: foregroundImageUrl and backgroundImageUrl + var foregroundImageSrc = control.attrString("foregroundImageSrc") ?? + control.attrString("foregroundImageUrl"); + var backgroundImageSrc = control.attrString("backgroundImageSrc") ?? + control.attrString("backgroundImageUrl"); + var contentCtrls = children.where((c) => c.name == "content"); + + ImageProvider? backgroundImage; + ImageProvider? foregroundImage; + + if (foregroundImageSrc != null || backgroundImageSrc != null) { + var assetSrc = getAssetSrc((foregroundImageSrc ?? backgroundImageSrc)!, + pageArgs.pageUri!, pageArgs.assetsDir); + + // foregroundImage + if (foregroundImageSrc != null) { + if (assetSrc.isFile) { + // from File + foregroundImage = AssetImage(assetSrc.path); + } else { + // URL + foregroundImage = NetworkImage(assetSrc.path); + } + } + + // backgroundImage + if (backgroundImageSrc != null) { + if (assetSrc.isFile) { + // from File + backgroundImage = AssetImage(assetSrc.path); + } else { + // URL + backgroundImage = NetworkImage(assetSrc.path); + } + } + } + + var avatar = CircleAvatar( + foregroundImage: foregroundImage, + backgroundImage: backgroundImage, + backgroundColor: HexColor.fromString( + Theme.of(context), control.attrString("bgColor", "")!), + foregroundColor: HexColor.fromString( + Theme.of(context), control.attrString("color", "")!), + radius: control.attrDouble("radius"), + minRadius: control.attrDouble("minRadius"), + maxRadius: control.attrDouble("maxRadius"), + onBackgroundImageError: backgroundImage != null + ? (object, trace) { + backend.triggerControlEvent( + control.id, "imageError", "background"); + } + : null, + onForegroundImageError: foregroundImage != null + ? (object, trace) { + backend.triggerControlEvent( + control.id, "imageError", "foreground"); + } + : null, + child: contentCtrls.isNotEmpty + ? createControl(control, contentCtrls.first.id, disabled) + : null); + + return constrainedControl(context, avatar, parent, control); + }); } } diff --git a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py index a4dd6d75d..f4f8bab0d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py +++ b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py @@ -1,3 +1,4 @@ +import warnings from typing import Any, Optional, Union from flet_core.constrained_control import ConstrainedControl @@ -16,7 +17,8 @@ class CircleAvatar(ConstrainedControl): """ A circle that represents a user. - If `foreground_image_url` fails then `background_image_url` is used. If `background_image_url` fails too, `bgcolor` is used. + If `foreground_image_src` fails then `background_image_src` is used. If `background_image_src` fails too, + then `bgcolor` is used. Example: ``` @@ -25,12 +27,12 @@ class CircleAvatar(ConstrainedControl): def main(page): # a "normal" avatar with background image a1 = ft.CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/5041459?s=88&v=4", + foreground_image_src="https://avatars.githubusercontent.com/u/5041459?s=88&v=4", content=ft.Text("FF"), ) # avatar with failing foreground image and fallback text a2 = ft.CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/_5041459?s=88&v=4", + foreground_image_src="https://avatars.githubusercontent.com/u/_5041459?s=88&v=4", content=ft.Text("FF"), ) # avatar with icon, aka icon with inverse background @@ -47,7 +49,7 @@ def main(page): a5 = ft.Stack( [ ft.CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" + foreground_image_src="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" ), ft.Container( content=ft.CircleAvatar(bgcolor=ft.colors.GREEN, radius=5), @@ -73,6 +75,8 @@ def __init__( content: Optional[Control] = None, foreground_image_url: Optional[str] = None, background_image_url: Optional[str] = None, + foreground_image_src: Optional[str] = None, + background_image_src: Optional[str] = None, color: Optional[str] = None, bgcolor: Optional[str] = None, radius: OptionalNumber = None, @@ -143,6 +147,8 @@ def __init__( self.foreground_image_url = foreground_image_url self.background_image_url = background_image_url + self.foreground_image_src = foreground_image_src + self.background_image_src = background_image_src self.radius = radius self.min_radius = min_radius self.max_radius = max_radius @@ -163,21 +169,63 @@ def _get_children(self): # foreground_image_url @property def foreground_image_url(self) -> Optional[str]: + warnings.warn( + f"foreground_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use foreground_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) return self._get_attr("foregroundImageUrl") @foreground_image_url.setter def foreground_image_url(self, value: Optional[str]): + warnings.warn( + f"foreground_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use foreground_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) self._set_attr("foregroundImageUrl", value) # background_image_url @property def background_image_url(self) -> Optional[str]: + warnings.warn( + f"background_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use background_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) return self._get_attr("backgroundImageUrl") @background_image_url.setter def background_image_url(self, value: Optional[str]): + warnings.warn( + f"background_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use background_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) self._set_attr("backgroundImageUrl", value) + # foreground_image_src + @property + def foreground_image_src(self) -> Optional[str]: + return self._get_attr("foregroundImageSrc") + + @foreground_image_src.setter + def foreground_image_src(self, value: Optional[str]): + self._set_attr("foregroundImageSrc", value) + + # background_image_src + @property + def background_image_src(self) -> Optional[str]: + return self._get_attr("backgroundImageSrc") + + @background_image_src.setter + def background_image_src(self, value: Optional[str]): + self._set_attr("backgroundImageSrc", value) + # radius @property def radius(self) -> OptionalNumber: From 80d70dd242047e2c590d5df0f08c83f84d6cedb6 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 06:20:01 +0100 Subject: [PATCH 054/103] UrlTarget enum --- .../packages/flet-core/src/flet_core/__init__.py | 1 + .../packages/flet-core/src/flet_core/container.py | 14 +++++++++----- .../flet-core/src/flet_core/cupertino_button.py | 14 +++++++++----- .../src/flet_core/cupertino_filled_button.py | 4 ++-- .../flet-core/src/flet_core/cupertino_list_tile.py | 14 +++++++++----- .../flet-core/src/flet_core/elevated_button.py | 14 +++++++++----- .../flet-core/src/flet_core/filled_button.py | 4 ++-- .../flet-core/src/flet_core/filled_tonal_button.py | 4 ++-- .../src/flet_core/floating_action_button.py | 14 +++++++++----- .../flet-core/src/flet_core/icon_button.py | 14 +++++++++----- .../packages/flet-core/src/flet_core/list_tile.py | 14 +++++++++----- .../flet-core/src/flet_core/outlined_button.py | 14 +++++++++----- .../flet-core/src/flet_core/text_button.py | 14 +++++++++----- .../packages/flet-core/src/flet_core/text_span.py | 14 +++++++++----- .../packages/flet-core/src/flet_core/types.py | 5 +++++ 15 files changed, 102 insertions(+), 56 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/__init__.py b/sdk/python/packages/flet-core/src/flet_core/__init__.py index d1c57bda0..881cb0b41 100644 --- a/sdk/python/packages/flet-core/src/flet_core/__init__.py +++ b/sdk/python/packages/flet-core/src/flet_core/__init__.py @@ -278,6 +278,7 @@ TabAlignment, TextAlign, ThemeMode, + UrlTarget, VerticalAlignment, ) from flet_core.user_control import UserControl diff --git a/sdk/python/packages/flet-core/src/flet_core/container.py b/sdk/python/packages/flet-core/src/flet_core/container.py index ebb8567e1..b724601ab 100644 --- a/sdk/python/packages/flet-core/src/flet_core/container.py +++ b/sdk/python/packages/flet-core/src/flet_core/container.py @@ -28,6 +28,7 @@ RotateValue, ScaleValue, ThemeMode, + UrlTarget, ) @@ -84,7 +85,7 @@ def __init__( ] = None, shadow: Union[None, BoxShadow, List[BoxShadow]] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, theme: Optional[Theme] = None, theme_mode: Optional[ThemeMode] = None, on_click=None, @@ -439,12 +440,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # theme @property diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_button.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_button.py index d9261acbd..b171745e2 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_button.py @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + UrlTarget, ) @@ -39,7 +40,7 @@ def __init__( alignment: Optional[Alignment] = None, border_radius: BorderRadiusValue = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, # # Common @@ -246,12 +247,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_filled_button.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_filled_button.py index 330a65ae4..fad1e98d4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_filled_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_filled_button.py @@ -4,7 +4,7 @@ from flet_core.control import Control, OptionalNumber from flet_core.cupertino_button import CupertinoButton from flet_core.ref import Ref -from flet_core.types import BorderRadiusValue, PaddingValue, ResponsiveNumber +from flet_core.types import BorderRadiusValue, PaddingValue, ResponsiveNumber, UrlTarget class CupertinoFilledButton(CupertinoButton): @@ -56,7 +56,7 @@ def __init__( icon_color: Optional[str] = None, content: Optional[Control] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, ): CupertinoButton.__init__( diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py index b4da2e564..23de32aaf 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py @@ -10,6 +10,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + UrlTarget, ) @@ -59,7 +60,7 @@ def __init__( bgcolor_activated: Optional[str] = None, padding: PaddingValue = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, toggle_inputs: Optional[bool] = None, additional_info: Optional[Control] = None, leading_size: OptionalNumber = None, @@ -280,12 +281,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # toggle_inputs @property 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 5172af7c7..1ad15837a 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 @@ -13,6 +13,7 @@ RotateValue, ScaleValue, ClipBehavior, + UrlTarget, ) from flet_core.utils import deprecated @@ -53,7 +54,7 @@ def __init__( autofocus: Optional[bool] = None, clip_behavior: Optional[ClipBehavior] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, on_hover=None, @@ -275,12 +276,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/filled_button.py b/sdk/python/packages/flet-core/src/flet_core/filled_button.py index 54ce44142..53b86d9af 100644 --- a/sdk/python/packages/flet-core/src/flet_core/filled_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/filled_button.py @@ -4,7 +4,7 @@ from flet_core.control import Control, OptionalNumber from flet_core.elevated_button import ElevatedButton from flet_core.ref import Ref -from flet_core.types import ResponsiveNumber +from flet_core.types import ResponsiveNumber, UrlTarget class FilledButton(ElevatedButton): @@ -42,7 +42,7 @@ def __init__( content: Optional[Control] = None, autofocus: Optional[bool] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, on_hover=None, diff --git a/sdk/python/packages/flet-core/src/flet_core/filled_tonal_button.py b/sdk/python/packages/flet-core/src/flet_core/filled_tonal_button.py index 3b2e99978..7d302c1e5 100644 --- a/sdk/python/packages/flet-core/src/flet_core/filled_tonal_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/filled_tonal_button.py @@ -4,7 +4,7 @@ from flet_core.control import Control, OptionalNumber from flet_core.elevated_button import ElevatedButton from flet_core.ref import Ref -from flet_core.types import ResponsiveNumber +from flet_core.types import ResponsiveNumber, UrlTarget class FilledTonalButton(ElevatedButton): @@ -41,7 +41,7 @@ def __init__( content: Optional[Control] = None, autofocus: Optional[bool] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, on_hover=None, diff --git a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py index cb4298d1f..344603b27 100644 --- a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py @@ -11,6 +11,7 @@ RotateValue, ScaleValue, ClipBehavior, + UrlTarget, ) @@ -82,7 +83,7 @@ def __init__( hover_elevation: OptionalNumber = None, enable_feedback: Optional[bool] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, # # ConstrainedControl @@ -217,12 +218,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/icon_button.py b/sdk/python/packages/flet-core/src/flet_core/icon_button.py index 6fb159220..4a63f611d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/icon_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/icon_button.py @@ -14,6 +14,7 @@ RotateValue, ScaleValue, PaddingValue, + UrlTarget, ) from flet_core.utils import deprecated @@ -79,7 +80,7 @@ def __init__( padding: PaddingValue = None, enable_feedback: Optional[bool] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_focus=None, on_blur=None, @@ -358,12 +359,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/list_tile.py b/sdk/python/packages/flet-core/src/flet_core/list_tile.py index 85a7cdd3c..04c1b3a4c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_tile.py @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + UrlTarget, ) @@ -84,7 +85,7 @@ def __init__( min_leading_width: OptionalNumber = None, min_vertical_padding: OptionalNumber = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, # @@ -394,12 +395,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/outlined_button.py b/sdk/python/packages/flet-core/src/flet_core/outlined_button.py index 7832814df..b8456a546 100644 --- a/sdk/python/packages/flet-core/src/flet_core/outlined_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/outlined_button.py @@ -13,6 +13,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + UrlTarget, ) from flet_core.utils import deprecated @@ -50,7 +51,7 @@ def __init__( autofocus: Optional[bool] = None, clip_behavior: Optional[ClipBehavior] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, on_hover=None, @@ -211,12 +212,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/text_button.py b/sdk/python/packages/flet-core/src/flet_core/text_button.py index 535efc855..86ad7a62b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/text_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/text_button.py @@ -12,6 +12,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + UrlTarget, ) from flet_core.utils import deprecated @@ -48,7 +49,7 @@ def __init__( style: Optional[ButtonStyle] = None, autofocus: Optional[bool] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_long_press=None, on_hover=None, @@ -208,12 +209,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/text_span.py b/sdk/python/packages/flet-core/src/flet_core/text_span.py index e85c2ea00..861f889f0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/text_span.py +++ b/sdk/python/packages/flet-core/src/flet_core/text_span.py @@ -2,6 +2,7 @@ from flet_core.inline_span import InlineSpan from flet_core.text_style import TextStyle +from flet_core.types import UrlTarget class TextSpan(InlineSpan): @@ -11,7 +12,7 @@ def __init__( style: Optional[TextStyle] = None, spans: Optional[List[InlineSpan]] = None, url: Optional[str] = None, - url_target: Optional[str] = None, + url_target: Optional[UrlTarget] = None, on_click=None, on_enter=None, on_exit=None, @@ -86,12 +87,15 @@ def url(self, value): # url_target @property - def url_target(self): - return self._get_attr("urlTarget") + def url_target(self) -> Optional[UrlTarget]: + return self.__url_target @url_target.setter - def url_target(self, value): - self._set_attr("urlTarget", value) + def url_target(self, value: Optional[UrlTarget]): + self.__url_target = value + self._set_attr( + "urlTarget", value.value if isinstance(value, UrlTarget) else value + ) # on_click @property diff --git a/sdk/python/packages/flet-core/src/flet_core/types.py b/sdk/python/packages/flet-core/src/flet_core/types.py index c244fcdd3..a0b61b92d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/types.py +++ b/sdk/python/packages/flet-core/src/flet_core/types.py @@ -31,6 +31,11 @@ class WebRenderer(Enum): CANVAS_KIT = "canvaskit" +class UrlTarget(Enum): + BLANK = "blank" + SELF = "_self" + + PaddingValue = Union[None, int, float, Padding] MarginValue = Union[None, int, float, Margin] From e2b74cac850d96a46f55ad8fb25f45e7c1066538 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 06:27:49 +0100 Subject: [PATCH 055/103] PopupMenuButton: reintroduce on_cancelled, but as deprecated --- packages/flet/lib/src/controls/popup_menu_button.dart | 1 + .../flet-core/src/flet_core/popup_menu_button.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/packages/flet/lib/src/controls/popup_menu_button.dart b/packages/flet/lib/src/controls/popup_menu_button.dart index 41966a2d7..47a9e0785 100644 --- a/packages/flet/lib/src/controls/popup_menu_button.dart +++ b/packages/flet/lib/src/controls/popup_menu_button.dart @@ -86,6 +86,7 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { shape: shape, onCanceled: () { backend.triggerControlEvent(control.id, "cancel"); + backend.triggerControlEvent(control.id, "cancelled"); // DEPRECATED }, onOpened: () { backend.triggerControlEvent(control.id, "open"); diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index d25e5a566..4976d8c88 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -182,6 +182,7 @@ def __init__( enable_feedback: Optional[bool] = None, shape: Optional[OutlinedBorder] = None, padding: PaddingValue = None, + on_cancelled=None, on_open=None, on_cancel=None, # @@ -249,6 +250,7 @@ def __init__( self.items = items self.icon = icon self.on_cancel = on_cancel + self.on_cancelled = on_cancelled self.on_open = on_open self.shape = shape self.padding = padding @@ -433,6 +435,15 @@ def on_cancel(self): def on_cancel(self, handler): self._add_event_handler("cancel", handler) + # on_cancelled + @property + def on_cancelled(self): + return self._get_event_handler("cancelled") + + @on_cancelled.setter + def on_cancelled(self, handler): + self._add_event_handler("cancelled", handler) + # on_open @property def on_open(self): From 65f7e9068c596c22f52a108b0d584bbb2a03e967 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 15:54:44 +0100 Subject: [PATCH 056/103] Reformat: created control.attrColor to ease color parsing --- .../flet/lib/src/controls/alert_dialog.dart | 10 ++----- packages/flet/lib/src/controls/app_bar.dart | 7 ++--- packages/flet/lib/src/controls/badge.dart | 7 ++--- packages/flet/lib/src/controls/banner.dart | 4 +-- packages/flet/lib/src/controls/barchart.dart | 17 ++++------- .../flet/lib/src/controls/bottom_app_bar.dart | 10 ++----- .../flet/lib/src/controls/bottom_sheet.dart | 4 +-- packages/flet/lib/src/controls/canvas.dart | 9 ++---- packages/flet/lib/src/controls/card.dart | 28 ++++++------------- packages/flet/lib/src/controls/checkbox.dart | 12 +++----- packages/flet/lib/src/controls/chip.dart | 23 ++++++--------- .../flet/lib/src/controls/circle_avatar.dart | 7 ++--- packages/flet/lib/src/controls/container.dart | 7 ++--- .../cupertino_activity_indicator.dart | 5 +--- .../lib/src/controls/cupertino_app_bar.dart | 8 ++---- .../src/controls/cupertino_bottom_sheet.dart | 5 +--- .../lib/src/controls/cupertino_button.dart | 17 ++++------- .../lib/src/controls/cupertino_checkbox.dart | 9 ++---- .../src/controls/cupertino_date_picker.dart | 5 +--- .../lib/src/controls/cupertino_list_tile.dart | 8 ++---- .../controls/cupertino_navigation_bar.dart | 10 ++----- .../lib/src/controls/cupertino_picker.dart | 5 +--- .../lib/src/controls/cupertino_radio.dart | 6 ++-- .../controls/cupertino_segmented_button.dart | 11 ++------ .../lib/src/controls/cupertino_slider.dart | 8 ++---- .../cupertino_sliding_segmented_button.dart | 8 ++---- .../lib/src/controls/cupertino_switch.dart | 6 ++-- .../lib/src/controls/cupertino_textfield.dart | 19 ++++--------- .../src/controls/cupertino_timer_picker.dart | 5 +--- packages/flet/lib/src/controls/divider.dart | 4 +-- packages/flet/lib/src/controls/dropdown.dart | 20 ++++++------- .../lib/src/controls/elevated_button.dart | 4 +-- .../lib/src/controls/expansion_panel.dart | 11 +++----- .../flet/lib/src/controls/expansion_tile.dart | 19 ++++--------- .../src/controls/floating_action_button.dart | 16 ++++------- .../flet/lib/src/controls/form_field.dart | 13 +++------ packages/flet/lib/src/controls/icon.dart | 4 +-- .../flet/lib/src/controls/icon_button.dart | 27 +++++++----------- packages/flet/lib/src/controls/image.dart | 4 +-- packages/flet/lib/src/controls/linechart.dart | 18 ++++++------ packages/flet/lib/src/controls/list_tile.dart | 19 ++++--------- .../flet/lib/src/controls/navigation_bar.dart | 14 ++++------ .../lib/src/controls/navigation_drawer.dart | 13 +++------ .../lib/src/controls/navigation_rail.dart | 8 ++---- .../lib/src/controls/outlined_button.dart | 4 +-- packages/flet/lib/src/controls/page.dart | 10 ++----- packages/flet/lib/src/controls/pagelet.dart | 7 ++--- packages/flet/lib/src/controls/piechart.dart | 8 ++---- .../lib/src/controls/popup_menu_button.dart | 13 +++------ .../flet/lib/src/controls/progress_bar.dart | 7 ++--- .../flet/lib/src/controls/progress_ring.dart | 7 ++--- packages/flet/lib/src/controls/radio.dart | 9 ++---- .../flet/lib/src/controls/range_slider.dart | 6 ++-- .../flet/lib/src/controls/search_anchor.dart | 6 ++-- packages/flet/lib/src/controls/slider.dart | 9 ++---- packages/flet/lib/src/controls/snack_bar.dart | 10 ++----- packages/flet/lib/src/controls/switch.dart | 18 ++++++------ packages/flet/lib/src/controls/tabs.dart | 21 +++++++------- packages/flet/lib/src/controls/text.dart | 7 ++--- .../flet/lib/src/controls/text_button.dart | 4 +-- packages/flet/lib/src/controls/textfield.dart | 13 +++------ packages/flet/lib/src/controls/tooltip.dart | 3 +- .../lib/src/controls/vertical_divider.dart | 4 +-- packages/flet/lib/src/models/control.dart | 8 ++++++ 64 files changed, 215 insertions(+), 433 deletions(-) diff --git a/packages/flet/lib/src/controls/alert_dialog.dart b/packages/flet/lib/src/controls/alert_dialog.dart index d30167841..71abbc295 100644 --- a/packages/flet/lib/src/controls/alert_dialog.dart +++ b/packages/flet/lib/src/controls/alert_dialog.dart @@ -4,7 +4,6 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'cupertino_alert_dialog.dart'; @@ -82,13 +81,10 @@ class _AlertDialogControlState extends State insetPadding: parseEdgeInsets(widget.control, "insetPadding") ?? const EdgeInsets.symmetric(horizontal: 40.0, vertical: 24.0), iconPadding: parseEdgeInsets(widget.control, "iconPadding"), - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!), + backgroundColor: widget.control.attrColor("bgcolor", context), buttonPadding: parseEdgeInsets(widget.control, "actionButtonPadding"), - surfaceTintColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("surfaceTintColor", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("shadowColor", "")!), + surfaceTintColor: widget.control.attrColor("surfaceTintColor", context), + shadowColor: widget.control.attrColor("shadowColor", context), elevation: widget.control.attrDouble("elevation"), clipBehavior: clipBehavior, icon: iconCtrls.isNotEmpty diff --git a/packages/flet/lib/src/controls/app_bar.dart b/packages/flet/lib/src/controls/app_bar.dart index 678f90f0d..6a2271b3a 100644 --- a/packages/flet/lib/src/controls/app_bar.dart +++ b/packages/flet/lib/src/controls/app_bar.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/theme.dart'; import 'create_control.dart'; import 'cupertino_app_bar.dart'; @@ -53,10 +52,8 @@ class AppBarControl extends StatelessWidget var centerTitle = control.attrBool("centerTitle", false)!; var automaticallyImplyLeading = control.attrBool("automaticallyImplyLeading", true)!; - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); - var bgcolor = HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!); + var color = control.attrColor("color", context); + var bgcolor = control.attrColor("bgcolor", context); return AppBar( leading: leadingCtrls.isNotEmpty diff --git a/packages/flet/lib/src/controls/badge.dart b/packages/flet/lib/src/controls/badge.dart index dcb3c1790..54be9eca8 100644 --- a/packages/flet/lib/src/controls/badge.dart +++ b/packages/flet/lib/src/controls/badge.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/text.dart'; import '../utils/transforms.dart'; @@ -40,11 +39,9 @@ class BadgeControl extends StatelessWidget { var offsetDetails = parseOffset(control, "offset"); - var bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); + var bgColor = control.attrColor("bgcolor", context); - var textColor = HexColor.fromString( - Theme.of(context), control.attrString("textColor", "")!); + var textColor = control.attrColor("textColor", context); bool isLabelVisible = control.attrBool("isLabelVisible", true)!; var largeSize = control.attrDouble("largeSize"); diff --git a/packages/flet/lib/src/controls/banner.dart b/packages/flet/lib/src/controls/banner.dart index ab34ac897..e5b6bb884 100644 --- a/packages/flet/lib/src/controls/banner.dart +++ b/packages/flet/lib/src/controls/banner.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -59,8 +58,7 @@ class _BannerControlState extends State { parentAdaptive: widget.parentAdaptive)) .toList(), forceActionsBelow: widget.control.attrBool("forceActionsBelow", false)!, - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!), + backgroundColor: widget.control.attrColor("bgcolor", context), ); } diff --git a/packages/flet/lib/src/controls/barchart.dart b/packages/flet/lib/src/controls/barchart.dart index 3eaf478b3..0d2ea72d0 100644 --- a/packages/flet/lib/src/controls/barchart.dart +++ b/packages/flet/lib/src/controls/barchart.dart @@ -13,7 +13,6 @@ import '../models/control.dart'; import '../utils/animations.dart'; import '../utils/borders.dart'; import '../utils/charts.dart'; -import '../utils/colors.dart'; import '../utils/gradient.dart'; import '../utils/text.dart'; import 'charts.dart'; @@ -205,8 +204,7 @@ class _BarChartControlState extends State { var chart = BarChart( BarChartData( - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!), + backgroundColor: widget.control.attrColor("bgcolor", context), minY: widget.control.attrDouble("miny"), maxY: widget.control.attrDouble("maxy"), baselineY: widget.control.attrDouble("baseliney"), @@ -231,8 +229,8 @@ class _BarChartControlState extends State { barTouchData: BarTouchData( enabled: interactive, touchTooltipData: BarTouchTooltipData( - tooltipBgColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("tooltipBgcolor", "")!), + tooltipBgColor: + widget.control.attrColor("tooltipBgColor", context), getTooltipItem: (group, groupIndex, rod, rodIndex) { var dp = viewModel.barGroups[groupIndex].barRods[rodIndex]; @@ -333,16 +331,14 @@ class _BarChartControlState extends State { bool interactiveChart, BarChartRodViewModel rodViewModel) { var bgFromY = rodViewModel.control.attrDouble("bgFromY"); var bgToY = rodViewModel.control.attrDouble("bgToY"); - var bgColor = HexColor.fromString( - theme, rodViewModel.control.attrString("bgColor", "")!); + var bgColor = rodViewModel.control.attrColor("bgColor", context); var bgGradient = parseGradient(theme, rodViewModel.control, "bgGradient"); return BarChartRodData( fromY: rodViewModel.control.attrDouble("fromY"), toY: rodViewModel.control.attrDouble("toY", 0)!, width: rodViewModel.control.attrDouble("width"), - color: HexColor.fromString( - theme, rodViewModel.control.attrString("color", "")!), + color: rodViewModel.control.attrColor("color", context), gradient: parseGradient(theme, rodViewModel.control, "gradient"), borderRadius: parseBorderRadius(rodViewModel.control, "borderRadius"), borderSide: @@ -370,8 +366,7 @@ class _BarChartControlState extends State { return BarChartRodStackItem( stackItemViewModel.control.attrDouble("fromY")!, stackItemViewModel.control.attrDouble("toY", 0)!, - HexColor.fromString( - theme, stackItemViewModel.control.attrString("color", "")!)!, + stackItemViewModel.control.attrColor("color", context)!, parseBorderSide(theme, stackItemViewModel.control, "borderSide") ?? BorderSide.none); } diff --git a/packages/flet/lib/src/controls/bottom_app_bar.dart b/packages/flet/lib/src/controls/bottom_app_bar.dart index 9004c3a93..d1d8fcf38 100644 --- a/packages/flet/lib/src/controls/bottom_app_bar.dart +++ b/packages/flet/lib/src/controls/bottom_app_bar.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -65,12 +64,9 @@ class _BottomAppBarControlState extends State height: widget.control.attrDouble("height"), elevation: elevation, shape: shape, - shadowColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("surfaceTintColor", "")!), - color: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), + shadowColor: widget.control.attrColor("shadowColor", context), + surfaceTintColor: widget.control.attrColor("surfaceTintColor", context), + color: widget.control.attrColor("bgColor", context), notchMargin: widget.control.attrDouble("notchMargin", 4.0)!, child: contentCtrls.isNotEmpty ? createControl(widget.control, contentCtrls.first.id, disabled, diff --git a/packages/flet/lib/src/controls/bottom_sheet.dart b/packages/flet/lib/src/controls/bottom_sheet.dart index a9f28a86c..f075f93ed 100644 --- a/packages/flet/lib/src/controls/bottom_sheet.dart +++ b/packages/flet/lib/src/controls/bottom_sheet.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; import 'error.dart'; @@ -89,8 +88,7 @@ class _BottomSheetControlState extends State { return content; }, isDismissible: dismissible, - backgroundColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("bgColor", "")!), + backgroundColor: widget.control.attrColor("bgColor", context), elevation: widget.control.attrDouble("elevation"), isScrollControlled: isScrollControlled, enableDrag: enableDrag, diff --git a/packages/flet/lib/src/controls/canvas.dart b/packages/flet/lib/src/controls/canvas.dart index cae8ae860..db3c7f2e9 100644 --- a/packages/flet/lib/src/controls/canvas.dart +++ b/packages/flet/lib/src/controls/canvas.dart @@ -13,7 +13,6 @@ import '../models/control.dart'; import '../models/control_tree_view_model.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/dash_path.dart'; import '../utils/drawing.dart'; import '../utils/numbers.dart'; @@ -232,9 +231,7 @@ class FletCustomPainter extends CustomPainter { } void drawColor(Canvas canvas, ControlTreeViewModel shape) { - var color = - HexColor.fromString(theme, shape.control.attrString("color", "")!) ?? - Colors.black; + var color = shape.control.attrColor("color", context) ?? Colors.black; var blendMode = BlendMode.values.firstWhere( (e) => e.name.toLowerCase() == @@ -333,9 +330,7 @@ class FletCustomPainter extends CustomPainter { void drawShadow(Canvas canvas, ControlTreeViewModel shape) { var path = buildPath(json.decode(shape.control.attrString("path", "[]")!)); - var color = - HexColor.fromString(theme, shape.control.attrString("color", "")!) ?? - Colors.black; + var color = shape.control.attrColor("color", context) ?? Colors.black; var elevation = shape.control.attrDouble("elevation", 0)!; var transparentOccluder = shape.control.attrBool("transparentOccluder", false)!; diff --git a/packages/flet/lib/src/controls/card.dart b/packages/flet/lib/src/controls/card.dart index 1abb2eca9..c5d207bc5 100644 --- a/packages/flet/lib/src/controls/card.dart +++ b/packages/flet/lib/src/controls/card.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; @@ -54,12 +53,9 @@ class CardControl extends StatelessWidget { semanticContainer: control.attrBool("isSemanticContainer", true)!, borderOnForeground: control.attrBool("showBorderOnForeground", true)!, clipBehavior: clipBehavior, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString( - Theme.of(context), control.attrString("surfaceTintColor", "")!), + color: control.attrColor("color", context), + shadowColor: control.attrColor("shadowColor", context), + surfaceTintColor: control.attrColor("surfaceTintColor", context), child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled, parentAdaptive: adaptive) @@ -72,12 +68,9 @@ class CardControl extends StatelessWidget { semanticContainer: control.attrBool("isSemanticContainer", true)!, borderOnForeground: control.attrBool("showBorderOnForeground", true)!, clipBehavior: clipBehavior, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString( - Theme.of(context), control.attrString("surfaceTintColor", "")!), + color: control.attrColor("color", context), + shadowColor: control.attrColor("shadowColor", context), + surfaceTintColor: control.attrColor("surfaceTintColor", context), child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled, parentAdaptive: adaptive) @@ -90,12 +83,9 @@ class CardControl extends StatelessWidget { semanticContainer: control.attrBool("isSemanticContainer", true)!, borderOnForeground: control.attrBool("showBorderOnForeground", true)!, clipBehavior: clipBehavior, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString( - Theme.of(context), control.attrString("surfaceTintColor", "")!), + color: control.attrColor("color", context), + shadowColor: control.attrColor("shadowColor", context), + surfaceTintColor: control.attrColor("surfaceTintColor", context), child: contentCtrls.isNotEmpty ? createControl(control, contentCtrls.first.id, disabled, parentAdaptive: adaptive) diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index 7761e46de..90d230e3a 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -125,16 +125,12 @@ class _CheckboxControlState extends State with FletStoreMixin { side: parseBorderSide(Theme.of(context), widget.control, "borderSide"), splashRadius: widget.control.attrDouble("splashRadius"), - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - focusColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("focusColor", "")!), - hoverColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("hoverColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), + focusColor: widget.control.attrColor("focusColor", context), + hoverColor: widget.control.attrColor("hoverColor", context), overlayColor: parseMaterialStateColor( Theme.of(context), widget.control, "overlayColor"), - checkColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("checkColor", "")!), + checkColor: widget.control.attrColor("checkColor", context), fillColor: parseMaterialStateColor( Theme.of(context), widget.control, "fillColor"), tristate: _tristate, diff --git a/packages/flet/lib/src/controls/chip.dart b/packages/flet/lib/src/controls/chip.dart index cee7fabde..70041b1c4 100644 --- a/packages/flet/lib/src/controls/chip.dart +++ b/packages/flet/lib/src/controls/chip.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -81,12 +80,9 @@ class _ChipControlState extends State { bool disabled = widget.control.isDisabled || widget.parentDisabled; - var bgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!); - var deleteIconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("deleteIconColor", "")!); - var disabledColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("disabledColor", "")!); + var bgcolor = widget.control.attrColor("bgcolor", context); + var deleteIconColor = widget.control.attrColor("deleteIconColor", context); + var disabledColor = widget.control.attrColor("disabledColor", context); bool onClick = widget.control.attrBool("onclick", false)!; bool onDelete = widget.control.attrBool("onDelete", false)!; @@ -134,8 +130,7 @@ class _ChipControlState extends State { parentAdaptive: widget.parentAdaptive) : null, backgroundColor: bgcolor, - checkmarkColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("checkColor", "")!), + checkmarkColor: widget.control.attrColor("checkColor", context), selected: _selected, showCheckmark: showCheckmark, deleteButtonTooltipMessage: deleteButtonTooltipMessage, @@ -159,12 +154,10 @@ class _ChipControlState extends State { labelPadding: parseEdgeInsets(widget.control, "labelPadding"), labelStyle: parseTextStyle(Theme.of(context), widget.control, "labelStyle"), - selectedColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("selectedColor", "")!), - selectedShadowColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("selectedShadowColor", "")!), - shadowColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("shadowColor", "")!), + selectedColor: widget.control.attrColor("selectedColor", context), + selectedShadowColor: + widget.control.attrColor("selectedShadowColor", context), + shadowColor: widget.control.attrColor("shadowColor", context), shape: parseOutlinedBorder(widget.control, "shape"), ), widget.parent, diff --git a/packages/flet/lib/src/controls/circle_avatar.dart b/packages/flet/lib/src/controls/circle_avatar.dart index ad0736ef6..f6e24a65b 100644 --- a/packages/flet/lib/src/controls/circle_avatar.dart +++ b/packages/flet/lib/src/controls/circle_avatar.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/images.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -68,10 +67,8 @@ class CircleAvatarControl extends StatelessWidget with FletStoreMixin { var avatar = CircleAvatar( foregroundImage: foregroundImage, backgroundImage: backgroundImage, - backgroundColor: HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!), - foregroundColor: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), + backgroundColor: control.attrColor("bgColor", context), + foregroundColor: control.attrColor("color", context), radius: control.attrDouble("radius"), minRadius: control.attrDouble("minRadius"), maxRadius: control.attrDouble("maxRadius"), diff --git a/packages/flet/lib/src/controls/container.dart b/packages/flet/lib/src/controls/container.dart index 6e53d700b..16dc91510 100644 --- a/packages/flet/lib/src/controls/container.dart +++ b/packages/flet/lib/src/controls/container.dart @@ -9,7 +9,6 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/animations.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/gradient.dart'; import '../utils/images.dart'; @@ -60,8 +59,7 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { Widget build(BuildContext context) { debugPrint("Container build: ${control.id}"); - var bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); + var bgColor = control.attrColor("bgColor", context); var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); bool ink = control.attrBool("ink", false)!; @@ -189,8 +187,7 @@ class ContainerControl extends StatelessWidget with FletStoreMixin { } : null, borderRadius: borderRadius, - splashColor: HexColor.fromString( - Theme.of(context), control.attrString("inkColor", "")!), + splashColor: control.attrColor("inkColor", context), child: Container( padding: parseEdgeInsets(control, "padding"), alignment: parseAlignment(control, "alignment"), diff --git a/packages/flet/lib/src/controls/cupertino_activity_indicator.dart b/packages/flet/lib/src/controls/cupertino_activity_indicator.dart index dd573785a..7329cfa05 100644 --- a/packages/flet/lib/src/controls/cupertino_activity_indicator.dart +++ b/packages/flet/lib/src/controls/cupertino_activity_indicator.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class CupertinoActivityIndicatorControl extends StatelessWidget { @@ -28,8 +26,7 @@ class CupertinoActivityIndicatorControl extends StatelessWidget { CupertinoActivityIndicator( radius: control.attrDouble("radius", 10)!, animating: control.attrBool("animating", true)!, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!), + color: control.attrColor("color", context), ), parent, control); diff --git a/packages/flet/lib/src/controls/cupertino_app_bar.dart b/packages/flet/lib/src/controls/cupertino_app_bar.dart index 59e7264b7..62d971014 100644 --- a/packages/flet/lib/src/controls/cupertino_app_bar.dart +++ b/packages/flet/lib/src/controls/cupertino_app_bar.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; @@ -44,8 +43,7 @@ class CupertinoAppBarControl extends StatelessWidget control.attrBool("automaticallyImplyMiddle", true)!; var transitionBetweenRoutes = control.attrBool("transitionBetweenRoutes", true)!; - var bgcolor = HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!); + var bgcolor = control.attrColor("bgcolor", context); return CupertinoNavigationBar( leading: leadingCtrls.isNotEmpty @@ -78,9 +76,7 @@ class CupertinoAppBarControl extends StatelessWidget @override bool shouldFullyObstruct(BuildContext context) { final Color backgroundColor = CupertinoDynamicColor.maybeResolve( - HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!), - context) ?? + control.attrColor("bgcolor", context), context) ?? CupertinoTheme.of(context).barBackgroundColor; return backgroundColor.alpha == 0xFF; } diff --git a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart index 45783a1c4..37e3b9d02 100644 --- a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart +++ b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -38,8 +36,7 @@ class _CupertinoBottomSheetControlState bool disabled = widget.control.isDisabled || widget.parentDisabled; var height = widget.control.attrDouble("height"); - var bgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!); + var bgcolor = widget.control.attrColor("bgcolor", context); var padding = parseEdgeInsets(widget.control, "padding"); var contentCtrls = diff --git a/packages/flet/lib/src/controls/cupertino_button.dart b/packages/flet/lib/src/controls/cupertino_button.dart index af81de9f4..ba376d9fc 100644 --- a/packages/flet/lib/src/controls/cupertino_button.dart +++ b/packages/flet/lib/src/controls/cupertino_button.dart @@ -6,7 +6,6 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; @@ -44,16 +43,15 @@ class _CupertinoButtonControlState extends State { String? text = widget.control.attrString("text"); IconData? icon = parseIcon(widget.control.attrString("icon", "")!); - Color? iconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("iconColor", "")!); + Color? iconColor = widget.control.attrColor("iconColor", context); // IconButton props below double? iconSize = widget.control.attrDouble("iconSize"); bool selected = widget.control.attrBool("selected", false)!; IconData? selectedIcon = parseIcon(widget.control.attrString("selectedIcon", "")!); - Color? selectedIconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("selectedIconColor", "")!); + Color? selectedIconColor = + widget.control.attrColor("selectedIconColor", context); Widget? content; List children = []; @@ -91,13 +89,10 @@ class _CupertinoButtonControlState extends State { double pressedOpacity = widget.control.attrDouble("opacityOnClick", 0.4)!; double minSize = widget.control.attrDouble("minSize", 44.0)!; String url = widget.control.attrString("url", "")!; - Color disabledColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("disabledColor", "")!) ?? + Color disabledColor = widget.control.attrColor("disabledColor", context) ?? CupertinoColors.quaternarySystemFill; - Color? bgColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!); - Color? color = HexColor.fromString( - Theme.of(context), widget.control.attrString("color", "")!); + Color? bgColor = widget.control.attrColor("bgColor", context); + Color? color = widget.control.attrColor("color", context); AlignmentGeometry alignment = parseAlignment(widget.control, "alignment") ?? Alignment.center; BorderRadius borderRadius = diff --git a/packages/flet/lib/src/controls/cupertino_checkbox.dart b/packages/flet/lib/src/controls/cupertino_checkbox.dart index 405dee467..678f1bdd1 100644 --- a/packages/flet/lib/src/controls/cupertino_checkbox.dart +++ b/packages/flet/lib/src/controls/cupertino_checkbox.dart @@ -96,12 +96,9 @@ class _CheckboxControlState extends State { value: _value, activeColor: HexColor.fromString(Theme.of(context), widget.control.attrString("activeColor", "primary")!), - checkColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("checkColor", "")!), - focusColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("focusColor", "")!), - inactiveColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("inactiveColor", "")!), + checkColor: widget.control.attrColor("checkColor", context), + focusColor: widget.control.attrColor("focusColor", context), + inactiveColor: widget.control.attrColor("inactiveColor", context), tristate: _tristate, onChanged: !disabled ? (bool? value) { diff --git a/packages/flet/lib/src/controls/cupertino_date_picker.dart b/packages/flet/lib/src/controls/cupertino_date_picker.dart index 88e713a51..4cbd262ed 100644 --- a/packages/flet/lib/src/controls/cupertino_date_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_date_picker.dart @@ -1,10 +1,8 @@ import 'package:collection/collection.dart'; import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; import 'error.dart'; @@ -35,8 +33,7 @@ class _CupertinoDatePickerControlState debugPrint("CupertinoDatePicker build: ${widget.control.id}"); bool showDayOfWeek = widget.control.attrBool("showDayOfWeek", false)!; - Color? bgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!); + Color? bgcolor = widget.control.attrColor("bgcolor", context); DateTime? value = widget.control.attrDateTime("value"); DateTime? firstDate = widget.control.attrDateTime("firstDate"); DateTime? lastDate = widget.control.attrDateTime("lastDate"); diff --git a/packages/flet/lib/src/controls/cupertino_list_tile.dart b/packages/flet/lib/src/controls/cupertino_list_tile.dart index 0bb235ee2..40c0ec9b9 100644 --- a/packages/flet/lib/src/controls/cupertino_list_tile.dart +++ b/packages/flet/lib/src/controls/cupertino_list_tile.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -72,10 +70,8 @@ class CupertinoListTileControl extends StatelessWidget { parentAdaptive: parentAdaptive) : null; - Color? backgroundColor = HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!); - Color? bgcolorActivated = HexColor.fromString( - Theme.of(context), control.attrString("bgcolorActivated", "")!); + Color? backgroundColor = control.attrColor("bgcolor", context); + Color? bgcolorActivated = control.attrColor("bgcolorActivated", context); var padding = parseEdgeInsets(control, "contentPadding"); diff --git a/packages/flet/lib/src/controls/cupertino_navigation_bar.dart b/packages/flet/lib/src/controls/cupertino_navigation_bar.dart index 9c532b11a..7ff2541a7 100644 --- a/packages/flet/lib/src/controls/cupertino_navigation_bar.dart +++ b/packages/flet/lib/src/controls/cupertino_navigation_bar.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -60,12 +59,9 @@ class _CupertinoNavigationBarControlState .where((c) => c.isVisible && c.name == null) .map((c) => c.id), (content, viewModel) { return CupertinoTabBar( - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - inactiveColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("inactiveColor", "")!) ?? + backgroundColor: widget.control.attrColor("bgColor", context), + activeColor: widget.control.attrColor("activeColor", context), + inactiveColor: widget.control.attrColor("inactiveColor", context) ?? CupertinoColors.inactiveGray, iconSize: widget.control.attrDouble("iconSize", 30.0)!, currentIndex: _selectedIndex, diff --git a/packages/flet/lib/src/controls/cupertino_picker.dart b/packages/flet/lib/src/controls/cupertino_picker.dart index e8b964cdb..f723d0ba3 100644 --- a/packages/flet/lib/src/controls/cupertino_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_picker.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; const double _kItemExtent = 32.0; @@ -53,8 +51,7 @@ class _CupertinoPickerControlState extends State { double offAxisFraction = widget.control.attrDouble("offAxisFraction", 0.0)!; bool useMagnifier = widget.control.attrBool("useMagnifier", false)!; bool looping = widget.control.attrBool("looping", false)!; - Color? backgroundColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!); + Color? backgroundColor = widget.control.attrColor("bgColor", context); Widget picker = CupertinoPicker( backgroundColor: backgroundColor, diff --git a/packages/flet/lib/src/controls/cupertino_radio.dart b/packages/flet/lib/src/controls/cupertino_radio.dart index b7495bd0c..56878807a 100644 --- a/packages/flet/lib/src/controls/cupertino_radio.dart +++ b/packages/flet/lib/src/controls/cupertino_radio.dart @@ -91,12 +91,10 @@ class _CupertinoRadioControlState extends State value: value, useCheckmarkStyle: widget.control.attrBool("useCheckmarkStyle", false)!, - fillColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("fillColor", "")!), + fillColor: widget.control.attrColor("fillColor", context), activeColor: HexColor.fromString(Theme.of(context), widget.control.attrString("activeColor", "primary")!), - inactiveColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("inactiveColor", "")!), + inactiveColor: widget.control.attrColor("inactiveColor", context), onChanged: !disabled ? (String? value) { _onChange(ancestorId, value); diff --git a/packages/flet/lib/src/controls/cupertino_segmented_button.dart b/packages/flet/lib/src/controls/cupertino_segmented_button.dart index 0be6c06e3..263d78de5 100644 --- a/packages/flet/lib/src/controls/cupertino_segmented_button.dart +++ b/packages/flet/lib/src/controls/cupertino_segmented_button.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -40,12 +38,9 @@ class _CupertinoSegmentedButtonControlState bool? adaptive = widget.control.attrBool("adaptive") ?? widget.parentAdaptive; - var borderColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("borderColor", "")!); - var selectedColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("selectedColor", "")!); - var unselectedColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("unselectedColor", "")!); + var borderColor = widget.control.attrColor("borderColor", context); + var selectedColor = widget.control.attrColor("selectedColor", context); + var unselectedColor = widget.control.attrColor("unselectedColor", context); List ctrls = widget.children.where((c) => c.isVisible).toList(); int? selectedIndex = widget.control.attrInt("selectedIndex"); diff --git a/packages/flet/lib/src/controls/cupertino_slider.dart b/packages/flet/lib/src/controls/cupertino_slider.dart index 9760db4f8..d0224834b 100644 --- a/packages/flet/lib/src/controls/cupertino_slider.dart +++ b/packages/flet/lib/src/controls/cupertino_slider.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/debouncer.dart'; import '../utils/desktop.dart'; import 'create_control.dart'; @@ -76,10 +74,8 @@ class _CupertinoSliderControlState extends State { min: min, max: max, divisions: divisions, - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - thumbColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("thumbColor", "")!) ?? + activeColor: widget.control.attrColor("activeColor", context), + thumbColor: widget.control.attrColor("thumbColor", context) ?? CupertinoColors.white, onChanged: !disabled ? (double value) { diff --git a/packages/flet/lib/src/controls/cupertino_sliding_segmented_button.dart b/packages/flet/lib/src/controls/cupertino_sliding_segmented_button.dart index 20b6467dd..95c1de146 100644 --- a/packages/flet/lib/src/controls/cupertino_sliding_segmented_button.dart +++ b/packages/flet/lib/src/controls/cupertino_sliding_segmented_button.dart @@ -1,9 +1,7 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -41,14 +39,12 @@ class _CupertinoSlidingSegmentedButtonControlState bool? adaptive = widget.control.attrBool("adaptive") ?? widget.parentAdaptive; - var thumbColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("thumbColor", "")!) ?? + var thumbColor = widget.control.attrColor("thumbColor", context) ?? const CupertinoDynamicColor.withBrightness( color: Color(0xFFFFFFFF), darkColor: Color(0xFF636366), ); - var bgColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!) ?? + var bgColor = widget.control.attrColor("bgColor", context) ?? CupertinoColors.tertiarySystemFill; List ctrls = widget.children.where((c) => c.isVisible).toList(); int? selectedIndex = widget.control.attrInt("selectedIndex"); diff --git a/packages/flet/lib/src/controls/cupertino_switch.dart b/packages/flet/lib/src/controls/cupertino_switch.dart index abc0eba7a..0028af4db 100644 --- a/packages/flet/lib/src/controls/cupertino_switch.dart +++ b/packages/flet/lib/src/controls/cupertino_switch.dart @@ -86,12 +86,10 @@ class _CupertinoSwitchControlState extends State { var swtch = CupertinoSwitch( autofocus: autofocus, focusNode: _focusNode, - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), thumbColor: materialThumbColor?.resolve({}), trackColor: materialTrackColor?.resolve({}), - focusColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("focusColor", "")!), + focusColor: widget.control.attrColor("focusColor", context), value: _value, onChanged: !disabled ? (bool value) { diff --git a/packages/flet/lib/src/controls/cupertino_textfield.dart b/packages/flet/lib/src/controls/cupertino_textfield.dart index 944af5cd3..c4c5277b4 100644 --- a/packages/flet/lib/src/controls/cupertino_textfield.dart +++ b/packages/flet/lib/src/controls/cupertino_textfield.dart @@ -6,7 +6,6 @@ import 'package:flutter/services.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/gradient.dart'; import '../utils/shadows.dart'; import '../utils/text.dart'; @@ -123,19 +122,15 @@ class _CupertinoTextFieldControlState extends State { bool password = widget.control.attrBool("password", false)!; bool onChange = widget.control.attrBool("onChange", false)!; - var cursorColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("cursorColor", "")!); - var selectionColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("selectionColor", "")!); + var cursorColor = widget.control.attrColor("cursorColor", context); + var selectionColor = widget.control.attrColor("selectionColor", context); int? maxLength = widget.control.attrInt("maxLength"); var textSize = widget.control.attrDouble("textSize"); - var color = HexColor.fromString( - Theme.of(context), widget.control.attrString("color", "")!); - var focusedColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("focusedColor", "")!); + var color = widget.control.attrColor("color", context); + var focusedColor = widget.control.attrColor("focusedColor", context); TextStyle? textStyle = parseTextStyle(Theme.of(context), widget.control, "textStyle"); @@ -198,8 +193,7 @@ class _CupertinoTextFieldControlState extends State { BoxBorder? border; double borderWidth = widget.control.attrDouble("borderWidth") ?? 1.0; - Color borderColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("borderColor", "")!) ?? + Color borderColor = widget.control.attrColor("borderColor", context) ?? const Color(0xFF000000); try { @@ -243,8 +237,7 @@ class _CupertinoTextFieldControlState extends State { e.name.toLowerCase() == widget.control.attrString("blendMode", "")!.toLowerCase()); - var bgColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!); + var bgColor = widget.control.attrColor("bgColor", context); // for adaptive TextField use label for placeholder var placeholder = widget.control.attrString("placeholderText") ?? widget.control.attrString("label"); diff --git a/packages/flet/lib/src/controls/cupertino_timer_picker.dart b/packages/flet/lib/src/controls/cupertino_timer_picker.dart index ecb0faef3..f1055e646 100644 --- a/packages/flet/lib/src/controls/cupertino_timer_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_timer_picker.dart @@ -1,10 +1,8 @@ import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class CupertinoTimerPickerControl extends StatefulWidget { @@ -44,8 +42,7 @@ class _CupertinoTimerPickerControlState widget.control.attrString("mode", "")!.toLowerCase(), orElse: () => CupertinoTimerPickerMode.hms); - Color? backgroundColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!); + Color? backgroundColor = widget.control.attrColor("bgColor", context); Widget picker = CupertinoTimerPicker( mode: mode, diff --git a/packages/flet/lib/src/controls/divider.dart b/packages/flet/lib/src/controls/divider.dart index e0021da58..4b445eed1 100644 --- a/packages/flet/lib/src/controls/divider.dart +++ b/packages/flet/lib/src/controls/divider.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class DividerControl extends StatelessWidget { @@ -18,8 +17,7 @@ class DividerControl extends StatelessWidget { var leadingIndent = control.attrDouble("leadingIndent"); var trailingIndent = control.attrDouble("trailingIndent"); var thickness = control.attrDouble("thickness"); - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); + var color = widget.control.attrColor("color", context); return baseControl( context, diff --git a/packages/flet/lib/src/controls/dropdown.dart b/packages/flet/lib/src/controls/dropdown.dart index 72ef1305b..fb1100c2b 100644 --- a/packages/flet/lib/src/controls/dropdown.dart +++ b/packages/flet/lib/src/controls/dropdown.dart @@ -4,7 +4,6 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -77,16 +76,13 @@ class _DropdownControlState extends State with FletStoreMixin { var hintCtrl = widget.children.where((c) => c.name == "hint" && c.isVisible); - var color = HexColor.fromString( - Theme.of(context), widget.control.attrString("color", "")!); - var focusedColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("focusedColor", "")!); - var bgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgcolor", "")!); - var iconEnabledColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("iconEnabledColor", "")!); - var iconDisabledColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("iconDisabledColor", "")!); + var color = widget.control.attrColor("color", context); + var focusedColor = widget.control.attrColor("focusedColor", context); + var bgcolor = widget.control.attrColor("bgcolor", context); + var iconEnabledColor = + widget.control.attrColor("iconEnabledColor", context); + var iconDisabledColor = + widget.control.attrColor("iconDisabledColor", context); TextStyle? textStyle = parseTextStyle(Theme.of(context), widget.control, "textStyle"); @@ -111,13 +107,13 @@ class _DropdownControlState extends State with FletStoreMixin { return DropdownMenuItem( enabled: !(disabled || itemCtrl.isDisabled), value: itemCtrl.attrs["key"] ?? itemCtrl.attrs["text"] ?? itemCtrl.id, - child: itemChild, alignment: align ?? AlignmentDirectional.centerStart, onTap: !(disabled || itemCtrl.isDisabled) ? () { widget.backend.triggerControlEvent(itemCtrl.id, "click"); } : null, + child: itemChild, ); }).toList(); diff --git a/packages/flet/lib/src/controls/elevated_button.dart b/packages/flet/lib/src/controls/elevated_button.dart index ba4567fc6..3486abd8c 100644 --- a/packages/flet/lib/src/controls/elevated_button.dart +++ b/packages/flet/lib/src/controls/elevated_button.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -88,8 +87,7 @@ class _ElevatedButtonControlState extends State String text = widget.control.attrString("text", "")!; String url = widget.control.attrString("url", "")!; IconData? icon = parseIcon(widget.control.attrString("icon", "")!); - Color? iconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("iconColor", "")!); + Color? iconColor = widget.control.attrColor("iconColor", context); var contentCtrls = widget.children.where((c) => c.name == "content"); var clipBehavior = Clip.values.firstWhere( (e) => diff --git a/packages/flet/lib/src/controls/expansion_panel.dart b/packages/flet/lib/src/controls/expansion_panel.dart index 38e115235..1942ebb40 100644 --- a/packages/flet/lib/src/controls/expansion_panel.dart +++ b/packages/flet/lib/src/controls/expansion_panel.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -49,10 +48,9 @@ class _ExpansionPanelListControlState extends State bool? adaptive = widget.control.attrBool("adaptive") ?? widget.parentAdaptive; - var dividerColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("dividerColor", "")!); - var expandedIconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("expandedIconColor", "")!); + var dividerColor = widget.control.attrColor("dividerColor", context); + var expandedIconColor = + widget.control.attrColor("expandedIconColor", context); var expandedHeaderPadding = parseEdgeInsets(widget.control, "expandedHeaderPadding"); @@ -83,8 +81,7 @@ class _ExpansionPanelListControlState extends State var isExpanded = panelView.control.attrBool("expanded", false)!; var canTapHeader = panelView.control.attrBool("canTapHeader", false)!; - var bgColor = HexColor.fromString(Theme.of(context), - panelView.control.attrString("bgColor", "")!); + var bgColor = widget.control.attrColor("bgColor", context); return ExpansionPanel( backgroundColor: bgColor, diff --git a/packages/flet/lib/src/controls/expansion_tile.dart b/packages/flet/lib/src/controls/expansion_tile.dart index 2e236122b..3ff5b555f 100644 --- a/packages/flet/lib/src/controls/expansion_tile.dart +++ b/packages/flet/lib/src/controls/expansion_tile.dart @@ -4,7 +4,6 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -49,18 +48,12 @@ class ExpansionTileControl extends StatelessWidget { bool maintainState = control.attrBool("maintainState", false)!; bool initiallyExpanded = control.attrBool("initiallyExpanded", false)!; - var iconColor = HexColor.fromString( - Theme.of(context), control.attrString("iconColor", "")!); - var textColor = HexColor.fromString( - Theme.of(context), control.attrString("textColor", "")!); - var bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); - var collapsedBgColor = HexColor.fromString( - Theme.of(context), control.attrString("collapsedBgColor", "")!); - var collapsedIconColor = HexColor.fromString( - Theme.of(context), control.attrString("collapsedIconColor", "")!); - var collapsedTextColor = HexColor.fromString( - Theme.of(context), control.attrString("collapsedTextColor", "")!); + var iconColor = control.attrColor("iconColor", context); + var textColor = control.attrColor("textColor", context); + var bgColor = control.attrColor("bgColor", context); + var collapsedBgColor = control.attrColor("collapsedBgColor", context); + var collapsedIconColor = control.attrColor("collapsedIconColor", context); + var collapsedTextColor = control.attrColor("collapsedTextColor", context); var affinity = ListTileControlAffinity.values.firstWhere( (e) => diff --git a/packages/flet/lib/src/controls/floating_action_button.dart b/packages/flet/lib/src/controls/floating_action_button.dart index cb688ea69..f46970eab 100644 --- a/packages/flet/lib/src/controls/floating_action_button.dart +++ b/packages/flet/lib/src/controls/floating_action_button.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -39,16 +38,11 @@ class FloatingActionButtonControl extends StatelessWidget { double? hoverElevation = control.attrDouble("hoverElevation"); double? highlightElevation = control.attrDouble("highlightElevation"); double? focusElevation = control.attrDouble("focusElevation"); - Color? bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); - Color? foregroundColor = HexColor.fromString( - Theme.of(context), control.attrString("foregroundColor", "")!); - Color? splashColor = HexColor.fromString( - Theme.of(context), control.attrString("splashColor", "")!); - Color? hoverColor = HexColor.fromString( - Theme.of(context), control.attrString("hoverColor", "")!); - Color? focusColor = HexColor.fromString( - Theme.of(context), control.attrString("focusColor", "")!); + Color? bgColor = control.attrColor("bgColor", context); + Color? foregroundColor = control.attrColor("foregroundColor", context); + Color? splashColor = control.attrColor("splashColor", context); + Color? hoverColor = control.attrColor("hoverColor", context); + Color? focusColor = control.attrColor("focusColor", context); OutlinedBorder? shape = parseOutlinedBorder(control, "shape"); var clipBehavior = Clip.values.firstWhere( (e) => diff --git a/packages/flet/lib/src/controls/form_field.dart b/packages/flet/lib/src/controls/form_field.dart index 46b7d9b66..9d09fb519 100644 --- a/packages/flet/lib/src/controls/form_field.dart +++ b/packages/flet/lib/src/controls/form_field.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/text.dart'; @@ -59,16 +58,12 @@ InputDecoration buildInputDecoration( var suffixIcon = parseIcon(control.attrString("suffixIcon", "")!); var suffixText = control.attrString("suffixText"); - var bgcolor = HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!); - var focusedBgcolor = HexColor.fromString( - Theme.of(context), control.attrString("focusedBgcolor", "")!); + var bgcolor = control.attrColor("bgcolor", context); + var focusedBgcolor = control.attrColor("focusedBgcolor", context); var borderRadius = parseBorderRadius(control, "borderRadius"); - var borderColor = HexColor.fromString( - Theme.of(context), control.attrString("borderColor", "")!); - var focusedBorderColor = HexColor.fromString( - Theme.of(context), control.attrString("focusedBorderColor", "")!); + var borderColor = control.attrColor("borderColor", context); + var focusedBorderColor = control.attrColor("focusedBorderColor", context); var borderWidth = control.attrDouble("borderWidth"); var focusedBorderWidth = control.attrDouble("focusedBorderWidth"); diff --git a/packages/flet/lib/src/controls/icon.dart b/packages/flet/lib/src/controls/icon.dart index 4cdc78460..3ce626e5a 100644 --- a/packages/flet/lib/src/controls/icon.dart +++ b/packages/flet/lib/src/controls/icon.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import 'create_control.dart'; @@ -18,8 +17,7 @@ class IconControl extends StatelessWidget { var name = control.attrString("name", "")!; var size = control.attrDouble("size"); var semanticsLabel = control.attrString("semanticsLabel"); - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); + var color = control.attrColor("color", context); return constrainedControl( context, diff --git a/packages/flet/lib/src/controls/icon_button.dart b/packages/flet/lib/src/controls/icon_button.dart index 22397cfd2..81131f6c0 100644 --- a/packages/flet/lib/src/controls/icon_button.dart +++ b/packages/flet/lib/src/controls/icon_button.dart @@ -4,7 +4,6 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; @@ -79,22 +78,16 @@ class _IconButtonControlState extends State IconData? icon = parseIcon(widget.control.attrString("icon", "")!); IconData? selectedIcon = parseIcon(widget.control.attrString("selectedIcon", "")!); - Color? iconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("iconColor", "")!); - Color? highlightColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("highlightColor", "")!); - Color? selectedIconColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("selectedIconColor", "")!); - Color? bgColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!); - Color? disabledColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("disabledColor", "")!); - Color? hoverColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("hoverColor", "")!); - Color? splashColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("splashColor", "")!); - Color? focusColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("focusColor", "")!); + Color? iconColor = widget.control.attrColor("iconColor", context); + Color? highlightColor = + widget.control.attrColor("highlightColor", context); + Color? selectedIconColor = + widget.control.attrColor("selectedIconColor", context); + Color? bgColor = widget.control.attrColor("bgColor", context); + Color? disabledColor = widget.control.attrColor("disabledColor", context); + Color? hoverColor = widget.control.attrColor("hoverColor", context); + Color? splashColor = widget.control.attrColor("splashColor", context); + Color? focusColor = widget.control.attrColor("focusColor", context); double? iconSize = widget.control.attrDouble("iconSize"); double? splashRadius = widget.control.attrDouble("splashRadius"); var padding = parseEdgeInsets(widget.control, "padding"); diff --git a/packages/flet/lib/src/controls/image.dart b/packages/flet/lib/src/controls/image.dart index f0fd712a4..12cd8f9c0 100644 --- a/packages/flet/lib/src/controls/image.dart +++ b/packages/flet/lib/src/controls/image.dart @@ -10,7 +10,6 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/collections.dart'; -import '../utils/colors.dart'; import '../utils/images.dart'; import 'create_control.dart'; import 'error.dart'; @@ -50,8 +49,7 @@ class ImageControl extends StatelessWidget with FletStoreMixin { var colorBlendMode = BlendMode.values.firstWhereOrNull((e) => e.name.toLowerCase() == control.attrString("colorBlendMode", "")!.toLowerCase()); - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); + var color = control.attrColor("color", context); String? semanticsLabel = control.attrString("semanticsLabel"); var gaplessPlayback = control.attrBool("gaplessPlayback"); var excludeFromSemantics = control.attrBool("excludeFromSemantics", false)!; diff --git a/packages/flet/lib/src/controls/linechart.dart b/packages/flet/lib/src/controls/linechart.dart index cb9a7b79f..4380f29ab 100644 --- a/packages/flet/lib/src/controls/linechart.dart +++ b/packages/flet/lib/src/controls/linechart.dart @@ -324,9 +324,9 @@ class _LineChartControlState extends State { }).toList(); }, touchTooltipData: LineTouchTooltipData( - tooltipBgColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("tooltipBgcolor", "")!) ?? - const Color.fromRGBO(96, 125, 139, 1), + tooltipBgColor: + widget.control.attrColor("tooltipBgColor", context) ?? + const Color.fromRGBO(96, 125, 139, 1), getTooltipItems: (touchedSpots) { return touchedSpots.map((spot) { var dp = viewModel.dataSeries[spot.barIndex] @@ -402,20 +402,18 @@ class _LineChartControlState extends State { LineChartBarData getBarData(ThemeData theme, Control parent, bool interactiveChart, LineChartDataViewModel dataViewModel) { - Color? aboveLineBgcolor = HexColor.fromString( - theme, dataViewModel.control.attrString("aboveLineBgcolor", "")!); + Color? aboveLineBgcolor = + widget.control.attrColor("aboveLineBgcolor", context); Gradient? aboveLineGradient = parseGradient(theme, dataViewModel.control, "aboveLineGradient"); - Color? belowLineBgcolor = HexColor.fromString( - theme, dataViewModel.control.attrString("belowLineBgcolor", "")!); + Color? belowLineBgcolor = + widget.control.attrColor("belowLineBgcolor", context); Gradient? belowLineGradient = parseGradient(theme, dataViewModel.control, "belowLineGradient"); var dashPattern = dataViewModel.control.attrString("dashPattern"); var shadow = parseBoxShadow(Theme.of(context), dataViewModel.control, "shadow"); - Color barColor = HexColor.fromString( - theme, dataViewModel.control.attrString("color", "")!) ?? - Colors.cyan; + Color barColor = widget.control.attrColor("color", context) ?? Colors.cyan; Gradient? barGradient = parseGradient(theme, dataViewModel.control, "gradient"); FlLine? aboveLine = diff --git a/packages/flet/lib/src/controls/list_tile.dart b/packages/flet/lib/src/controls/list_tile.dart index c801448d2..128c34bec 100644 --- a/packages/flet/lib/src/controls/list_tile.dart +++ b/packages/flet/lib/src/controls/list_tile.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -120,18 +119,12 @@ class ListTileControl extends StatelessWidget with FletStoreMixin { enableFeedback: enableFeedback, minLeadingWidth: minLeadingWidth, minVerticalPadding: minVerticalPadding, - selectedTileColor: HexColor.fromString( - Theme.of(context), control.attrString("selectedTileColor", "")!), - selectedColor: HexColor.fromString( - Theme.of(context), control.attrString("selectedColor", "")!), - focusColor: HexColor.fromString( - Theme.of(context), control.attrString("focusColor", "")!), - tileColor: HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!), - splashColor: HexColor.fromString( - Theme.of(context), control.attrString("bgcolorActivated", "")!), - hoverColor: HexColor.fromString( - Theme.of(context), control.attrString("hoverColor", "")!), + selectedTileColor: control.attrColor("selectedTileColor", context), + selectedColor: control.attrColor("selectedColor", context), + focusColor: control.attrColor("focusColor", context), + tileColor: control.attrColor("bgcolor", context), + splashColor: control.attrColor("bgcolorActivated", context), + hoverColor: control.attrColor("hoverColor", context), leading: leadingCtrls.isNotEmpty ? createControl(control, leadingCtrls.first.id, disabled, parentAdaptive: adaptive) diff --git a/packages/flet/lib/src/controls/navigation_bar.dart b/packages/flet/lib/src/controls/navigation_bar.dart index 8ee4b26ff..3dc5c5010 100644 --- a/packages/flet/lib/src/controls/navigation_bar.dart +++ b/packages/flet/lib/src/controls/navigation_bar.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import 'create_control.dart'; import 'cupertino_navigation_bar.dart'; @@ -86,16 +85,13 @@ class _NavigationBarControlState extends State ? Duration(milliseconds: animationDuration) : null, elevation: widget.control.attrDouble("elevation"), - shadowColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("surfaceTintColor", "")!), - indicatorColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("indicatorColor", "")!), + shadowColor: widget.control.attrColor("shadowColor", context), + surfaceTintColor: + widget.control.attrColor("surfaceTintColor", context), + indicatorColor: widget.control.attrColor("indicatorColor", context), indicatorShape: parseOutlinedBorder(widget.control, "indicatorShape"), - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), + backgroundColor: widget.control.attrColor("bgColor", context), selectedIndex: _selectedIndex, onDestinationSelected: _destinationChanged, destinations: viewModel.controlViews.map((destView) { diff --git a/packages/flet/lib/src/controls/navigation_drawer.dart b/packages/flet/lib/src/controls/navigation_drawer.dart index 08580fcf3..8b4507f3a 100644 --- a/packages/flet/lib/src/controls/navigation_drawer.dart +++ b/packages/flet/lib/src/controls/navigation_drawer.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import 'create_control.dart'; @@ -93,16 +92,12 @@ class _NavigationDrawerControlState extends State }).toList(); return NavigationDrawer( elevation: widget.control.attrDouble("elevation"), - indicatorColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("indicatorColor", "")!), + indicatorColor: widget.control.attrColor("indicatorColor", context), indicatorShape: parseOutlinedBorder(widget.control, "indicatorShape"), - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), + backgroundColor: widget.control.attrColor("bgColor", context), selectedIndex: _selectedIndex, - shadowColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("shadowColor", "")!), - surfaceTintColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("surfaceTintColor", "")!), + shadowColor: widget.control.attrColor("shadowColor", context), + surfaceTintColor: widget.control.attrColor("surfaceTintColor", context), tilePadding: parseEdgeInsets(widget.control, "tilePadding") ?? const EdgeInsets.symmetric(horizontal: 12.0), onDestinationSelected: _destinationChanged, diff --git a/packages/flet/lib/src/controls/navigation_rail.dart b/packages/flet/lib/src/controls/navigation_rail.dart index e90e2ef69..5d588222b 100644 --- a/packages/flet/lib/src/controls/navigation_rail.dart +++ b/packages/flet/lib/src/controls/navigation_rail.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import 'create_control.dart'; @@ -96,10 +95,9 @@ class _NavigationRailControlState extends State minWidth: widget.control.attrDouble("minWidth"), minExtendedWidth: widget.control.attrDouble("minExtendedWidth"), groupAlignment: widget.control.attrDouble("groupAlignment"), - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), - indicatorColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("indicatorColor", "")!), + backgroundColor: widget.control.attrColor("bgColor", context), + indicatorColor: + widget.control.attrColor("indicatorColor", context), leading: leadingCtrls.isNotEmpty ? createControl( widget.control, leadingCtrls.first.id, disabled, diff --git a/packages/flet/lib/src/controls/outlined_button.dart b/packages/flet/lib/src/controls/outlined_button.dart index ba9036745..472e192a4 100644 --- a/packages/flet/lib/src/controls/outlined_button.dart +++ b/packages/flet/lib/src/controls/outlined_button.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -63,8 +62,7 @@ class _OutlinedButtonControlState extends State String text = widget.control.attrString("text", "")!; IconData? icon = parseIcon(widget.control.attrString("icon", "")!); - Color? iconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("iconColor", "")!); + Color? iconColor = widget.control.attrColor("iconColor", context); var contentCtrls = widget.children.where((c) => c.name == "content"); String url = widget.control.attrString("url", "")!; String? urlTarget = widget.control.attrString("urlTarget"); diff --git a/packages/flet/lib/src/controls/page.dart b/packages/flet/lib/src/controls/page.dart index c80e0bdbf..12c1e9e1c 100644 --- a/packages/flet/lib/src/controls/page.dart +++ b/packages/flet/lib/src/controls/page.dart @@ -24,7 +24,6 @@ import '../routing/route_state.dart'; import '../routing/router_delegate.dart'; import '../utils/alignment.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/desktop.dart'; import '../utils/edge_insets.dart'; import '../utils/images.dart'; @@ -294,8 +293,7 @@ class _PageControlState extends State with FletStoreMixin { // window params var windowTitle = widget.control.attrString("title", "")!; - var windowBgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("windowBgcolor", "")!); + var windowBgcolor = widget.control.attrColor("windowBgcolor", context); var windowWidth = widget.control.attrDouble("windowWidth"); var windowHeight = widget.control.attrDouble("windowHeight"); var windowMinWidth = widget.control.attrDouble("windowMinWidth"); @@ -993,8 +991,7 @@ class _ViewControlState extends State with FletStoreMixin { Widget scaffold = Scaffold( key: bar == null || bar is AppBarControl ? scaffoldKey : null, - backgroundColor: HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!) ?? + backgroundColor: control.attrColor("bgcolor", context) ?? CupertinoTheme.of(context).scaffoldBackgroundColor, appBar: bar is AppBarControl ? bar : null, drawer: drawerView != null @@ -1052,8 +1049,7 @@ class _ViewControlState extends State with FletStoreMixin { if (bar is CupertinoAppBarControl) { scaffold = CupertinoPageScaffold( key: scaffoldKey, - backgroundColor: HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!), + backgroundColor: control.attrColor("bgcolor", context), navigationBar: bar as ObstructingPreferredSizeWidget, child: scaffold); } diff --git a/packages/flet/lib/src/controls/pagelet.dart b/packages/flet/lib/src/controls/pagelet.dart index a25537e7c..0d949d080 100644 --- a/packages/flet/lib/src/controls/pagelet.dart +++ b/packages/flet/lib/src/controls/pagelet.dart @@ -8,7 +8,6 @@ import '../models/app_state.dart'; import '../models/control.dart'; import '../models/controls_view_model.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import 'app_bar.dart'; import 'create_control.dart'; import 'cupertino_app_bar.dart'; @@ -205,8 +204,7 @@ class _PageletControlState extends State with FletStoreMixin { Widget scaffold = Scaffold( key: bar == null || bar is AppBarControl ? scaffoldKey : null, - backgroundColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("bgcolor", "")!) ?? + backgroundColor: widget.control.attrColor("bgcolor", context) ?? CupertinoTheme.of(context).scaffoldBackgroundColor, appBar: bar is AppBarControl ? bar : null, drawer: drawerView != null @@ -257,8 +255,7 @@ class _PageletControlState extends State with FletStoreMixin { if (bar is CupertinoAppBarControl) { scaffold = CupertinoPageScaffold( key: scaffoldKey, - backgroundColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("bgcolor", "")!), + backgroundColor: widget.control.attrColor("bgcolor", context), navigationBar: bar as ObstructingPreferredSizeWidget, child: scaffold); } diff --git a/packages/flet/lib/src/controls/piechart.dart b/packages/flet/lib/src/controls/piechart.dart index 266c80a30..819309746 100644 --- a/packages/flet/lib/src/controls/piechart.dart +++ b/packages/flet/lib/src/controls/piechart.dart @@ -12,7 +12,6 @@ import '../models/app_state.dart'; import '../models/control.dart'; import '../utils/animations.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -113,8 +112,8 @@ class _PieChartControlState extends State { Widget chart = PieChart( PieChartData( - centerSpaceColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("centerSpaceColor", "")!), + centerSpaceColor: + widget.control.attrColor("centerSpaceColor", context), centerSpaceRadius: widget.control.attrDouble("centerSpaceRadius"), sectionsSpace: widget.control.attrDouble("sectionsSpace"), startDegreeOffset: widget.control.attrDouble("startDegreeOffset"), @@ -171,8 +170,7 @@ class _PieChartControlState extends State { PieChartSectionViewModel sectionViewModel) { return PieChartSectionData( value: sectionViewModel.control.attrDouble("value"), - color: HexColor.fromString( - Theme.of(context), sectionViewModel.control.attrString("color", "")!), + color: sectionViewModel.control.attrColor("color", context), radius: sectionViewModel.control.attrDouble("radius"), showTitle: sectionViewModel.control.attrString("title", "")! != "", title: sectionViewModel.control.attrString("title"), diff --git a/packages/flet/lib/src/controls/popup_menu_button.dart b/packages/flet/lib/src/controls/popup_menu_button.dart index 47a9e0785..826ddef05 100644 --- a/packages/flet/lib/src/controls/popup_menu_button.dart +++ b/packages/flet/lib/src/controls/popup_menu_button.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import 'create_control.dart'; @@ -44,14 +43,10 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { e.name.toLowerCase() == control.attrString("clipBehavior", "")!.toLowerCase(), orElse: () => Clip.none); - var bgcolor = HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!); - var iconColor = HexColor.fromString( - Theme.of(context), control.attrString("iconColor", "")!); - var shadowColor = HexColor.fromString( - Theme.of(context), control.attrString("shadowColor", "")!); - var surfaceTintColor = HexColor.fromString( - Theme.of(context), control.attrString("surfaceTintColor", "")!); + var bgcolor = control.attrColor("bgcolor", context); + var iconColor = control.attrColor("iconColor", context); + var shadowColor = control.attrColor("shadowColor", context); + var surfaceTintColor = control.attrColor("surfaceTintColor", context); var contentCtrls = children.where((c) => c.name == "content" && c.isVisible); bool disabled = control.isDisabled || parentDisabled; diff --git a/packages/flet/lib/src/controls/progress_bar.dart b/packages/flet/lib/src/controls/progress_bar.dart index c633e4ce9..c6661857e 100644 --- a/packages/flet/lib/src/controls/progress_bar.dart +++ b/packages/flet/lib/src/controls/progress_bar.dart @@ -2,7 +2,6 @@ import 'package:flet/src/utils/borders.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class ProgressBarControl extends StatelessWidget { @@ -20,10 +19,8 @@ class ProgressBarControl extends StatelessWidget { var semanticsValue = control.attrDouble("semanticsValue"); var semanticsLabel = control.attrString("semanticsLabel"); var barHeight = control.attrDouble("barHeight", 4)!; - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); - var bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); + var color = control.attrColor("color", context); + var bgColor = control.attrColor("bgColor", context); return constrainedControl( context, diff --git a/packages/flet/lib/src/controls/progress_ring.dart b/packages/flet/lib/src/controls/progress_ring.dart index 6952d5e15..8d8bda37a 100644 --- a/packages/flet/lib/src/controls/progress_ring.dart +++ b/packages/flet/lib/src/controls/progress_ring.dart @@ -2,7 +2,6 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class ProgressRingControl extends StatelessWidget { @@ -24,10 +23,8 @@ class ProgressRingControl extends StatelessWidget { e.name.toLowerCase() == control.attrString("strokeCap", "")!.toLowerCase()); var strokeWidth = control.attrDouble("strokeWidth", 4)!; - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); - var bgColor = HexColor.fromString( - Theme.of(context), control.attrString("bgColor", "")!); + var color = control.attrColor("color", context); + var bgColor = control.attrColor("bgColor", context); return constrainedControl( context, diff --git a/packages/flet/lib/src/controls/radio.dart b/packages/flet/lib/src/controls/radio.dart index 71321a3d0..9cbad84f1 100644 --- a/packages/flet/lib/src/controls/radio.dart +++ b/packages/flet/lib/src/controls/radio.dart @@ -112,12 +112,9 @@ class _RadioControlState extends State with FletStoreMixin { focusNode: _focusNode, groupValue: groupValue, value: value, - activeColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("activeColor", "")!), - focusColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("activeColor", "")!), - hoverColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("activeColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), + focusColor: widget.control.attrColor("focusColor", context), + hoverColor: widget.control.attrColor("hoverColor", context), splashRadius: widget.control.attrDouble("splashRadius"), toggleable: widget.control.attrBool("toggleable", false)!, fillColor: parseMaterialStateColor( diff --git a/packages/flet/lib/src/controls/range_slider.dart b/packages/flet/lib/src/controls/range_slider.dart index 75d1eb4bc..502f6c91d 100644 --- a/packages/flet/lib/src/controls/range_slider.dart +++ b/packages/flet/lib/src/controls/range_slider.dart @@ -77,10 +77,8 @@ class _SliderControlState extends State { min: min, max: max, divisions: divisions, - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - inactiveColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("inactiveColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), + inactiveColor: widget.control.attrColor("inactiveColor", context), overlayColor: parseMaterialStateColor( Theme.of(context), widget.control, "overlayColor"), onChanged: !disabled diff --git a/packages/flet/lib/src/controls/search_anchor.dart b/packages/flet/lib/src/controls/search_anchor.dart index 5c3e8a1d4..6c254f9c5 100644 --- a/packages/flet/lib/src/controls/search_anchor.dart +++ b/packages/flet/lib/src/controls/search_anchor.dart @@ -88,10 +88,8 @@ class _SearchAnchorControlState extends State { var viewTrailingCtrls = widget.children.where((c) => c.name == "viewTrailing" && c.isVisible); - var viewBgcolor = HexColor.fromString( - Theme.of(context), widget.control.attrString("viewBgcolor", "")!); - var dividerColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("dividerColor", "")!); + var viewBgcolor = widget.control.attrColor("viewBgcolor", context); + var dividerColor = widget.control.attrColor("dividerColor", context); TextStyle? viewHeaderTextStyle = parseTextStyle( Theme.of(context), widget.control, "viewHeaderTextStyle"); diff --git a/packages/flet/lib/src/controls/slider.dart b/packages/flet/lib/src/controls/slider.dart index bd796083c..8f1c512ac 100644 --- a/packages/flet/lib/src/controls/slider.dart +++ b/packages/flet/lib/src/controls/slider.dart @@ -120,14 +120,11 @@ class _SliderControlState extends State with FletStoreMixin { max: max, divisions: divisions, label: label?.replaceAll("{value}", _value.toStringAsFixed(round)), - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - inactiveColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("inactiveColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), + inactiveColor: widget.control.attrColor("inactiveColor", context), overlayColor: overlayColor, allowedInteraction: interaction, - thumbColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("thumbColor", "")!), + thumbColor: widget.control.attrColor("thumbColor", context), onChanged: !disabled ? (double value) { onChange(value); diff --git a/packages/flet/lib/src/controls/snack_bar.dart b/packages/flet/lib/src/controls/snack_bar.dart index fecc4aa8d..b22c45532 100644 --- a/packages/flet/lib/src/controls/snack_bar.dart +++ b/packages/flet/lib/src/controls/snack_bar.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import 'create_control.dart'; import 'error.dart'; @@ -47,8 +46,7 @@ class _SnackBarControlState extends State { SnackBarAction? action = actionName != "" ? SnackBarAction( label: actionName, - textColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("actionColor", "")!), + textColor: widget.control.attrColor("actionColor", context), onPressed: () { debugPrint("SnackBar ${widget.control.id} clicked!"); widget.backend.triggerControlEvent(widget.control.id, "action"); @@ -80,12 +78,10 @@ class _SnackBarControlState extends State { }, dismissDirection: dismissDirection, showCloseIcon: widget.control.attrBool("showCloseIcon"), - closeIconColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("closeIconColor", "")!), + closeIconColor: widget.control.attrColor("closeIconColor", context), content: createControl(widget.control, contentCtrls.first.id, disabled, parentAdaptive: widget.parentAdaptive), - backgroundColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("bgColor", "")!), + backgroundColor: widget.control.attrColor("bgColor", context), action: action, margin: parseEdgeInsets(widget.control, "margin"), padding: parseEdgeInsets(widget.control, "padding"), diff --git a/packages/flet/lib/src/controls/switch.dart b/packages/flet/lib/src/controls/switch.dart index 7457229ed..54a4d5c5d 100644 --- a/packages/flet/lib/src/controls/switch.dart +++ b/packages/flet/lib/src/controls/switch.dart @@ -103,22 +103,20 @@ class _SwitchControlState extends State with FletStoreMixin { var swtch = Switch( autofocus: autofocus, focusNode: _focusNode, - activeColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("activeColor", "")!), - activeTrackColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("activeTrackColor", "")!), - inactiveThumbColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("inactiveThumbColor", "")!), - inactiveTrackColor: HexColor.fromString(Theme.of(context), - widget.control.attrString("inactiveTrackColor", "")!), + activeColor: widget.control.attrColor("activeColor", context), + activeTrackColor: + widget.control.attrColor("activeTrackColor", context), + inactiveThumbColor: + widget.control.attrColor("inactiveThumbColor", context), + inactiveTrackColor: + widget.control.attrColor("inactiveTrackColor", context), thumbColor: parseMaterialStateColor( Theme.of(context), widget.control, "thumbColor"), thumbIcon: parseMaterialStateIcon( Theme.of(context), widget.control, "thumbIcon"), trackColor: parseMaterialStateColor( Theme.of(context), widget.control, "trackColor"), - focusColor: HexColor.fromString( - Theme.of(context), widget.control.attrString("focusColor", "")!), + focusColor: widget.control.attrColor("focusColor", context), value: _value, onChanged: !disabled ? (bool value) { diff --git a/packages/flet/lib/src/controls/tabs.dart b/packages/flet/lib/src/controls/tabs.dart index 6e7547a61..9be2b062f 100644 --- a/packages/flet/lib/src/controls/tabs.dart +++ b/packages/flet/lib/src/controls/tabs.dart @@ -128,21 +128,20 @@ class _TabsControlState extends State var indicatorPadding = parseEdgeInsets(widget.control, "indicatorPadding"); - var indicatorColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("indicatorColor", "")!) ?? - TabBarTheme.of(context).indicatorColor ?? + var indicatorColor = + widget.control.attrColor("indicatorColor", context) ?? + TabBarTheme.of(context).indicatorColor ?? Theme.of(context).colorScheme.primary; - var labelColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("labelColor", "")!) ?? + var labelColor = widget.control.attrColor("labelColor", context) ?? TabBarTheme.of(context).labelColor ?? Theme.of(context).colorScheme.primary; - var unselectedLabelColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("unselectedLabelColor", "")!) ?? - TabBarTheme.of(context).unselectedLabelColor ?? + var unselectedLabelColor = + widget.control.attrColor("unselectedLabelColor", context) ?? + TabBarTheme.of(context).unselectedLabelColor ?? Theme.of(context).colorScheme.onSurface; - var dividerColor = HexColor.fromString(Theme.of(context), - widget.control.attrString("dividerColor", "")!) ?? - TabBarTheme.of(context).dividerColor; + var dividerColor = + widget.control.attrColor("dividerColor", context) ?? + TabBarTheme.of(context).dividerColor; var themeIndicator = TabBarTheme.of(context).indicator as UnderlineTabIndicator?; diff --git a/packages/flet/lib/src/controls/text.dart b/packages/flet/lib/src/controls/text.dart index 3b54d3d49..7d489e5c7 100644 --- a/packages/flet/lib/src/controls/text.dart +++ b/packages/flet/lib/src/controls/text.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import '../utils/numbers.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -86,13 +85,11 @@ class TextControl extends StatelessWidget with FletStoreMixin { : null, fontFamily: control.attrString("fontFamily"), fontVariations: variations, - color: HexColor.fromString( - Theme.of(context), control.attrString("color", "")!) ?? + color: control.attrColor("color", context) ?? (spans.isNotEmpty ? DefaultTextStyle.of(context).style.color : null), - backgroundColor: HexColor.fromString( - Theme.of(context), control.attrString("bgcolor", "")!), + backgroundColor: control.attrColor("bgcolor", context), ); TextAlign textAlign = parseTextAlign( diff --git a/packages/flet/lib/src/controls/text_button.dart b/packages/flet/lib/src/controls/text_button.dart index 342d04dfe..430892091 100644 --- a/packages/flet/lib/src/controls/text_button.dart +++ b/packages/flet/lib/src/controls/text_button.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/buttons.dart'; -import '../utils/colors.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; import 'create_control.dart'; @@ -85,8 +84,7 @@ class _TextButtonControlState extends State String text = widget.control.attrString("text", "")!; IconData? icon = parseIcon(widget.control.attrString("icon", "")!); - Color? iconColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("iconColor", "")!); + Color? iconColor = widget.control.attrColor("iconColor", context); var contentCtrls = widget.children.where((c) => c.name == "content"); bool onHover = widget.control.attrBool("onHover", false)!; bool onLongPress = widget.control.attrBool("onLongPress", false)!; diff --git a/packages/flet/lib/src/controls/textfield.dart b/packages/flet/lib/src/controls/textfield.dart index 83dfad402..86f469a7a 100644 --- a/packages/flet/lib/src/controls/textfield.dart +++ b/packages/flet/lib/src/controls/textfield.dart @@ -4,7 +4,6 @@ import 'package:flutter/services.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/text.dart'; import '../utils/textfield.dart'; import 'create_control.dart'; @@ -138,19 +137,15 @@ class _TextFieldControlState extends State widget.control.attrBool("canRevealPassword", false)!; bool onChange = widget.control.attrBool("onChange", false)!; - var cursorColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("cursorColor", "")!); - var selectionColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("selectionColor", "")!); + var cursorColor = widget.control.attrColor("cursorColor", context); + var selectionColor = widget.control.attrColor("selectionColor", context); int? maxLength = widget.control.attrInt("maxLength"); var textSize = widget.control.attrDouble("textSize"); - var color = HexColor.fromString( - Theme.of(context), widget.control.attrString("color", "")!); - var focusedColor = HexColor.fromString( - Theme.of(context), widget.control.attrString("focusedColor", "")!); + var color = widget.control.attrColor("color", context); + var focusedColor = widget.control.attrColor("focusedColor", context); TextStyle? textStyle = parseTextStyle(Theme.of(context), widget.control, "textStyle"); diff --git a/packages/flet/lib/src/controls/tooltip.dart b/packages/flet/lib/src/controls/tooltip.dart index 598e97b88..1348503ff 100644 --- a/packages/flet/lib/src/controls/tooltip.dart +++ b/packages/flet/lib/src/controls/tooltip.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; import '../utils/borders.dart'; -import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/gradient.dart'; import '../utils/text.dart'; @@ -55,7 +54,7 @@ class TooltipControl extends StatelessWidget { gradient != null || shape != null) { decoration = (defaultDecoration as BoxDecoration).copyWith( - color: HexColor.fromString(Theme.of(context), bgColor ?? ""), + color: control.attrColor("bgColor", context), gradient: gradient, border: border, borderRadius: borderRadius, diff --git a/packages/flet/lib/src/controls/vertical_divider.dart b/packages/flet/lib/src/controls/vertical_divider.dart index 15351b604..06f80b0e7 100644 --- a/packages/flet/lib/src/controls/vertical_divider.dart +++ b/packages/flet/lib/src/controls/vertical_divider.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import '../models/control.dart'; -import '../utils/colors.dart'; import 'create_control.dart'; class VerticalDividerControl extends StatelessWidget { @@ -19,8 +18,7 @@ class VerticalDividerControl extends StatelessWidget { var thickness = control.attrDouble("thickness"); var leadingIndent = control.attrDouble("leadingIndent"); var trailingIndent = control.attrDouble("trailingIndent"); - var color = HexColor.fromString( - Theme.of(context), control.attrString("color", "")!); + var color = control.attrColor("color", context); return baseControl( context, diff --git a/packages/flet/lib/src/models/control.dart b/packages/flet/lib/src/models/control.dart index a4f3a15e2..b76001699 100644 --- a/packages/flet/lib/src/models/control.dart +++ b/packages/flet/lib/src/models/control.dart @@ -1,6 +1,8 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; +import '../utils/colors.dart'; + class Control extends Equatable { static const reservedProps = ['i', 'p', 't', 'c', 'n']; @@ -107,6 +109,12 @@ class Control extends Equatable { hour: int.parse(splitted[0]), minute: int.parse(splitted[1])); } + Color? attrColor(String name, BuildContext? context, [Color? defValue]) { + return HexColor.fromString(context != null ? Theme.of(context) : null, + attrString(name, "")!) ?? + defValue; + } + Control copyWith( {String? id, String? pid, From e4b00d233268731cbacb4ca977be58895a8502ce Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 16:17:25 +0100 Subject: [PATCH 057/103] ListView+GridView: cache_extent --- packages/flet/lib/src/controls/grid_view.dart | 3 +++ packages/flet/lib/src/controls/list_view.dart | 8 ++++++-- .../packages/flet-core/src/flet_core/grid_view.py | 11 +++++++++++ .../packages/flet-core/src/flet_core/list_view.py | 11 +++++++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/grid_view.dart b/packages/flet/lib/src/controls/grid_view.dart index ed3fa8aaf..b51426aac 100644 --- a/packages/flet/lib/src/controls/grid_view.dart +++ b/packages/flet/lib/src/controls/grid_view.dart @@ -63,6 +63,8 @@ class _GridViewControlState extends State { final padding = parseEdgeInsets(widget.control, "padding"); final childAspectRatio = widget.control.attrDouble("childAspectRatio", 1)!; final reverse = widget.control.attrBool("reverse", false)!; + final cacheExtent = widget.control.attrDouble("cacheExtent"); + var clipBehavior = Clip.values.firstWhere( (e) => e.name.toLowerCase() == @@ -98,6 +100,7 @@ class _GridViewControlState extends State { controller: _controller, clipBehavior: clipBehavior, reverse: reverse, + cacheExtent: cacheExtent, semanticChildCount: semanticChildCount, shrinkWrap: shrinkWrap, padding: padding, diff --git a/packages/flet/lib/src/controls/list_view.dart b/packages/flet/lib/src/controls/list_view.dart index 6e2031146..62d5d24ef 100644 --- a/packages/flet/lib/src/controls/list_view.dart +++ b/packages/flet/lib/src/controls/list_view.dart @@ -58,6 +58,7 @@ class _ListViewControlState extends State { final spacing = widget.control.attrDouble("spacing", 0)!; final dividerThickness = widget.control.attrDouble("dividerThickness", 0)!; final itemExtent = widget.control.attrDouble("itemExtent"); + final cacheExtent = widget.control.attrDouble("cacheExtent"); final semanticChildCount = widget.control.attrInt("semanticChildCount"); final firstItemPrototype = widget.control.attrBool("firstItemPrototype", false)!; @@ -71,6 +72,7 @@ class _ListViewControlState extends State { List visibleControls = widget.children.where((c) => c.isVisible).toList(); + var scrollDirection = horizontal ? Axis.horizontal : Axis.vertical; Widget listView = LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { @@ -84,9 +86,10 @@ class _ListViewControlState extends State { Widget child = spacing > 0 ? ListView.separated( controller: _controller, + cacheExtent: cacheExtent, reverse: reverse, clipBehavior: clipBehavior, - scrollDirection: horizontal ? Axis.horizontal : Axis.vertical, + scrollDirection: scrollDirection, shrinkWrap: shrinkWrap, padding: padding, itemCount: widget.children.length, @@ -112,7 +115,8 @@ class _ListViewControlState extends State { clipBehavior: clipBehavior, semanticChildCount: semanticChildCount, reverse: reverse, - scrollDirection: horizontal ? Axis.horizontal : Axis.vertical, + cacheExtent: cacheExtent, + scrollDirection: scrollDirection, shrinkWrap: shrinkWrap, padding: padding, itemCount: widget.children.length, diff --git a/sdk/python/packages/flet-core/src/flet_core/grid_view.py b/sdk/python/packages/flet-core/src/flet_core/grid_view.py index f6e6932de..2a471f1cf 100644 --- a/sdk/python/packages/flet-core/src/flet_core/grid_view.py +++ b/sdk/python/packages/flet-core/src/flet_core/grid_view.py @@ -76,6 +76,7 @@ def __init__( padding: PaddingValue = None, clip_behavior: Optional[ClipBehavior] = None, semantic_child_count: Optional[int] = None, + cache_extent: OptionalNumber = None, # # ConstrainedControl # @@ -168,6 +169,7 @@ def __init__( self.padding = padding self.clip_behavior = clip_behavior self.semantic_child_count = semantic_child_count + self.cache_extent = cache_extent def _get_control_name(self): return "gridview" @@ -200,6 +202,15 @@ def horizontal(self) -> Optional[bool]: def horizontal(self, value: Optional[bool]): self._set_attr("horizontal", value) + # cache_extent + @property + def cache_extent(self) -> OptionalNumber: + return self._get_attr("cacheExtent") + + @cache_extent.setter + def cache_extent(self, value: OptionalNumber): + self._set_attr("cacheExtent", value) + # runs_count @property def runs_count(self) -> Optional[int]: diff --git a/sdk/python/packages/flet-core/src/flet_core/list_view.py b/sdk/python/packages/flet-core/src/flet_core/list_view.py index 82d2afed7..c56b8d9a0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_view.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_view.py @@ -67,6 +67,7 @@ def __init__( padding: PaddingValue = None, clip_behavior: Optional[ClipBehavior] = None, semantic_child_count: Optional[int] = None, + cache_extent: OptionalNumber = None, # # ScrollableControl specific # @@ -158,6 +159,7 @@ def __init__( self.padding = padding self.clip_behavior = clip_behavior self.semantic_child_count = semantic_child_count + self.cache_extent = cache_extent def _get_control_name(self): return "listview" @@ -217,6 +219,15 @@ def item_extent(self) -> OptionalNumber: def item_extent(self, value: OptionalNumber): self._set_attr("itemExtent", value) + # cache_extent + @property + def cache_extent(self) -> OptionalNumber: + return self._get_attr("cacheExtent") + + @cache_extent.setter + def cache_extent(self, value: OptionalNumber): + self._set_attr("cacheExtent", value) + # first_item_prototype @property def first_item_prototype(self) -> Optional[bool]: From 7ceb22ccc76be2bd8bd474660beecdff807bcf95 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 17:39:26 +0100 Subject: [PATCH 058/103] AppBar: elevation_on_scroll, shadow_color, surface_tint_color, clip_behavior, force_material_transparency, is_secondary, title_spacing, exclude_header_semantics --- packages/flet/lib/src/controls/app_bar.dart | 32 ++++++ packages/flet/lib/src/controls/divider.dart | 2 +- .../flet-core/src/flet_core/app_bar.py | 104 +++++++++++++++++- 3 files changed, 133 insertions(+), 5 deletions(-) diff --git a/packages/flet/lib/src/controls/app_bar.dart b/packages/flet/lib/src/controls/app_bar.dart index 6a2271b3a..42c79ceb0 100644 --- a/packages/flet/lib/src/controls/app_bar.dart +++ b/packages/flet/lib/src/controls/app_bar.dart @@ -1,3 +1,4 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; @@ -46,6 +47,14 @@ class AppBarControl extends StatelessWidget var titleCtrls = children.where((c) => c.name == "title" && c.isVisible); var actionCtrls = children.where((c) => c.name == "action" && c.isVisible); + /* + var bottomCtrls = children.where((c) => + c.name == "bottom" && + (c.type == "cupertinoappbar" || + c.type == "appbar" || + c.type == "tabs") && // must be of type PreferredSizeWidget + c.isVisible); + */ var leadingWidth = control.attrDouble("leadingWidth"); var elevation = control.attrDouble("elevation"); @@ -54,6 +63,21 @@ class AppBarControl extends StatelessWidget control.attrBool("automaticallyImplyLeading", true)!; var color = control.attrColor("color", context); var bgcolor = control.attrColor("bgcolor", context); + var shadowColor = control.attrColor("shadowColor", context); + var surfaceTintColor = control.attrColor("surfaceTintColor", context); + var elevationOnScroll = control.attrDouble("elevationOnScroll"); + var forceMaterialTransparency = + control.attrBool("forceMaterialTransparency", false)!; + var isSecondary = control.attrBool("isSecondary", false)!; + var excludeHeaderSemantics = + control.attrBool("excludeHeaderSemantics", false)!; + var titleSpacing = control.attrDouble("titleSpacing"); + + var clipBehavior = Clip.values.firstWhereOrNull( + (e) => + e.name.toLowerCase() == + control.attrString("clipBehavior", "")!.toLowerCase(), + ); return AppBar( leading: leadingCtrls.isNotEmpty @@ -78,6 +102,14 @@ class AppBarControl extends StatelessWidget systemOverlayStyle: Theme.of(context) .extension() ?.systemUiOverlayStyle, + shadowColor: shadowColor, + surfaceTintColor: surfaceTintColor, + scrolledUnderElevation: elevationOnScroll, + forceMaterialTransparency: forceMaterialTransparency, + primary: !isSecondary, + titleSpacing: titleSpacing, + excludeHeaderSemantics: excludeHeaderSemantics, + clipBehavior: clipBehavior, ); }); } diff --git a/packages/flet/lib/src/controls/divider.dart b/packages/flet/lib/src/controls/divider.dart index 4b445eed1..e1ef7c5fa 100644 --- a/packages/flet/lib/src/controls/divider.dart +++ b/packages/flet/lib/src/controls/divider.dart @@ -17,7 +17,7 @@ class DividerControl extends StatelessWidget { var leadingIndent = control.attrDouble("leadingIndent"); var trailingIndent = control.attrDouble("trailingIndent"); var thickness = control.attrDouble("thickness"); - var color = widget.control.attrColor("color", context); + var color = control.attrColor("color", context); return baseControl( context, diff --git a/sdk/python/packages/flet-core/src/flet_core/app_bar.py b/sdk/python/packages/flet-core/src/flet_core/app_bar.py index 0129c58dc..10f4426a4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/app_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/app_bar.py @@ -3,6 +3,7 @@ from flet_core.adaptive_control import AdaptiveControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref +from flet_core.types import ClipBehavior class AppBar(AdaptiveControl): @@ -60,6 +61,14 @@ def __init__( color: Optional[str] = None, bgcolor: Optional[str] = None, elevation: OptionalNumber = None, + elevation_on_scroll: OptionalNumber = None, + shadow_color: Optional[str] = None, + surface_tint_color: Optional[str] = None, + clip_behavior: Optional[ClipBehavior] = None, + force_material_transparency: Optional[bool] = None, + is_secondary: Optional[bool] = None, + title_spacing: OptionalNumber = None, + exclude_header_semantics: Optional[bool] = None, actions: Optional[List[Control]] = None, # # AdaptiveControl @@ -85,6 +94,14 @@ def __init__( self.bgcolor = bgcolor self.elevation = elevation self.actions = actions + self.elevation_on_scroll = elevation_on_scroll + self.shadow_color = shadow_color + self.surface_tint_color = surface_tint_color + self.clip_behavior = clip_behavior + self.force_material_transparency = force_material_transparency + self.is_secondary = is_secondary + self.title_spacing = title_spacing + self.exclude_header_semantics = exclude_header_semantics def _get_control_name(self): return "appbar" @@ -125,6 +142,15 @@ def leading_width(self) -> OptionalNumber: def leading_width(self, value: OptionalNumber): self._set_attr("leadingWidth", value) + # title_spacing + @property + def title_spacing(self) -> OptionalNumber: + return self._get_attr("titleSpacing", data_type="float") + + @title_spacing.setter + def title_spacing(self, value: OptionalNumber): + self._set_attr("titleSpacing", value) + # automatically_imply_leading @property def automatically_imply_leading(self) -> Optional[bool]: @@ -165,22 +191,71 @@ def toolbar_height(self, value: OptionalNumber): # color @property - def color(self): + def color(self) -> Optional[str]: return self._get_attr("color") @color.setter - def color(self, value): + def color(self, value: Optional[str]): self._set_attr("color", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) + # shadow_color + @property + def shadow_color(self) -> Optional[str]: + return self._get_attr("shadowColor") + + @shadow_color.setter + def shadow_color(self, value: Optional[str]): + self._set_attr("shadowColor", value) + + # surface_tint_color + @property + def surface_tint_color(self) -> Optional[str]: + return self._get_attr("surfaceTintColor") + + @surface_tint_color.setter + def surface_tint_color(self, value: Optional[str]): + self._set_attr("surfaceTintColor", value) + + # is_secondary + @property + def is_secondary(self) -> Optional[bool]: + return self._get_attr("isSecondary", data_type="bool", def_value=False) + + @is_secondary.setter + def is_secondary(self, value: Optional[bool]): + self._set_attr("isSecondary", value) + + # exclude_header_semantics + @property + def exclude_header_semantics(self) -> Optional[bool]: + return self._get_attr( + "excludeHeaderSemantics", data_type="bool", def_value=False + ) + + @exclude_header_semantics.setter + def exclude_header_semantics(self, value: Optional[bool]): + self._set_attr("excludeHeaderSemantics", value) + + # force_material_transparency + @property + def force_material_transparency(self) -> Optional[bool]: + return self._get_attr( + "forceMaterialTransparency", data_type="bool", def_value=False + ) + + @force_material_transparency.setter + def force_material_transparency(self, value: Optional[bool]): + self._set_attr("forceMaterialTransparency", value) + # elevation @property def elevation(self) -> OptionalNumber: @@ -190,6 +265,27 @@ def elevation(self) -> OptionalNumber: def elevation(self, value: OptionalNumber): self._set_attr("elevation", value) + # elevation_on_scroll + @property + def elevation_on_scroll(self) -> OptionalNumber: + return self._get_attr("elevationOnScroll") + + @elevation_on_scroll.setter + def elevation_on_scroll(self, value: OptionalNumber): + self._set_attr("elevationOnScroll", value) + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self._get_attr("clipBehavior") + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self._set_attr( + "clipBehavior", + value.value if isinstance(value, ClipBehavior) else value, + ) + # actions @property def actions(self): From 0c7f83dbb8d62e30e274faa37104353707f17db7 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 21 Mar 2024 18:00:26 +0100 Subject: [PATCH 059/103] Reformat: avoid spamming warnings --- .../flet-core/src/flet_core/circle_avatar.py | 26 ++++++++++--------- .../src/flet_core/popup_menu_button.py | 14 ++++++++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py index f4f8bab0d..d03928a97 100644 --- a/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py +++ b/sdk/python/packages/flet-core/src/flet_core/circle_avatar.py @@ -179,13 +179,14 @@ def foreground_image_url(self) -> Optional[str]: @foreground_image_url.setter def foreground_image_url(self, value: Optional[str]): - warnings.warn( - f"foreground_image_url is deprecated since version 0.22.0 " - f"and will be removed in version 1.0. Use foreground_image_src instead.", - category=DeprecationWarning, - stacklevel=2, - ) self._set_attr("foregroundImageUrl", value) + if value is not None: + warnings.warn( + f"foreground_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use foreground_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) # background_image_url @property @@ -200,13 +201,14 @@ def background_image_url(self) -> Optional[str]: @background_image_url.setter def background_image_url(self, value: Optional[str]): - warnings.warn( - f"background_image_url is deprecated since version 0.22.0 " - f"and will be removed in version 1.0. Use background_image_src instead.", - category=DeprecationWarning, - stacklevel=2, - ) self._set_attr("backgroundImageUrl", value) + if value is not None: + warnings.warn( + f"background_image_url is deprecated since version 0.22.0 " + f"and will be removed in version 1.0. Use background_image_src instead.", + category=DeprecationWarning, + stacklevel=2, + ) # foreground_image_src @property diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 4976d8c88..0fe9c29b6 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -1,3 +1,4 @@ +import warnings from enum import Enum from typing import Any, List, Optional, Union @@ -438,11 +439,24 @@ def on_cancel(self, handler): # on_cancelled @property def on_cancelled(self): + warnings.warn( + f"on_cancelled is deprecated/renamed since version 0.22.0 " + f"and will be removed in version 1.0. Use on_cancel instead.", + category=DeprecationWarning, + stacklevel=2, + ) return self._get_event_handler("cancelled") @on_cancelled.setter def on_cancelled(self, handler): self._add_event_handler("cancelled", handler) + if handler is not None: + warnings.warn( + f"on_cancelled is deprecated/renamed since version 0.22.0 " + f"and will be removed in version 1.0. Use on_cancel instead.", + category=DeprecationWarning, + stacklevel=2, + ) # on_open @property From 03d5e819036a6cd12f40a2518e8622f52a43858e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 22 Mar 2024 14:44:14 +0100 Subject: [PATCH 060/103] TextField: fill_color, hover_color --- client/pubspec.lock | 10 +- .../flet/lib/src/controls/form_field.dart | 7 +- .../src/flet_core/form_field_control.py | 114 +++++++++++------- .../flet-core/src/flet_core/textfield.py | 35 ++---- 4 files changed, 95 insertions(+), 71 deletions(-) diff --git a/client/pubspec.lock b/client/pubspec.lock index a7def2dfa..02e8abacd 100644 --- a/client/pubspec.lock +++ b/client/pubspec.lock @@ -294,7 +294,7 @@ packages: source: hosted version: "1.0.4" flutter_localizations: - dependency: "direct main" + dependency: transitive description: flutter source: sdk version: "0.0.0" @@ -382,6 +382,14 @@ packages: description: flutter source: sdk version: "0.0.0" + intl: + dependency: transitive + description: + name: intl + sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + url: "https://pub.dev" + source: hosted + version: "0.18.1" js: dependency: transitive description: diff --git a/packages/flet/lib/src/controls/form_field.dart b/packages/flet/lib/src/controls/form_field.dart index 9d09fb519..86933a120 100644 --- a/packages/flet/lib/src/controls/form_field.dart +++ b/packages/flet/lib/src/controls/form_field.dart @@ -60,9 +60,11 @@ InputDecoration buildInputDecoration( var bgcolor = control.attrColor("bgcolor", context); var focusedBgcolor = control.attrColor("focusedBgcolor", context); + var fillColor = control.attrColor("fillColor", context); + var hoverColor = control.attrColor("hoverColor", context); + var borderColor = control.attrColor("borderColor", context); var borderRadius = parseBorderRadius(control, "borderRadius"); - var borderColor = control.attrColor("borderColor", context); var focusedBorderColor = control.attrColor("focusedBorderColor", context); var borderWidth = control.attrDouble("borderWidth"); var focusedBorderWidth = control.attrDouble("focusedBorderWidth"); @@ -115,9 +117,10 @@ InputDecoration buildInputDecoration( border: border, enabledBorder: border, focusedBorder: focusedBorder, + hoverColor: hoverColor, icon: icon != null ? Icon(icon) : null, filled: control.attrBool("filled", false)!, - fillColor: focused ? focusedBgcolor ?? bgcolor : bgcolor, + fillColor: fillColor ?? (focused ? focusedBgcolor ?? bgcolor : bgcolor), hintText: control.attrString("hintText"), hintStyle: parseTextStyle(Theme.of(context), control, "hintStyle"), helperText: control.attrString("helperText"), diff --git a/sdk/python/packages/flet-core/src/flet_core/form_field_control.py b/sdk/python/packages/flet-core/src/flet_core/form_field_control.py index 5d39132a8..b51921d75 100644 --- a/sdk/python/packages/flet-core/src/flet_core/form_field_control.py +++ b/sdk/python/packages/flet-core/src/flet_core/form_field_control.py @@ -52,6 +52,8 @@ def __init__( content_padding: PaddingValue = None, dense: Optional[bool] = None, filled: Optional[bool] = None, + fill_color: Optional[str] = None, + hover_color: Optional[str] = None, hint_text: Optional[str] = None, hint_style: Optional[TextStyle] = None, helper_text: Optional[str] = None, @@ -167,6 +169,8 @@ def __init__( self.suffix_icon = suffix_icon self.suffix_text = suffix_text self.suffix_style = suffix_style + self.hover_color = hover_color + self.fill_color = fill_color def before_update(self): super().before_update() @@ -183,10 +187,10 @@ def before_update(self): def _get_children(self): children = [] - if self.__prefix: + if isinstance(self.__prefix, Control): self.__prefix._set_attr_internal("n", "prefix") children.append(self.__prefix) - if self.__suffix: + if isinstance(self.__suffix, Control): self.__suffix._set_attr_internal("n", "suffix") children.append(self.__suffix) return children @@ -202,7 +206,7 @@ def text_size(self, value: OptionalNumber): # text_style @property - def text_style(self): + def text_style(self) -> Optional[TextStyle]: return self.__text_style @text_style.setter @@ -211,16 +215,16 @@ def text_style(self, value: Optional[TextStyle]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) # label_style @property - def label_style(self): + def label_style(self) -> Optional[TextStyle]: return self.__label_style @label_style.setter @@ -229,11 +233,11 @@ def label_style(self, value: Optional[TextStyle]): # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) # border @@ -250,20 +254,20 @@ def border(self, value: Optional[InputBorder]): # color @property - def color(self): + def color(self) -> Optional[str]: return self._get_attr("color") @color.setter - def color(self, value): + def color(self, value: Optional[str]): self._set_attr("color", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) # border_radius @@ -286,11 +290,11 @@ def border_width(self, value: OptionalNumber): # border_color @property - def border_color(self): + def border_color(self) -> Optional[str]: return self._get_attr("borderColor") @border_color.setter - def border_color(self, value): + def border_color(self, value: Optional[str]): self._set_attr("borderColor", value) # text_vertical_align @@ -307,20 +311,20 @@ def text_vertical_align(self, value: Union[VerticalAlignment, OptionalNumber]): # focused_color @property - def focused_color(self): + def focused_color(self) -> Optional[str]: return self._get_attr("focusedColor") @focused_color.setter - def focused_color(self, value): + def focused_color(self, value: Optional[str]): self._set_attr("focusedColor", value) # focused_bgcolor @property - def focused_bgcolor(self): + def focused_bgcolor(self) -> Optional[str]: return self._get_attr("focusedBgcolor") @focused_bgcolor.setter - def focused_bgcolor(self, value): + def focused_bgcolor(self, value: Optional[str]): self._set_attr("focusedBgcolor", value) # focused_border_width @@ -334,11 +338,11 @@ def focused_border_width(self, value: OptionalNumber): # focused_border_color @property - def focused_border_color(self): + def focused_border_color(self) -> Optional[str]: return self._get_attr("focusedBorderColor") @focused_border_color.setter - def focused_border_color(self, value): + def focused_border_color(self, value: Optional[str]): self._set_attr("focusedBorderColor", value) # content_padding @@ -370,16 +374,16 @@ def filled(self, value: Optional[bool]): # hint_text @property - def hint_text(self): + def hint_text(self) -> Optional[str]: return self._get_attr("hintText") @hint_text.setter - def hint_text(self, value): + def hint_text(self, value: Optional[str]): self._set_attr("hintText", value) # hint_style @property - def hint_style(self): + def hint_style(self) -> Optional[TextStyle]: return self.__hint_style @hint_style.setter @@ -388,16 +392,16 @@ def hint_style(self, value: Optional[TextStyle]): # helper_text @property - def helper_text(self): + def helper_text(self) -> Optional[str]: return self._get_attr("helperText") @helper_text.setter - def helper_text(self, value): + def helper_text(self, value: Optional[str]): self._set_attr("helperText", value) # helper_style @property - def helper_style(self): + def helper_style(self) -> Optional[TextStyle]: return self.__helper_style @helper_style.setter @@ -406,16 +410,16 @@ def helper_style(self, value: Optional[TextStyle]): # counter_text @property - def counter_text(self): + def counter_text(self) -> Optional[str]: return self._get_attr("counterText") @counter_text.setter - def counter_text(self, value): + def counter_text(self, value: Optional[str]): self._set_attr("counterText", value) # counter_style @property - def counter_style(self): + def counter_style(self) -> Optional[TextStyle]: return self.__counter_style @counter_style.setter @@ -424,16 +428,16 @@ def counter_style(self, value: Optional[TextStyle]): # error_text @property - def error_text(self): + def error_text(self) -> Optional[str]: return self._get_attr("errorText") @error_text.setter - def error_text(self, value): + def error_text(self, value: Optional[str]): self._set_attr("errorText", value) # error_style @property - def error_style(self): + def error_style(self) -> Optional[TextStyle]: return self.__error_style @error_style.setter @@ -442,34 +446,34 @@ def error_style(self, value: Optional[TextStyle]): # prefix @property - def prefix(self): + def prefix(self) -> Optional[Control]: return self.__prefix @prefix.setter - def prefix(self, value): + def prefix(self, value: Optional[Control]): self.__prefix = value # prefix_icon @property - def prefix_icon(self): + def prefix_icon(self) -> Optional[str]: return self._get_attr("prefixIcon") @prefix_icon.setter - def prefix_icon(self, value): + def prefix_icon(self, value: Optional[str]): self._set_attr("prefixIcon", value) # prefix_text @property - def prefix_text(self): + def prefix_text(self) -> Optional[str]: return self._get_attr("prefixText") @prefix_text.setter - def prefix_text(self, value): + def prefix_text(self, value: Optional[str]): self._set_attr("prefixText", value) # prefix_style @property - def prefix_style(self): + def prefix_style(self) -> Optional[TextStyle]: return self.__prefix_style @prefix_style.setter @@ -478,36 +482,54 @@ def prefix_style(self, value: Optional[TextStyle]): # suffix @property - def suffix(self): + def suffix(self) -> Optional[Control]: return self.__suffix @suffix.setter - def suffix(self, value): + def suffix(self, value: Optional[Control]): self.__suffix = value # suffix_icon @property - def suffix_icon(self): + def suffix_icon(self) -> Optional[str]: return self._get_attr("suffixIcon") @suffix_icon.setter - def suffix_icon(self, value): + def suffix_icon(self, value: Optional[str]): self._set_attr("suffixIcon", value) # suffix_text @property - def suffix_text(self): + def suffix_text(self) -> Optional[str]: return self._get_attr("suffixText") @suffix_text.setter - def suffix_text(self, value): + def suffix_text(self, value: Optional[str]): self._set_attr("suffixText", value) # suffix_style @property - def suffix_style(self): + def suffix_style(self) -> Optional[TextStyle]: return self.__suffix_style @suffix_style.setter def suffix_style(self, value: Optional[TextStyle]): self.__suffix_style = value + + # fill_color + @property + def fill_color(self) -> Optional[str]: + return self._get_attr("fillColor") + + @fill_color.setter + def fill_color(self, value: Optional[str]): + self._set_attr("fillColor", value) + + # hover_color + @property + def hover_color(self) -> Optional[str]: + return self._get_attr("hoverColor") + + @hover_color.setter + def hover_color(self, value: Optional[str]): + self._set_attr("hoverColor", value) diff --git a/sdk/python/packages/flet-core/src/flet_core/textfield.py b/sdk/python/packages/flet-core/src/flet_core/textfield.py index 0454311b2..90c7406b0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/textfield.py +++ b/sdk/python/packages/flet-core/src/flet_core/textfield.py @@ -27,21 +27,6 @@ except ImportError: from typing_extensions import Literal -KeyboardTypeString = Literal[ - None, - "text", - "multiline", - "number", - "phone", - "datetime", - "email", - "url", - "visiblePassword", - "name", - "streetAddress", - "none", -] - class KeyboardType(Enum): NONE = "none" @@ -57,9 +42,6 @@ class KeyboardType(Enum): STREET_ADDRESS = "streetAddress" -TextCapitalizationString = Literal[None, "none", "characters", "words", "sentences"] - - class TextCapitalization(Enum): NONE = None CHARACTERS = "characters" @@ -76,12 +58,12 @@ class InputFilter: class NumbersOnlyInputFilter(InputFilter): def __init__(self): - super().__init__(r"[0-9]") + super().__init__(regex_string=r"[0-9]") class TextOnlyInputFilter(InputFilter): def __init__(self): - super().__init__(r"[a-zA-Z]") + super().__init__(regex_string=r"[a-zA-Z]") class TextField(FormFieldControl, AdaptiveControl): @@ -166,6 +148,8 @@ def __init__( content_padding: PaddingValue = None, dense: Optional[bool] = None, filled: Optional[bool] = None, + fill_color: Optional[str] = None, + hover_color: Optional[str] = None, hint_text: Optional[str] = None, hint_style: Optional[TextStyle] = None, helper_text: Optional[str] = None, @@ -259,6 +243,8 @@ def __init__( content_padding=content_padding, dense=dense, filled=filled, + fill_color=fill_color, + hover_color=hover_color, hint_text=hint_text, hint_style=hint_style, helper_text=helper_text, @@ -315,8 +301,13 @@ def _get_control_name(self): def before_update(self): super().before_update() self._set_attr_json("inputFilter", self.__input_filter) - if self.bgcolor is not None and self.filled is None: - self.filled = True # Flutter requires filled = True to display a bgcolor + if ( + self.bgcolor is not None + or self.fill_color is not None + or self.hover_color is not None, + self.focused_bgcolor is not None, + ) and self.filled is None: + self.filled = True # required to display a one of above colors def focus(self): self._set_attr_json("focus", str(time.time())) From 73ce01cf749a79f3592362847e784a5c70b67b04 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 22 Mar 2024 14:49:02 +0100 Subject: [PATCH 061/103] Dropdown: fill_color --- sdk/python/packages/flet-core/src/flet_core/dropdown.py | 8 ++++++++ sdk/python/packages/flet-core/src/flet_core/textfield.py | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/dropdown.py b/sdk/python/packages/flet-core/src/flet_core/dropdown.py index 95e4738b8..9aa23813d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/dropdown.py +++ b/sdk/python/packages/flet-core/src/flet_core/dropdown.py @@ -158,6 +158,7 @@ def __init__( content_padding: PaddingValue = None, dense: Optional[bool] = None, filled: Optional[bool] = None, + fill_color: Optional[str] = None, hint_text: Optional[str] = None, hint_style: Optional[TextStyle] = None, helper_text: Optional[str] = None, @@ -247,6 +248,7 @@ def __init__( content_padding=content_padding, dense=dense, filled=filled, + fill_color=fill_color, hint_text=hint_text, hint_style=hint_style, helper_text=helper_text, @@ -292,6 +294,12 @@ def before_update(self): super().before_update() self._set_attr_json("padding", self.__padding) self._set_attr_json("alignment", self.__alignment) + if ( + self.bgcolor is not None + or self.fill_color is not None + or self.focused_bgcolor is not None, + ) and self.filled is None: + self.filled = True # required to display any of the above colors def _get_children(self): children = FormFieldControl._get_children(self) diff --git a/sdk/python/packages/flet-core/src/flet_core/textfield.py b/sdk/python/packages/flet-core/src/flet_core/textfield.py index 90c7406b0..7d7218b04 100644 --- a/sdk/python/packages/flet-core/src/flet_core/textfield.py +++ b/sdk/python/packages/flet-core/src/flet_core/textfield.py @@ -307,7 +307,7 @@ def before_update(self): or self.hover_color is not None, self.focused_bgcolor is not None, ) and self.filled is None: - self.filled = True # required to display a one of above colors + self.filled = True # required to display any of the above colors def focus(self): self._set_attr_json("focus", str(time.time())) From 0d83ceeb3258d1fbadb5490c8825009ef4266908 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 22 Mar 2024 15:44:02 +0100 Subject: [PATCH 062/103] Fix failing CI: omitted parenthesis --- .../packages/flet-core/src/flet_core/dropdown.py | 8 +++++--- .../flet-core/src/flet_core/form_field_control.py | 2 +- .../packages/flet-core/src/flet_core/textfield.py | 10 ++++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/dropdown.py b/sdk/python/packages/flet-core/src/flet_core/dropdown.py index 9aa23813d..3e0f810f8 100644 --- a/sdk/python/packages/flet-core/src/flet_core/dropdown.py +++ b/sdk/python/packages/flet-core/src/flet_core/dropdown.py @@ -295,9 +295,11 @@ def before_update(self): self._set_attr_json("padding", self.__padding) self._set_attr_json("alignment", self.__alignment) if ( - self.bgcolor is not None - or self.fill_color is not None - or self.focused_bgcolor is not None, + ( + self.bgcolor is not None + or self.fill_color is not None + or self.focused_bgcolor is not None + ) ) and self.filled is None: self.filled = True # required to display any of the above colors diff --git a/sdk/python/packages/flet-core/src/flet_core/form_field_control.py b/sdk/python/packages/flet-core/src/flet_core/form_field_control.py index b51921d75..62efe63ff 100644 --- a/sdk/python/packages/flet-core/src/flet_core/form_field_control.py +++ b/sdk/python/packages/flet-core/src/flet_core/form_field_control.py @@ -366,7 +366,7 @@ def dense(self, value: Optional[bool]): # filled @property def filled(self) -> Optional[bool]: - return self._get_attr("filled") + return self._get_attr("filled", data_type=bool) @filled.setter def filled(self, value: Optional[bool]): diff --git a/sdk/python/packages/flet-core/src/flet_core/textfield.py b/sdk/python/packages/flet-core/src/flet_core/textfield.py index 7d7218b04..e86f73b2e 100644 --- a/sdk/python/packages/flet-core/src/flet_core/textfield.py +++ b/sdk/python/packages/flet-core/src/flet_core/textfield.py @@ -302,10 +302,12 @@ def before_update(self): super().before_update() self._set_attr_json("inputFilter", self.__input_filter) if ( - self.bgcolor is not None - or self.fill_color is not None - or self.hover_color is not None, - self.focused_bgcolor is not None, + ( + self.bgcolor is not None + or self.fill_color is not None + or self.hover_color is not None + or self.focused_color is not None + ) ) and self.filled is None: self.filled = True # required to display any of the above colors From 39dd3969dc03407a1803dcf9ffd0f4fcf4262367 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Fri, 22 Mar 2024 19:52:02 +0100 Subject: [PATCH 063/103] Locale: script_code --- packages/flet/lib/src/utils/locale.dart | 36 +++++++++---------- .../packages/flet-core/src/flet_core/page.py | 3 +- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/packages/flet/lib/src/utils/locale.dart b/packages/flet/lib/src/utils/locale.dart index 80a183a46..59ae5afe2 100644 --- a/packages/flet/lib/src/utils/locale.dart +++ b/packages/flet/lib/src/utils/locale.dart @@ -18,35 +18,31 @@ Map? parseLocaleConfiguration( Map localeConfigurationFromJSON(dynamic json) { List? supportedLocales; var sl = json["supported_locales"]; - var locale = - json["used_locale"] != null ? parseLocale(json["used_locale"]) : null; + Locale? locale = + json["used_locale"] != null ? localeFromJSON(json["used_locale"]) : null; if (sl != null) { supportedLocales = - sl.map((e) => parseLocale(e)).whereType().toList(); + sl.map((e) => localeFromJSON(e)).whereType().toList(); } return { "supportedLocales": supportedLocales != null && supportedLocales.isNotEmpty ? supportedLocales - : [const Locale("en", "US")], + : [const Locale("en", "US")], // American locale as fallback "locale": locale }; } -Locale? parseLocale(value) { - var languageCode = value["language_code"]; - if (languageCode != null && languageCode.trim().isNotEmpty) { - var countryCode = value["country_code"]; - return Locale(languageCode, countryCode); - } - return null; -} - -Locale? localeFromJSON(dynamic json) { - String? languageCode = json["language_code"]; - if (languageCode != null && languageCode.trim().isNotEmpty) { - String? countryCode = json["country_code"]; - return Locale(languageCode, countryCode); - } - return null; +Locale localeFromJSON(dynamic json) { + var languageCode = json["language_code"]?.trim(); + var countryCode = json["country_code"]?.trim(); + var scriptCode = json["script_code"]?.trim(); + return Locale.fromSubtags( + languageCode: (languageCode != null && languageCode.isNotEmpty) + ? languageCode + : "und", // und = undefined language code + countryCode: + (countryCode != null && countryCode.isNotEmpty) ? countryCode : null, + scriptCode: + (scriptCode != null && scriptCode.isNotEmpty) ? scriptCode : null); } diff --git a/sdk/python/packages/flet-core/src/flet_core/page.py b/sdk/python/packages/flet-core/src/flet_core/page.py index 0f53ccb70..35e9ce211 100644 --- a/sdk/python/packages/flet-core/src/flet_core/page.py +++ b/sdk/python/packages/flet-core/src/flet_core/page.py @@ -79,8 +79,9 @@ def __init__( @dataclass class Locale: - language_code: str = field(default="en") + language_code: Optional[str] = field(default=None) country_code: Optional[str] = field(default=None) + script_code: Optional[str] = field(default=None) @dataclass From f2ee6d108a8dfd2b60b92fab705a8f4bfe42e96c Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 23 Mar 2024 01:11:37 +0100 Subject: [PATCH 064/103] Locale: rename used_locale to default_locale --- packages/flet/lib/src/utils/locale.dart | 5 +++-- sdk/python/packages/flet-core/src/flet_core/page.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/utils/locale.dart b/packages/flet/lib/src/utils/locale.dart index 59ae5afe2..57ca734ff 100644 --- a/packages/flet/lib/src/utils/locale.dart +++ b/packages/flet/lib/src/utils/locale.dart @@ -18,8 +18,9 @@ Map? parseLocaleConfiguration( Map localeConfigurationFromJSON(dynamic json) { List? supportedLocales; var sl = json["supported_locales"]; - Locale? locale = - json["used_locale"] != null ? localeFromJSON(json["used_locale"]) : null; + Locale? locale = json["default_locale"] != null + ? localeFromJSON(json["default_locale"]) + : null; if (sl != null) { supportedLocales = sl.map((e) => localeFromJSON(e)).whereType().toList(); diff --git a/sdk/python/packages/flet-core/src/flet_core/page.py b/sdk/python/packages/flet-core/src/flet_core/page.py index 35e9ce211..139b1bddf 100644 --- a/sdk/python/packages/flet-core/src/flet_core/page.py +++ b/sdk/python/packages/flet-core/src/flet_core/page.py @@ -87,7 +87,7 @@ class Locale: @dataclass class LocaleConfiguration: supported_locales: Optional[List[Locale]] = field(default=None) - used_locale: Optional[Locale] = field(default=None) + default_locale: Optional[Locale] = field(default=None) class PageDisconnectedException(Exception): From c87ab1b9dbc35c91788d5d5eb4a4ca167195eaac Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 23 Mar 2024 01:12:04 +0100 Subject: [PATCH 065/103] CupertinoBottomSheet default values --- .../flet/lib/src/controls/cupertino_bottom_sheet.dart | 9 +++++---- .../flet-core/src/flet_core/cupertino_bottom_sheet.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart index 37e3b9d02..b2d327951 100644 --- a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart +++ b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart @@ -35,8 +35,9 @@ class _CupertinoBottomSheetControlState Widget _createDialog() { bool disabled = widget.control.isDisabled || widget.parentDisabled; - var height = widget.control.attrDouble("height"); - var bgcolor = widget.control.attrColor("bgcolor", context); + var height = widget.control.attrDouble("height", 220.0)!; + var bgcolor = widget.control.attrColor("bgcolor", context) ?? + CupertinoColors.systemBackground.resolveFrom(context); var padding = parseEdgeInsets(widget.control, "padding"); var contentCtrls = @@ -47,7 +48,7 @@ class _CupertinoBottomSheetControlState parentAdaptive: widget.parentAdaptive) : const SizedBox.shrink(); - if (height != null || bgcolor != null || padding != null) { + if (padding != null) { content = Container( height: height, padding: padding, @@ -55,7 +56,7 @@ class _CupertinoBottomSheetControlState margin: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom, ), - // Provide a background color for the popup. + // background color for the popup. color: bgcolor, // Use a SafeArea widget to avoid system overlaps. child: SafeArea( diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_bottom_sheet.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_bottom_sheet.py index a83ef75e8..9c88a98f2 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_bottom_sheet.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_bottom_sheet.py @@ -93,7 +93,7 @@ def bgcolor(self, value): # height @property def height(self) -> OptionalNumber: - return self._get_attr("height", data_type="float") + return self._get_attr("height", data_type="float", def_value=220) @height.setter def height(self, value: OptionalNumber): From 9340e9bf444214d4d7e29368cfcaa5ebb9b16aa7 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 23 Mar 2024 01:47:24 +0100 Subject: [PATCH 066/103] CupertinoBottomSheet: check the type of content control --- packages/flet/lib/src/controls/cupertino_bottom_sheet.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart index b2d327951..d73568650 100644 --- a/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart +++ b/packages/flet/lib/src/controls/cupertino_bottom_sheet.dart @@ -48,7 +48,10 @@ class _CupertinoBottomSheetControlState parentAdaptive: widget.parentAdaptive) : const SizedBox.shrink(); - if (padding != null) { + if (contentCtrls.isNotEmpty && + (contentCtrls.first.type == "cupertinopicker" || + contentCtrls.first.type == "cupertinotimerpicker" || + contentCtrls.first.type == "cupertinodatepicker")) { content = Container( height: height, padding: padding, From c91c73ea1515b02c48a1065a0574bec58f6ac654 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Sat, 23 Mar 2024 14:28:05 +0100 Subject: [PATCH 067/103] Locale: rename default_locale to current_locale :) --- packages/flet/lib/src/utils/locale.dart | 4 ++-- sdk/python/packages/flet-core/src/flet_core/page.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/utils/locale.dart b/packages/flet/lib/src/utils/locale.dart index 57ca734ff..7d02acac2 100644 --- a/packages/flet/lib/src/utils/locale.dart +++ b/packages/flet/lib/src/utils/locale.dart @@ -18,8 +18,8 @@ Map? parseLocaleConfiguration( Map localeConfigurationFromJSON(dynamic json) { List? supportedLocales; var sl = json["supported_locales"]; - Locale? locale = json["default_locale"] != null - ? localeFromJSON(json["default_locale"]) + Locale? locale = json["current_locale"] != null + ? localeFromJSON(json["current_locale"]) : null; if (sl != null) { supportedLocales = diff --git a/sdk/python/packages/flet-core/src/flet_core/page.py b/sdk/python/packages/flet-core/src/flet_core/page.py index 139b1bddf..85c1b8781 100644 --- a/sdk/python/packages/flet-core/src/flet_core/page.py +++ b/sdk/python/packages/flet-core/src/flet_core/page.py @@ -87,7 +87,7 @@ class Locale: @dataclass class LocaleConfiguration: supported_locales: Optional[List[Locale]] = field(default=None) - default_locale: Optional[Locale] = field(default=None) + current_locale: Optional[Locale] = field(default=None) class PageDisconnectedException(Exception): From 28366feff9e52fdc444f5fbcedf769e1e2f1aad9 Mon Sep 17 00:00:00 2001 From: TheEthicalBoy <98978078+ndonkoHenri@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:16:58 +0100 Subject: [PATCH 068/103] TimePicker.value: avoid splitting None --- .../packages/flet-core/src/flet_core/time_picker.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/time_picker.py b/sdk/python/packages/flet-core/src/flet_core/time_picker.py index 258c1fe26..03a3b8c2e 100644 --- a/sdk/python/packages/flet-core/src/flet_core/time_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/time_picker.py @@ -144,12 +144,11 @@ def value(self) -> Optional[time]: value_string = self._get_attr( "value", def_value=None ) # value_string in comes in format 'HH:MM' - splitted = value_string.split(":") - return ( - time(hour=int(splitted[0]), minute=int(splitted[1])) - if value_string - else None - ) + if value_string: + splitted = value_string.split(":") + return time(hour=int(splitted[0]), minute=int(splitted[1])) + else: + return None @value.setter def value(self, value: Optional[Union[time, str]]): From 1bab9805838e84c89708bedecfc726a1833ad03a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 13:43:49 +0100 Subject: [PATCH 069/103] AlertDialog: alignment, icon_color, scrollable, content_text_style, title_text_style, actions_overflow_button_spacing, --- .../flet/lib/src/controls/alert_dialog.dart | 12 +- .../flet-core/src/flet_core/alert_dialog.py | 105 +++++++++++++++--- 2 files changed, 100 insertions(+), 17 deletions(-) diff --git a/packages/flet/lib/src/controls/alert_dialog.dart b/packages/flet/lib/src/controls/alert_dialog.dart index 71abbc295..c08787599 100644 --- a/packages/flet/lib/src/controls/alert_dialog.dart +++ b/packages/flet/lib/src/controls/alert_dialog.dart @@ -5,6 +5,7 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; import '../utils/edge_insets.dart'; +import '../utils/text.dart'; import 'create_control.dart'; import 'cupertino_alert_dialog.dart'; import 'error.dart'; @@ -48,7 +49,7 @@ class _AlertDialogControlState extends State var actionCtrls = widget.children.where((c) => c.name == "action" && c.isVisible); final actionsAlignment = parseMainAxisAlignment( - widget.control, "actionsAlignment", MainAxisAlignment.start); + widget.control, "actionsAlignment", MainAxisAlignment.end); if (titleCtrls.isEmpty && contentCtrls.isEmpty && actionCtrls.isEmpty) { return const ErrorControl("AlertDialog does not have any content."); } @@ -91,6 +92,15 @@ class _AlertDialogControlState extends State ? createControl(widget.control, iconCtrls.first.id, disabled, parentAdaptive: adaptive) : null, + iconColor: widget.control.attrColor("iconColor", context), + scrollable: widget.control.attrBool("scrollable", false)!, + actionsOverflowButtonSpacing: + widget.control.attrDouble("actionsOverflowButtonSpacing"), + alignment: parseAlignment(widget.control, "alignment"), + contentTextStyle: + parseTextStyle(Theme.of(context), widget.control, "contentTextStyle"), + titleTextStyle: + parseTextStyle(Theme.of(context), widget.control, "titleTextStyle"), ); } diff --git a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py index bbad8b29f..eb38c6006 100644 --- a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py +++ b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py @@ -1,9 +1,11 @@ from typing import Any, List, Optional from flet_core.adaptive_control import AdaptiveControl +from flet_core.alignment import Alignment from flet_core.buttons import OutlinedBorder from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref +from flet_core.text_style import TextStyle from flet_core.types import ClipBehavior, MainAxisAlignment, PaddingValue @@ -73,16 +75,21 @@ def __init__( title_padding: PaddingValue = None, content_padding: PaddingValue = None, actions_padding: PaddingValue = None, - actions_alignment: MainAxisAlignment = MainAxisAlignment.NONE, + actions_alignment: MainAxisAlignment = None, shape: Optional[OutlinedBorder] = None, inset_padding: PaddingValue = None, icon_padding: PaddingValue = None, action_button_padding: PaddingValue = None, surface_tint_color: Optional[str] = None, shadow_color: Optional[str] = None, + icon_color: Optional[str] = None, + scrollable: Optional[bool] = None, + actions_overflow_button_spacing: OptionalNumber = None, + alignment: Optional[Alignment] = None, + content_text_style: Optional[TextStyle] = None, + title_text_style: Optional[TextStyle] = None, clip_behavior: Optional[ClipBehavior] = None, semantics_label: Optional[str] = None, - adaptive: Optional[bool] = None, on_dismiss=None, # # AdaptiveControl @@ -91,6 +98,7 @@ def __init__( disabled: Optional[bool] = None, visible: Optional[bool] = None, data: Any = None, + adaptive: Optional[bool] = None, ): Control.__init__( self, @@ -128,6 +136,12 @@ def __init__( self.shadow_color = shadow_color self.surface_tint_color = surface_tint_color self.icon_padding = icon_padding + self.icon_color = icon_color + self.scrollable = scrollable + self.actions_overflow_button_spacing = actions_overflow_button_spacing + self.alignment = alignment + self.content_text_style = content_text_style + self.title_text_style = title_text_style def _get_control_name(self): return "alertdialog" @@ -141,6 +155,11 @@ def before_update(self): self._set_attr_json("insetPadding", self.__inset_padding) self._set_attr_json("iconPadding", self.__icon_padding) self._set_attr_json("actionButtonPadding", self.__action_button_padding) + self._set_attr_json("alignment", self.__alignment) + if isinstance(self.__content_text_style, TextStyle): + self._set_attr_json("contentTextStyle", self.__content_text_style) + if isinstance(self.__title_text_style, TextStyle): + self._set_attr_json("titleTextStyle", self.__title_text_style) def _get_children(self): children = [] @@ -169,7 +188,7 @@ def open(self, value: Optional[bool]): # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter @@ -178,7 +197,7 @@ def bgcolor(self, value: Optional[str]): # shadow_color @property - def shadow_color(self): + def shadow_color(self) -> Optional[str]: return self._get_attr("shadowColor") @shadow_color.setter @@ -187,22 +206,76 @@ def shadow_color(self, value: Optional[str]): # surface_tint_color @property - def surface_tint_color(self): + def surface_tint_color(self) -> Optional[str]: return self._get_attr("surfaceTintColor") @surface_tint_color.setter def surface_tint_color(self, value: Optional[str]): self._set_attr("surfaceTintColor", value) + # icon_color + @property + def icon_color(self) -> Optional[str]: + return self._get_attr("iconColor") + + @icon_color.setter + def icon_color(self, value: Optional[str]): + self._set_attr("iconColor", value) + # elevation @property def elevation(self) -> OptionalNumber: - return self._get_attr("elevation") + return self._get_attr("elevation", data_type="float") @elevation.setter def elevation(self, value: OptionalNumber): self._set_attr("elevation", value) + # actions_overflow_button_spacing + @property + def actions_overflow_button_spacing(self) -> OptionalNumber: + return self._get_attr("actionsOverflowButtonSpacing", data_type="float") + + @actions_overflow_button_spacing.setter + def actions_overflow_button_spacing(self, value: OptionalNumber): + self._set_attr("actionsOverflowButtonSpacing", value) + + # scrollable + @property + def scrollable(self) -> Optional[bool]: + return self._get_attr("scrollable", data_type="bool", def_value=False) + + @scrollable.setter + def scrollable(self, value: Optional[bool]): + self._set_attr("scrollable", value) + + # alignment + @property + def alignment(self) -> Optional[Alignment]: + return self.__alignment + + @alignment.setter + def alignment(self, value: Optional[Alignment]): + self.__alignment = value + + # content_text_style + @property + def content_text_style(self) -> Optional[TextStyle]: + return self.__content_text_style + + @content_text_style.setter + def content_text_style(self, value: Optional[TextStyle]): + self.__content_text_style = value + + # title_text_style + @property + def title_text_style(self) -> Optional[TextStyle]: + return self.__title_text_style + + @title_text_style.setter + def title_text_style(self, value: Optional[TextStyle]): + self.__title_text_style = value + # modal @property def modal(self) -> Optional[bool]: @@ -214,20 +287,20 @@ def modal(self, value: Optional[bool]): # title @property - def title(self): + def title(self) -> Optional[Control]: return self.__title @title.setter - def title(self, value): + def title(self, value: Optional[Control]): self.__title = value # icon @property - def icon(self): + def icon(self) -> Optional[Control]: return self.__icon @icon.setter - def icon(self, value): + def icon(self, value: Optional[Control]): self.__icon = value # title_padding @@ -241,11 +314,11 @@ def title_padding(self, value: PaddingValue): # content @property - def content(self): + def content(self) -> Optional[Control]: return self.__content @content.setter - def content(self, value): + def content(self, value: Optional[Control]): self.__content = value # content_padding @@ -259,11 +332,11 @@ def content_padding(self, value: PaddingValue): # actions @property - def actions(self): + def actions(self) -> Optional[List[Control]]: return self.__actions @actions.setter - def actions(self, value): + def actions(self, value: Optional[List[Control]]): self.__actions = value if value is not None else [] # actions_padding @@ -326,11 +399,11 @@ def action_button_padding(self, value: PaddingValue): # semantics_label @property - def semantics_label(self): + def semantics_label(self) -> Optional[str]: return self._get_attr("semanticsLabel") @semantics_label.setter - def semantics_label(self, value): + def semantics_label(self, value: Optional[str]): self._set_attr("semanticsLabel", value) # clip_behavior From aca3b2f8a7848e4c6d1409dfdaa384dd0b9d80f3 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 13:52:14 +0100 Subject: [PATCH 070/103] AppBar: toolbar_opacity, title_text_style, toolbar_text_style,shape --- packages/flet/lib/src/controls/app_bar.dart | 17 +++--- .../flet-core/src/flet_core/app_bar.py | 59 ++++++++++++++++++- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/packages/flet/lib/src/controls/app_bar.dart b/packages/flet/lib/src/controls/app_bar.dart index 42c79ceb0..e56e65076 100644 --- a/packages/flet/lib/src/controls/app_bar.dart +++ b/packages/flet/lib/src/controls/app_bar.dart @@ -2,6 +2,8 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; +import '../utils/text.dart'; import '../utils/theme.dart'; import 'create_control.dart'; import 'cupertino_app_bar.dart'; @@ -47,17 +49,10 @@ class AppBarControl extends StatelessWidget var titleCtrls = children.where((c) => c.name == "title" && c.isVisible); var actionCtrls = children.where((c) => c.name == "action" && c.isVisible); - /* - var bottomCtrls = children.where((c) => - c.name == "bottom" && - (c.type == "cupertinoappbar" || - c.type == "appbar" || - c.type == "tabs") && // must be of type PreferredSizeWidget - c.isVisible); - */ var leadingWidth = control.attrDouble("leadingWidth"); var elevation = control.attrDouble("elevation"); + var toolbarOpacity = control.attrDouble("toolbarOpacity", 1)!; var centerTitle = control.attrBool("centerTitle", false)!; var automaticallyImplyLeading = control.attrBool("automaticallyImplyLeading", true)!; @@ -110,6 +105,12 @@ class AppBarControl extends StatelessWidget titleSpacing: titleSpacing, excludeHeaderSemantics: excludeHeaderSemantics, clipBehavior: clipBehavior, + titleTextStyle: + parseTextStyle(Theme.of(context), control, "titleTextStyle"), + shape: parseOutlinedBorder(control, "shape"), + toolbarOpacity: toolbarOpacity, + toolbarTextStyle: + parseTextStyle(Theme.of(context), control, "toolbarTextStyle"), ); }); } diff --git a/sdk/python/packages/flet-core/src/flet_core/app_bar.py b/sdk/python/packages/flet-core/src/flet_core/app_bar.py index 10f4426a4..3edf8476d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/app_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/app_bar.py @@ -1,8 +1,10 @@ from typing import List, Optional from flet_core.adaptive_control import AdaptiveControl +from flet_core.buttons import OutlinedBorder from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref +from flet_core.text_style import TextStyle from flet_core.types import ClipBehavior @@ -70,6 +72,10 @@ def __init__( title_spacing: OptionalNumber = None, exclude_header_semantics: Optional[bool] = None, actions: Optional[List[Control]] = None, + toolbar_opacity: OptionalNumber = None, + title_text_style: Optional[TextStyle] = None, + toolbar_text_style: Optional[TextStyle] = None, + shape: Optional[OutlinedBorder] = None, # # AdaptiveControl # @@ -102,10 +108,23 @@ def __init__( self.is_secondary = is_secondary self.title_spacing = title_spacing self.exclude_header_semantics = exclude_header_semantics + self.toolbar_opacity = toolbar_opacity + self.title_text_style = title_text_style + self.toolbar_text_style = toolbar_text_style + self.shape = shape def _get_control_name(self): return "appbar" + def before_update(self): + super().before_update() + if isinstance(self.__title_text_style, TextStyle): + self._set_attr_json("titleTextStyle", self.__title_text_style) + if isinstance(self.__toolbar_text_style, TextStyle): + self._set_attr_json("toolbarTextStyle", self.__toolbar_text_style) + if isinstance(self.__shape, OutlinedBorder): + self._set_attr_json("shape", self.__shape) + def _get_children(self): children = [] if self.__leading: @@ -151,6 +170,42 @@ def title_spacing(self) -> OptionalNumber: def title_spacing(self, value: OptionalNumber): self._set_attr("titleSpacing", value) + # toolbar_opacity + @property + def toolbar_opacity(self) -> OptionalNumber: + return self._get_attr("toolbarOpacity", data_type="float", def_value=1.0) + + @toolbar_opacity.setter + def toolbar_opacity(self, value: OptionalNumber): + self._set_attr("toolbarOpacity", value) + + # shape + @property + def shape(self) -> Optional[OutlinedBorder]: + return self.__shape + + @shape.setter + def shape(self, value: Optional[OutlinedBorder]): + self.__shape = value + + # title_text_style + @property + def title_text_style(self) -> Optional[TextStyle]: + return self.__title_text_style + + @title_text_style.setter + def title_text_style(self, value: Optional[TextStyle]): + self.__title_text_style = value + + # toolbar_text_style + @property + def toolbar_text_style(self) -> Optional[TextStyle]: + return self.__toolbar_text_style + + @toolbar_text_style.setter + def toolbar_text_style(self, value: Optional[TextStyle]): + self.__toolbar_text_style = value + # automatically_imply_leading @property def automatically_imply_leading(self) -> Optional[bool]: @@ -288,9 +343,9 @@ def clip_behavior(self, value: Optional[ClipBehavior]): # actions @property - def actions(self): + def actions(self) -> Optional[List[Control]]: return self.__actions @actions.setter - def actions(self, value): + def actions(self, value: Optional[List[Control]]): self.__actions = value if value is not None else [] From e53d7bbc9f4bba42b4d1747f27d4732ca5bfec82 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:01:23 +0100 Subject: [PATCH 071/103] parseMouseCursor: defaultMouseCursor --- .../lib/src/controls/gesture_detector.dart | 2 +- packages/flet/lib/src/utils/mouse.dart | 157 +++++++++--------- 2 files changed, 80 insertions(+), 79 deletions(-) diff --git a/packages/flet/lib/src/controls/gesture_detector.dart b/packages/flet/lib/src/controls/gesture_detector.dart index 975d9e257..eaef88492 100644 --- a/packages/flet/lib/src/controls/gesture_detector.dart +++ b/packages/flet/lib/src/controls/gesture_detector.dart @@ -557,7 +557,7 @@ class _GestureDetectorControlState extends State { var mouseCursor = widget.control.attrString("mouseCursor"); result = ((mouseCursor != null) || onHover || onEnter || onExit) ? MouseRegion( - cursor: parseMouseCursor(mouseCursor), + cursor: parseMouseCursor(mouseCursor)!, onHover: onHover ? (details) { handleHover(details); diff --git a/packages/flet/lib/src/utils/mouse.dart b/packages/flet/lib/src/utils/mouse.dart index 7b3c8762e..80d1dbcf0 100644 --- a/packages/flet/lib/src/utils/mouse.dart +++ b/packages/flet/lib/src/utils/mouse.dart @@ -1,80 +1,81 @@ import 'package:flutter/material.dart'; -MouseCursor parseMouseCursor(String? cursor) { - switch (cursor) { - case "alias": - return SystemMouseCursors.alias; - case "allScroll": - return SystemMouseCursors.allScroll; - case "basic": - return SystemMouseCursors.basic; - case "cell": - return SystemMouseCursors.cell; - case "click": - return SystemMouseCursors.click; - case "contextMenu": - return SystemMouseCursors.contextMenu; - case "copy": - return SystemMouseCursors.copy; - case "disappearing": - return SystemMouseCursors.disappearing; - case "forbidden": - return SystemMouseCursors.forbidden; - case "grab": - return SystemMouseCursors.grab; - case "grabbing": - return SystemMouseCursors.grabbing; - case "help": - return SystemMouseCursors.help; - case "move": - return SystemMouseCursors.move; - case "noDrop": - return SystemMouseCursors.noDrop; - case "none": - return SystemMouseCursors.none; - case "precise": - return SystemMouseCursors.precise; - case "progress": - return SystemMouseCursors.progress; - case "resizeColumn": - return SystemMouseCursors.resizeColumn; - case "resizeDown": - return SystemMouseCursors.resizeDown; - case "resizeDownLeft": - return SystemMouseCursors.resizeDownLeft; - case "resizeDownRight": - return SystemMouseCursors.resizeDownRight; - case "resizeLeft": - return SystemMouseCursors.resizeLeft; - case "resizeLeftRight": - return SystemMouseCursors.resizeLeftRight; - case "resizeRight": - return SystemMouseCursors.resizeRight; - case "resizeRow": - return SystemMouseCursors.resizeRow; - case "resizeUp": - return SystemMouseCursors.resizeUp; - case "resizeUpDown": - return SystemMouseCursors.resizeUpDown; - case "resizeUpLeft": - return SystemMouseCursors.resizeUpLeft; - case "resizeUpLeftDownRight": - return SystemMouseCursors.resizeUpLeftDownRight; - case "resizeUpRight": - return SystemMouseCursors.resizeUpRight; - case "resizeUpRightDownLeft": - return SystemMouseCursors.resizeUpRightDownLeft; - case "text": - return SystemMouseCursors.text; - case "verticalText": - return SystemMouseCursors.verticalText; - case "wait": - return SystemMouseCursors.wait; - case "zoomIn": - return SystemMouseCursors.zoomIn; - case "zoomOut": - return SystemMouseCursors.zoomOut; - default: - return MouseCursor.defer; - } - } \ No newline at end of file +MouseCursor? parseMouseCursor(String? cursor, + [MouseCursor? defaultMouseCursor = MouseCursor.defer]) { + switch (cursor) { + case "alias": + return SystemMouseCursors.alias; + case "allScroll": + return SystemMouseCursors.allScroll; + case "basic": + return SystemMouseCursors.basic; + case "cell": + return SystemMouseCursors.cell; + case "click": + return SystemMouseCursors.click; + case "contextMenu": + return SystemMouseCursors.contextMenu; + case "copy": + return SystemMouseCursors.copy; + case "disappearing": + return SystemMouseCursors.disappearing; + case "forbidden": + return SystemMouseCursors.forbidden; + case "grab": + return SystemMouseCursors.grab; + case "grabbing": + return SystemMouseCursors.grabbing; + case "help": + return SystemMouseCursors.help; + case "move": + return SystemMouseCursors.move; + case "noDrop": + return SystemMouseCursors.noDrop; + case "none": + return SystemMouseCursors.none; + case "precise": + return SystemMouseCursors.precise; + case "progress": + return SystemMouseCursors.progress; + case "resizeColumn": + return SystemMouseCursors.resizeColumn; + case "resizeDown": + return SystemMouseCursors.resizeDown; + case "resizeDownLeft": + return SystemMouseCursors.resizeDownLeft; + case "resizeDownRight": + return SystemMouseCursors.resizeDownRight; + case "resizeLeft": + return SystemMouseCursors.resizeLeft; + case "resizeLeftRight": + return SystemMouseCursors.resizeLeftRight; + case "resizeRight": + return SystemMouseCursors.resizeRight; + case "resizeRow": + return SystemMouseCursors.resizeRow; + case "resizeUp": + return SystemMouseCursors.resizeUp; + case "resizeUpDown": + return SystemMouseCursors.resizeUpDown; + case "resizeUpLeft": + return SystemMouseCursors.resizeUpLeft; + case "resizeUpLeftDownRight": + return SystemMouseCursors.resizeUpLeftDownRight; + case "resizeUpRight": + return SystemMouseCursors.resizeUpRight; + case "resizeUpRightDownLeft": + return SystemMouseCursors.resizeUpRightDownLeft; + case "text": + return SystemMouseCursors.text; + case "verticalText": + return SystemMouseCursors.verticalText; + case "wait": + return SystemMouseCursors.wait; + case "zoomIn": + return SystemMouseCursors.zoomIn; + case "zoomOut": + return SystemMouseCursors.zoomOut; + default: + return defaultMouseCursor; + } +} From 6bccaffeb08c15e96f5bda641aaef1b559743ce4 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:03:44 +0100 Subject: [PATCH 072/103] Checkbox: visual_density, mouse_cursor --- packages/flet/lib/src/controls/checkbox.dart | 6 ++++ .../flet-core/src/flet_core/checkbox.py | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/packages/flet/lib/src/controls/checkbox.dart b/packages/flet/lib/src/controls/checkbox.dart index 90d230e3a..111d691c0 100644 --- a/packages/flet/lib/src/controls/checkbox.dart +++ b/packages/flet/lib/src/controls/checkbox.dart @@ -4,7 +4,9 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/colors.dart'; +import '../utils/mouse.dart'; import '../utils/text.dart'; +import '../utils/theme.dart'; import 'create_control.dart'; import 'cupertino_checkbox.dart'; import 'flet_store_mixin.dart'; @@ -134,6 +136,10 @@ class _CheckboxControlState extends State with FletStoreMixin { fillColor: parseMaterialStateColor( Theme.of(context), widget.control, "fillColor"), tristate: _tristate, + visualDensity: parseVisualDensity( + widget.control.attrString("visualDensity"), null), + mouseCursor: + parseMouseCursor(widget.control.attrString("mouseCursor"), null), onChanged: !disabled ? (bool? value) { _onChange(value); diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index b3df740eb..43a04bd83 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -5,8 +5,10 @@ from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.text_style import TextStyle +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, LabelPosition, @@ -71,6 +73,8 @@ def __init__( splash_radius: OptionalNumber = None, border_side: Optional[BorderSide] = None, is_error: Optional[bool] = None, + visual_density: Optional[ThemeVisualDensity] = None, + mouse_cursor: Optional[MouseCursor] = None, on_change=None, on_focus=None, on_blur=None, @@ -159,6 +163,8 @@ def __init__( self.on_change = on_change self.on_focus = on_focus self.on_blur = on_blur + self.visual_density = visual_density + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "checkbox" @@ -214,6 +220,32 @@ def label_position(self, value: Optional[LabelPosition]): "labelPosition", value.value if isinstance(value, LabelPosition) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", + value.value if isinstance(value, MouseCursor) else value, + ) + + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + # autofocus @property def autofocus(self) -> Optional[bool]: From 3f92df2b0b5e7d26ddb3e8640f531914fe6b9ad8 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:16:16 +0100 Subject: [PATCH 073/103] Banner: content_text_style, margin, elevation, divider_color, shadow_color, surface_tint_color, on_visible --- packages/flet/lib/src/controls/banner.dart | 16 ++- .../flet/lib/src/controls/create_control.dart | 3 +- .../flet-core/src/flet_core/banner.py | 97 +++++++++++++++++-- 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/packages/flet/lib/src/controls/banner.dart b/packages/flet/lib/src/controls/banner.dart index e5b6bb884..016e40191 100644 --- a/packages/flet/lib/src/controls/banner.dart +++ b/packages/flet/lib/src/controls/banner.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; +import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/edge_insets.dart'; +import '../utils/text.dart'; import 'create_control.dart'; import 'error.dart'; @@ -12,6 +14,7 @@ class BannerControl extends StatefulWidget { final bool parentDisabled; final bool? parentAdaptive; final Widget? nextChild; + final FletControlBackend backend; const BannerControl( {super.key, @@ -20,7 +23,8 @@ class BannerControl extends StatefulWidget { required this.children, required this.parentDisabled, required this.parentAdaptive, - required this.nextChild}); + required this.nextChild, + required this.backend}); @override State createState() => _BannerControlState(); @@ -59,6 +63,16 @@ class _BannerControlState extends State { .toList(), forceActionsBelow: widget.control.attrBool("forceActionsBelow", false)!, backgroundColor: widget.control.attrColor("bgcolor", context), + contentTextStyle: + parseTextStyle(Theme.of(context), widget.control, "contentTextStyle"), + surfaceTintColor: widget.control.attrColor("surfaceTintColor", context), + shadowColor: widget.control.attrColor("shadowColor", context), + dividerColor: widget.control.attrColor("dividerColor", context), + elevation: widget.control.attrDouble("elevation"), + margin: parseEdgeInsets(widget.control, "margin"), + onVisible: () { + widget.backend.triggerControlEvent(widget.control.id, "visible"); + }, ); } diff --git a/packages/flet/lib/src/controls/create_control.dart b/packages/flet/lib/src/controls/create_control.dart index a069d80cb..ad9f60f47 100644 --- a/packages/flet/lib/src/controls/create_control.dart +++ b/packages/flet/lib/src/controls/create_control.dart @@ -886,7 +886,8 @@ Widget createWidget( children: controlView.children, parentDisabled: parentDisabled, parentAdaptive: parentAdaptive, - nextChild: nextChild); + nextChild: nextChild, + backend: backend); case "tabs": return TabsControl( key: key, diff --git a/sdk/python/packages/flet-core/src/flet_core/banner.py b/sdk/python/packages/flet-core/src/flet_core/banner.py index 5bc041de6..0f692bc1a 100644 --- a/sdk/python/packages/flet-core/src/flet_core/banner.py +++ b/sdk/python/packages/flet-core/src/flet_core/banner.py @@ -1,8 +1,9 @@ from typing import Any, List, Optional -from flet_core.control import Control +from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref -from flet_core.types import PaddingValue +from flet_core.text_style import TextStyle +from flet_core.types import PaddingValue, MarginValue class Banner(Control): @@ -57,6 +58,13 @@ def __init__( actions: Optional[List[Control]] = None, force_actions_below: Optional[bool] = None, bgcolor: Optional[str] = None, + surface_tint_color: Optional[str] = None, + shadow_color: Optional[str] = None, + divider_color: Optional[str] = None, + elevation: OptionalNumber = None, + margin: MarginValue = None, + content_text_style: Optional[TextStyle] = None, + on_visible=None, # # Control # @@ -86,6 +94,13 @@ def __init__( self.actions = actions self.force_actions_below = force_actions_below self.bgcolor = bgcolor + self.surface_tint_color = surface_tint_color + self.shadow_color = shadow_color + self.divider_color = divider_color + self.elevation = elevation + self.margin = margin + self.content_text_style = content_text_style + self.on_visible = on_visible def _get_control_name(self): return "banner" @@ -94,6 +109,9 @@ def before_update(self): super().before_update() self._set_attr_json("contentPadding", self.__content_padding) self._set_attr_json("leadingPadding", self.__leading_padding) + self._set_attr_json("margin", self.__margin) + if isinstance(self.__content_text_style, TextStyle): + self._set_attr_json("contentTextStyle", self.__content_text_style) def _get_children(self): children = [] @@ -128,11 +146,11 @@ def modal(self, value: Optional[bool]): # leading @property - def leading(self): + def leading(self) -> Optional[Control]: return self.__leading @leading.setter - def leading(self, value): + def leading(self, value: Optional[Control]): self.__leading = value # leading_padding @@ -146,11 +164,11 @@ def leading_padding(self, value: PaddingValue): # content @property - def content(self): + def content(self) -> Optional[Control]: return self.__content @content.setter - def content(self, value): + def content(self, value: Optional[Control]): self.__content = value # content_padding @@ -162,6 +180,15 @@ def content_padding(self) -> PaddingValue: def content_padding(self, value: PaddingValue): self.__content_padding = value + # margin + @property + def margin(self) -> MarginValue: + return self.__margin + + @margin.setter + def margin(self, value: MarginValue): + self.__margin = value + # actions @property def actions(self): @@ -182,9 +209,63 @@ def force_actions_below(self, value: Optional[bool]): # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgColor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgColor", value) + + # content_text_style + @property + def content_text_style(self) -> Optional[TextStyle]: + return self.__content_text_style + + @content_text_style.setter + def content_text_style(self, value: Optional[TextStyle]): + self.__content_text_style = value + + # shadow_color + @property + def shadow_color(self) -> Optional[str]: + return self._get_attr("shadowColor") + + @shadow_color.setter + def shadow_color(self, value: Optional[str]): + self._set_attr("shadowColor", value) + + # surface_tint_color + @property + def surface_tint_color(self) -> Optional[str]: + return self._get_attr("surfaceTintColor") + + @surface_tint_color.setter + def surface_tint_color(self, value: Optional[str]): + self._set_attr("surfaceTintColor", value) + + # divider_color + @property + def divider_color(self) -> Optional[str]: + return self._get_attr("dividerColor") + + @divider_color.setter + def divider_color(self, value: Optional[str]): + self._set_attr("dividerColor", value) + + # elevation + @property + def elevation(self) -> OptionalNumber: + return self._get_attr("elevation", data_type="float") + + @elevation.setter + def elevation(self, value: OptionalNumber): + self._set_attr("elevation", value) + + # on_visible + @property + def on_visible(self): + return self._get_event_handler("visible") + + @on_visible.setter + def on_visible(self, handler): + self._add_event_handler("visible", handler) From 3153dba409aab7514c65fd3860d58a7168411083 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:21:25 +0100 Subject: [PATCH 074/103] CupertinoListTile: leading_size, leading_to_title --- .../lib/src/controls/cupertino_list_tile.dart | 2 ++ .../src/flet_core/cupertino_list_tile.py | 31 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_list_tile.dart b/packages/flet/lib/src/controls/cupertino_list_tile.dart index 40c0ec9b9..82d7ffa1a 100644 --- a/packages/flet/lib/src/controls/cupertino_list_tile.dart +++ b/packages/flet/lib/src/controls/cupertino_list_tile.dart @@ -111,6 +111,8 @@ class CupertinoListTileControl extends StatelessWidget { backgroundColor: backgroundColor, backgroundColorActivated: bgcolorActivated, leading: leading, + leadingSize: control.attrDouble("leadingSize", 30.0)!, + leadingToTitle: control.attrDouble("leadingToTitle", 12.0)!, padding: padding, title: title, subtitle: subtitle, diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py index 23de32aaf..3c7b5d3a4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_list_tile.py @@ -150,7 +150,7 @@ def _get_control_name(self): def before_update(self): super().before_update() - self._set_attr_json("contentPadding", self.__padding) + self._set_attr_json("padding", self.__padding) def _get_children(self): children = [] @@ -182,20 +182,20 @@ def leading(self, value: Optional[Control]): # leading_size @property - def leading_size(self): - return self._get_attr("leadingSize") + def leading_size(self) -> OptionalNumber: + return self._get_attr("leadingSize", data_type="float", def_value=30.0) @leading_size.setter - def leading_size(self, value): + def leading_size(self, value: OptionalNumber): self._set_attr("leadingSize", value) # leading_to_title @property - def leading_to_title(self): - return self._get_attr("leadingToTitle") + def leading_to_title(self) -> OptionalNumber: + return self._get_attr("leadingToTitle", data_type="float", def_value=12.0) @leading_to_title.setter - def leading_to_title(self, value): + def leading_to_title(self, value: OptionalNumber): self._set_attr("leadingToTitle", value) # title @@ -254,29 +254,29 @@ def notched(self, value: Optional[bool]): # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) # bgcolor_activated @property - def bgcolor_activated(self): + def bgcolor_activated(self) -> Optional[str]: return self._get_attr("bgcolorActivated") @bgcolor_activated.setter - def bgcolor_activated(self, value): + def bgcolor_activated(self, value: Optional[str]): self._set_attr("bgcolorActivated", value) # url @property - def url(self): + def url(self) -> Optional[str]: return self._get_attr("url") @url.setter - def url(self, value): + def url(self, value: Optional[str]): self._set_attr("url", value) # url_target @@ -308,7 +308,4 @@ def on_click(self): @on_click.setter def on_click(self, handler): self._add_event_handler("click", handler) - if handler is not None: - self._set_attr("onclick", True) - else: - self._set_attr("onclick", None) + self._set_attr("onclick", True if handler is not None else None) From 7ad9c52d9bbd598ccf1d04183a086b3391f8815a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:39:53 +0100 Subject: [PATCH 075/103] Chip: surface_tint_color, color, click_elevation, clip_behavior, visual_density, border_side --- packages/flet/lib/src/controls/chip.dart | 39 +++++-- .../packages/flet-core/src/flet_core/chip.py | 102 +++++++++++++++--- 2 files changed, 121 insertions(+), 20 deletions(-) diff --git a/packages/flet/lib/src/controls/chip.dart b/packages/flet/lib/src/controls/chip.dart index 70041b1c4..77141da1f 100644 --- a/packages/flet/lib/src/controls/chip.dart +++ b/packages/flet/lib/src/controls/chip.dart @@ -3,8 +3,10 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; +import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/text.dart'; +import '../utils/theme.dart'; import 'create_control.dart'; import 'error.dart'; @@ -66,6 +68,7 @@ class _ChipControlState extends State { @override Widget build(BuildContext context) { debugPrint("Chip build: ${widget.control.id}"); + bool disabled = widget.control.isDisabled || widget.parentDisabled; var labelCtrls = widget.children.where((c) => c.name == "label" && c.isVisible); @@ -78,11 +81,26 @@ class _ChipControlState extends State { return const ErrorControl("Chip must have label specified."); } - bool disabled = widget.control.isDisabled || widget.parentDisabled; - - var bgcolor = widget.control.attrColor("bgcolor", context); - var deleteIconColor = widget.control.attrColor("deleteIconColor", context); - var disabledColor = widget.control.attrColor("disabledColor", context); + double? clickElevation = widget.control.attrDouble("clickElevation"); + Color? bgcolor = widget.control.attrColor("bgcolor", context); + Color? deleteIconColor = + widget.control.attrColor("deleteIconColor", context); + Color? disabledColor = widget.control.attrColor("disabledColor", context); + Color? surfaceTintColor = + widget.control.attrColor("surfaceTintColor", context); + Color? selectedShadowColor = + widget.control.attrColor("selectedShadowColor", context); + Color? shadowColor = widget.control.attrColor("shadowColor", context); + var color = + parseMaterialStateColor(Theme.of(context), widget.control, "color"); + + BorderSide? borderSide = + parseBorderSide(Theme.of(context), widget.control, "borderSide"); + VisualDensity? visualDensity = + parseVisualDensity(widget.control.attrString("visualDensity"), null); + Clip clipBehavior = Clip.values.firstWhere( + (c) => c.toString() == widget.control.attrString("clipBehavior", "")!, + orElse: () => Clip.none); bool onClick = widget.control.attrBool("onclick", false)!; bool onDelete = widget.control.attrBool("onDelete", false)!; @@ -155,10 +173,15 @@ class _ChipControlState extends State { labelStyle: parseTextStyle(Theme.of(context), widget.control, "labelStyle"), selectedColor: widget.control.attrColor("selectedColor", context), - selectedShadowColor: - widget.control.attrColor("selectedShadowColor", context), - shadowColor: widget.control.attrColor("shadowColor", context), + selectedShadowColor: selectedShadowColor, + shadowColor: shadowColor, shape: parseOutlinedBorder(widget.control, "shape"), + color: color, + surfaceTintColor: surfaceTintColor, + pressElevation: clickElevation, + side: borderSide, + clipBehavior: clipBehavior, + visualDensity: visualDensity, ), widget.parent, widget.control); diff --git a/sdk/python/packages/flet-core/src/flet_core/chip.py b/sdk/python/packages/flet-core/src/flet_core/chip.py index 1bc16787a..80b97874c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/chip.py +++ b/sdk/python/packages/flet-core/src/flet_core/chip.py @@ -1,10 +1,12 @@ -from typing import Any, Optional, Union +from typing import Any, Optional, Union, Dict +from flet_core.border import BorderSide from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref from flet_core.text_style import TextStyle +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, OffsetValue, @@ -12,6 +14,8 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, + MaterialState, ) @@ -82,6 +86,12 @@ def __init__( label_style: Optional[TextStyle] = None, selected_shadow_color: Optional[str] = None, autofocus: Optional[bool] = None, + surface_tint_color: Optional[str] = None, + color: Union[None, str, Dict[Union[MaterialState, str], str]] = None, + click_elevation: OptionalNumber = None, + clip_behavior: Optional[ClipBehavior] = None, + visual_density: Optional[ThemeVisualDensity] = None, + border_side: Optional[BorderSide] = None, on_click=None, on_delete=None, on_select=None, @@ -176,6 +186,12 @@ def __init__( self.on_select = on_select self.on_focus = on_focus self.on_blur = on_blur + self.color = color + self.surface_tint_color = surface_tint_color + self.click_elevation = click_elevation + self.clip_behavior = clip_behavior + self.visual_density = visual_density + self.border_side = border_side def _get_control_name(self): return "chip" @@ -186,6 +202,7 @@ def before_update(self): self._set_attr_json("labelStyle", self.__label_style) self._set_attr_json("padding", self.__padding) self._set_attr_json("shape", self.__shape) + self._set_attr_json("color", self.__color) def _get_children(self): children = [] @@ -299,6 +316,15 @@ def disabled_color(self): def disabled_color(self, value): self._set_attr("disabledColor", value) + # color + @property + def color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__color + + @color.setter + def color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__color = value + # autofocus @property def autofocus(self) -> Optional[bool]: @@ -310,58 +336,76 @@ def autofocus(self, value: Optional[bool]): # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) # check_color @property - def check_color(self): + def check_color(self) -> Optional[str]: return self._get_attr("checkColor") @check_color.setter - def check_color(self, value): + def check_color(self, value: Optional[str]): self._set_attr("checkColor", value) # selected_color @property - def selected_color(self): + def selected_color(self) -> Optional[str]: return self._get_attr("selectedColor") @selected_color.setter - def selected_color(self, value): + def selected_color(self, value: Optional[str]): self._set_attr("selectedColor", value) # selected_shadow_color @property - def selected_shadow_color(self): + def selected_shadow_color(self) -> Optional[str]: return self._get_attr("selectedShadowColor") @selected_shadow_color.setter - def selected_shadow_color(self, value): + def selected_shadow_color(self, value: Optional[str]): self._set_attr("selectedShadowColor", value) + # surface_tint_color + @property + def surface_tint_color(self) -> Optional[str]: + return self._get_attr("surfaceTintColor") + + @surface_tint_color.setter + def surface_tint_color(self, value: Optional[str]): + self._set_attr("surfaceTintColor", value) + # shadow_color @property - def shadow_color(self): + def shadow_color(self) -> Optional[str]: return self._get_attr("shadowColor") @shadow_color.setter - def shadow_color(self, value): + def shadow_color(self, value: Optional[str]): self._set_attr("shadowColor", value) # elevation @property def elevation(self) -> OptionalNumber: - return self._get_attr("elevation") + return self._get_attr("elevation", data_type="float") @elevation.setter def elevation(self, value: OptionalNumber): self._set_attr("elevation", value) + # click_elevation + @property + def click_elevation(self) -> OptionalNumber: + return self._get_attr("clickElevation", data_type="float") + + @click_elevation.setter + def click_elevation(self, value: OptionalNumber): + self._set_attr("clickElevation", value) + # shape @property def shape(self) -> Optional[OutlinedBorder]: @@ -371,6 +415,40 @@ def shape(self) -> Optional[OutlinedBorder]: def shape(self, value: Optional[OutlinedBorder]): self.__shape = value + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + + # border_side + @property + def border_side(self) -> Optional[BorderSide]: + return self.__border_side + + @border_side.setter + def border_side(self, value: Optional[BorderSide]): + self.__border_side = value + # on_click @property def on_click(self): From 097f8186dbd3de9e8f8a5bdeb97eb0c29da4a6a8 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:44:19 +0100 Subject: [PATCH 076/103] CupertinoRadio: toggleable, focus_color --- .../lib/src/controls/cupertino_radio.dart | 2 ++ .../src/flet_core/cupertino_radio.py | 26 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_radio.dart b/packages/flet/lib/src/controls/cupertino_radio.dart index 56878807a..811630307 100644 --- a/packages/flet/lib/src/controls/cupertino_radio.dart +++ b/packages/flet/lib/src/controls/cupertino_radio.dart @@ -92,6 +92,8 @@ class _CupertinoRadioControlState extends State useCheckmarkStyle: widget.control.attrBool("useCheckmarkStyle", false)!, fillColor: widget.control.attrColor("fillColor", context), + focusColor: widget.control.attrColor("focusColor", context), + toggleable: widget.control.attrBool("toggleable", false)!, activeColor: HexColor.fromString(Theme.of(context), widget.control.attrString("activeColor", "primary")!), inactiveColor: widget.control.attrColor("inactiveColor", context), diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py index 2d8d99bcd..75e78f1ed 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py @@ -37,6 +37,8 @@ def __init__( inactive_color: Optional[str] = None, autofocus: Optional[bool] = None, use_checkmark_style: Optional[bool] = None, + toggleable: Optional[bool] = None, + focus_color: Optional[str] = None, on_focus=None, on_blur=None, # @@ -110,6 +112,8 @@ def __init__( self.inactive_color = inactive_color self.on_focus = on_focus self.on_blur = on_blur + self.focus_color = focus_color + self.toggleable = toggleable def _get_control_name(self): return "cupertinoradio" @@ -128,11 +132,11 @@ def value(self, value: Optional[str]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) # label_position @@ -156,6 +160,24 @@ def fill_color(self) -> Optional[str]: def fill_color(self, value: Optional[str]): self._set_attr("fillColor", value) + # focus_color + @property + def focus_color(self) -> Optional[str]: + return self._get_attr("focusColor") + + @focus_color.setter + def focus_color(self, value: Optional[str]): + self._set_attr("focusColor", value) + + # toggleable + @property + def toggleable(self) -> Optional[bool]: + return self._get_attr("toggleable", data_type="bool", def_value=False) + + @toggleable.setter + def toggleable(self, value: Optional[bool]): + self._set_attr("toggleable", value) + # on_focus @property def on_focus(self): From aedcbf17e1ee9eaa85f1009f97a5c1330557dd8a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:47:07 +0100 Subject: [PATCH 077/103] CupertinoSegmentedButton: click_color --- .../controls/cupertino_segmented_button.dart | 2 ++ .../src/flet_core/cupertino_segmented_button.py | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_segmented_button.dart b/packages/flet/lib/src/controls/cupertino_segmented_button.dart index 263d78de5..6ab938a3b 100644 --- a/packages/flet/lib/src/controls/cupertino_segmented_button.dart +++ b/packages/flet/lib/src/controls/cupertino_segmented_button.dart @@ -41,6 +41,7 @@ class _CupertinoSegmentedButtonControlState var borderColor = widget.control.attrColor("borderColor", context); var selectedColor = widget.control.attrColor("selectedColor", context); var unselectedColor = widget.control.attrColor("unselectedColor", context); + var clickColor = widget.control.attrColor("clickColor", context); List ctrls = widget.children.where((c) => c.isVisible).toList(); int? selectedIndex = widget.control.attrInt("selectedIndex"); @@ -72,6 +73,7 @@ class _CupertinoSegmentedButtonControlState borderColor: borderColor, selectedColor: selectedColor, unselectedColor: unselectedColor, + pressedColor: clickColor, padding: parseEdgeInsets(widget.control, "padding"), ), widget.parent, diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py index e579a4e64..3e02e7f6f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_segmented_button.py @@ -30,6 +30,7 @@ def __init__( unselected_color: Optional[str] = None, border_color: Optional[str] = None, padding: PaddingValue = None, + click_color: Optional[str] = None, on_change=None, # # ConstrainedControl @@ -99,6 +100,7 @@ def __init__( self.selected_color = selected_color self.unselected_color = unselected_color self.on_change = on_change + self.click_color = click_color def _get_control_name(self): return "cupertinosegmentedbutton" @@ -112,7 +114,7 @@ def _before_build_command(self): # controls @property - def controls(self): + def controls(self) -> List[Control]: return self.__controls @controls.setter @@ -150,13 +152,22 @@ def selected_color(self, value: Optional[str]): # unselected_color @property - def unselected_color(self): + def unselected_color(self) -> Optional[str]: return self._get_attr("unselectedColor") @unselected_color.setter - def unselected_color(self, value): + def unselected_color(self, value: Optional[str]): self._set_attr("unselectedColor", value) + # click_color + @property + def click_color(self) -> Optional[str]: + return self._get_attr("clickColor") + + @click_color.setter + def click_color(self, value: Optional[str]): + self._set_attr("clickColor", value) + # padding @property def padding(self) -> PaddingValue: From ee02266e1b1bba1305888eff7f5450340d82cf4d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 14:53:31 +0100 Subject: [PATCH 078/103] CupertinoSwitch: on_label_color, off_label_color --- .../lib/src/controls/cupertino_switch.dart | 2 + .../src/flet_core/cupertino_switch.py | 40 ++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_switch.dart b/packages/flet/lib/src/controls/cupertino_switch.dart index 0028af4db..9dee0aea4 100644 --- a/packages/flet/lib/src/controls/cupertino_switch.dart +++ b/packages/flet/lib/src/controls/cupertino_switch.dart @@ -91,6 +91,8 @@ class _CupertinoSwitchControlState extends State { trackColor: materialTrackColor?.resolve({}), focusColor: widget.control.attrColor("focusColor", context), value: _value, + offLabelColor: widget.control.attrColor("offLabelColor", context), + onLabelColor: widget.control.attrColor("onLabelColor", context), onChanged: !disabled ? (bool value) { _onChange(value); diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_switch.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_switch.py index 509b9f615..ce256aa2e 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_switch.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_switch.py @@ -43,12 +43,14 @@ def __init__( self, label: Optional[str] = None, value: Optional[bool] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, active_color: Optional[str] = None, thumb_color: Optional[str] = None, track_color: Optional[str] = None, focus_color: Optional[str] = None, autofocus: Optional[bool] = None, + on_label_color: Optional[str] = None, + off_label_color: Optional[str] = None, on_change=None, on_focus=None, on_blur=None, @@ -124,6 +126,8 @@ def __init__( self.on_change = on_change self.on_focus = on_focus self.on_blur = on_blur + self.on_label_color = on_label_color + self.off_label_color = off_label_color def _get_control_name(self): return "cupertinoswitch" @@ -144,20 +148,20 @@ def value(self, value: Optional[bool]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value @@ -174,20 +178,20 @@ def autofocus(self, value: Optional[bool]): # active_color @property - def active_color(self): + def active_color(self) -> Optional[str]: return self._get_attr("activeColor") @active_color.setter - def active_color(self, value): + def active_color(self, value: Optional[str]): self._set_attr("activeColor", value) # focus_color @property - def focus_color(self): + def focus_color(self) -> Optional[str]: return self._get_attr("focusColor") @focus_color.setter - def focus_color(self, value): + def focus_color(self, value: Optional[str]): self._set_attr("focusColor", value) # thumb_color @@ -208,6 +212,24 @@ def track_color(self) -> Optional[str]: def track_color(self, value: Optional[str]): self.__track_color = value + # on_label_color + @property + def on_label_color(self) -> Optional[str]: + return self._get_attr("onLabelColor") + + @on_label_color.setter + def on_label_color(self, value: Optional[str]): + self._set_attr("onLabelColor", value) + + # off_label_color + @property + def off_label_color(self) -> Optional[str]: + return self._get_attr("offLabelColor") + + @off_label_color.setter + def off_label_color(self, value: Optional[str]): + self._set_attr("offLabelColor", value) + # on_change @property def on_change(self): From 88a5d618fe1daade633da86f2bd4e8e3e17d4ccd Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:01:55 +0100 Subject: [PATCH 079/103] Switch: hover_color, splash_radius, overlay_color, track_outline_color,mouse_cursor --- packages/flet/lib/src/controls/switch.dart | 9 +++ .../flet-core/src/flet_core/switch.py | 66 ++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/switch.dart b/packages/flet/lib/src/controls/switch.dart index 54a4d5c5d..01ab6f1d3 100644 --- a/packages/flet/lib/src/controls/switch.dart +++ b/packages/flet/lib/src/controls/switch.dart @@ -4,6 +4,7 @@ import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; import '../utils/icons.dart'; +import '../utils/mouse.dart'; import '../utils/text.dart'; import 'create_control.dart'; import 'cupertino_switch.dart'; @@ -118,6 +119,14 @@ class _SwitchControlState extends State with FletStoreMixin { Theme.of(context), widget.control, "trackColor"), focusColor: widget.control.attrColor("focusColor", context), value: _value, + mouseCursor: + parseMouseCursor(widget.control.attrString("mouseCursor")), + splashRadius: widget.control.attrDouble("splashRadius"), + hoverColor: widget.control.attrColor("hoverColor", context), + overlayColor: parseMaterialStateColor( + Theme.of(context), widget.control, "overlayColor"), + trackOutlineColor: parseMaterialStateColor( + Theme.of(context), widget.control, "trackOutlineColor"), onChanged: !disabled ? (bool value) { _onChange(value); diff --git a/sdk/python/packages/flet-core/src/flet_core/switch.py b/sdk/python/packages/flet-core/src/flet_core/switch.py index efc8bc80f..c67602de7 100644 --- a/sdk/python/packages/flet-core/src/flet_core/switch.py +++ b/sdk/python/packages/flet-core/src/flet_core/switch.py @@ -3,6 +3,7 @@ from flet_core.adaptive_control import AdaptiveControl from flet_core.constrained_control import ConstrainedControl from flet_core.control import OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.text_style import TextStyle from flet_core.types import ( @@ -66,6 +67,11 @@ def __init__( thumb_icon: Union[None, str, Dict[MaterialState, str]] = None, track_color: Union[None, str, Dict[MaterialState, str]] = None, adaptive: Optional[bool] = None, + hover_color: Optional[str] = None, + splash_radius: OptionalNumber = None, + overlay_color: Union[None, str, Dict[MaterialState, str]] = None, + track_outline_color: Union[None, str, Dict[MaterialState, str]] = None, + mouse_cursor: Optional[MouseCursor] = None, on_change=None, on_focus=None, on_blur=None, @@ -149,6 +155,11 @@ def __init__( self.on_change = on_change self.on_focus = on_focus self.on_blur = on_blur + self.hover_color = hover_color + self.splash_radius = splash_radius + self.overlay_color = overlay_color + self.track_outline_color = track_outline_color + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "switch" @@ -156,6 +167,8 @@ def _get_control_name(self): def before_update(self): super().before_update() self._set_attr_json("thumbColor", self.__thumb_color) + self._set_attr_json("overlayColor", self.__overlay_color) + self._set_attr_json("trackOutlineColor", self.__track_outline_color) self._set_attr_json("thumbIcon", self.__thumb_icon) self._set_attr_json("trackColor", self.__track_color) if isinstance(self.__label_style, TextStyle): @@ -172,13 +185,49 @@ def value(self, value: Optional[bool]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) + # hover_color + @property + def hover_color(self) -> Optional[str]: + return self._get_attr("hoverColor") + + @hover_color.setter + def hover_color(self, value: Optional[str]): + self._set_attr("hoverColor", value) + + # track_outline_color + @property + def track_outline_color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__track_outline_color + + @track_outline_color.setter + def track_outline_color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__track_outline_color = value + + # overlay_color + @property + def overlay_color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__overlay_color + + @overlay_color.setter + def overlay_color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__overlay_color = value + + # splash_radius + @property + def splash_radius(self) -> OptionalNumber: + return self._get_attr("splashRadius", data_type="float") + + @splash_radius.setter + def splash_radius(self, value: OptionalNumber): + self._set_attr("splashRadius", value) + # label_style @property def label_style(self) -> Optional[TextStyle]: @@ -200,6 +249,19 @@ def label_position(self, value: LabelPosition): "labelPosition", value.value if isinstance(value, LabelPosition) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> MouseCursor: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: MouseCursor): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", + value.value if isinstance(value, MouseCursor) else value, + ) + # autofocus @property def autofocus(self) -> Optional[bool]: From 85c128d7bec999452ae72139c7e1a271a3858ab1 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:05:43 +0100 Subject: [PATCH 080/103] Snackbar: action_overflow_threshold --- packages/flet/lib/src/controls/snack_bar.dart | 2 ++ .../flet-core/src/flet_core/snack_bar.py | 33 ++++++++++++------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/flet/lib/src/controls/snack_bar.dart b/packages/flet/lib/src/controls/snack_bar.dart index b22c45532..d020c6c81 100644 --- a/packages/flet/lib/src/controls/snack_bar.dart +++ b/packages/flet/lib/src/controls/snack_bar.dart @@ -71,6 +71,8 @@ class _SnackBarControlState extends State { return SnackBar( behavior: behavior, clipBehavior: clipBehavior, + actionOverflowThreshold: + widget.control.attrDouble("actionOverflowThreshold"), shape: parseOutlinedBorder(widget.control, "shape"), onVisible: () { debugPrint("SnackBar.onVisible(${widget.control.id})"); diff --git a/sdk/python/packages/flet-core/src/flet_core/snack_bar.py b/sdk/python/packages/flet-core/src/flet_core/snack_bar.py index 34f403017..f60182f20 100644 --- a/sdk/python/packages/flet-core/src/flet_core/snack_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/snack_bar.py @@ -78,6 +78,7 @@ def __init__( elevation: OptionalNumber = None, shape: Optional[OutlinedBorder] = None, clip_behavior: Optional[ClipBehavior] = None, + action_overflow_threshold: OptionalNumber = None, on_action=None, on_visible=None, # @@ -114,6 +115,7 @@ def __init__( self.on_visible = on_visible self.shape = shape self.clip_behavior = clip_behavior + self.action_overflow_threshold = action_overflow_threshold def _get_control_name(self): return "snackbar" @@ -160,49 +162,58 @@ def content(self, value: Control): # action @property - def action(self): + def action(self) -> Optional[str]: return self._get_attr("action") @action.setter - def action(self, value): + def action(self, value: Optional[str]): self._set_attr("action", value) # action_color @property - def action_color(self): + def action_color(self) -> Optional[str]: return self._get_attr("actionColor") @action_color.setter - def action_color(self, value): + def action_color(self, value: Optional[str]): self._set_attr("actionColor", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgColor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgColor", value) # close_icon_color @property - def close_icon_color(self): + def close_icon_color(self) -> Optional[str]: return self._get_attr("closeIconColor") @close_icon_color.setter - def close_icon_color(self, value): + def close_icon_color(self, value: Optional[str]): self._set_attr("closeIconColor", value) # duration @property def duration(self) -> Optional[int]: - return self._get_attr("duration") + return self._get_attr("duration", data_type="int") @duration.setter def duration(self, value: Optional[int]): self._set_attr("duration", value) + # action_overflow_threshold + @property + def action_overflow_threshold(self) -> OptionalNumber: + return self._get_attr("actionOverflowThreshold", data_type="float") + + @action_overflow_threshold.setter + def action_overflow_threshold(self, value: OptionalNumber): + self._set_attr("actionOverflowThreshold", value) + # behavior @property def behavior(self) -> Optional[SnackBarBehavior]: @@ -250,7 +261,7 @@ def margin(self, value: MarginValue): # width @property def width(self) -> OptionalNumber: - return self._get_attr("width") + return self._get_attr("width", data_type="float") @width.setter def width(self, value: OptionalNumber): @@ -259,7 +270,7 @@ def width(self, value: OptionalNumber): # elevation @property def elevation(self) -> OptionalNumber: - return self._get_attr("elevation") + return self._get_attr("elevation", data_type="float") @elevation.setter def elevation(self, value: OptionalNumber): From 17d652e3b022ac122033b57dd06feda19a976c5e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:11:36 +0100 Subject: [PATCH 081/103] Tabs: is_secondary, mouseCursor, clipBehavior --- packages/flet/lib/src/controls/tabs.dart | 17 +++++-- .../flet-core/src/flet_core/switch.py | 4 +- .../packages/flet-core/src/flet_core/tabs.py | 48 +++++++++++++++---- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/packages/flet/lib/src/controls/tabs.dart b/packages/flet/lib/src/controls/tabs.dart index 9be2b062f..009b6b264 100644 --- a/packages/flet/lib/src/controls/tabs.dart +++ b/packages/flet/lib/src/controls/tabs.dart @@ -13,6 +13,7 @@ import '../utils/colors.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/material_state.dart'; +import '../utils/mouse.dart'; import 'create_control.dart'; class TabsControl extends StatefulWidget { @@ -131,14 +132,14 @@ class _TabsControlState extends State var indicatorColor = widget.control.attrColor("indicatorColor", context) ?? TabBarTheme.of(context).indicatorColor ?? - Theme.of(context).colorScheme.primary; + Theme.of(context).colorScheme.primary; var labelColor = widget.control.attrColor("labelColor", context) ?? TabBarTheme.of(context).labelColor ?? Theme.of(context).colorScheme.primary; var unselectedLabelColor = widget.control.attrColor("unselectedLabelColor", context) ?? TabBarTheme.of(context).unselectedLabelColor ?? - Theme.of(context).colorScheme.onSurface; + Theme.of(context).colorScheme.onSurface; var dividerColor = widget.control.attrColor("dividerColor", context) ?? TabBarTheme.of(context).dividerColor; @@ -147,13 +148,20 @@ class _TabsControlState extends State TabBarTheme.of(context).indicator as UnderlineTabIndicator?; var indicatorTabSize = widget.control.attrBool("indicatorTabSize"); var isScrollable = widget.control.attrBool("scrollable", true)!; - var secondary = widget.control.attrBool("secondary", false)!; + var secondary = widget.control.attrBool("isSecondary", false)!; var dividerHeight = widget.control.attrDouble("dividerHeight"); var enableFeedback = widget.control.attrBool("enableFeedback"); var indicatorWeight = widget.control.attrDouble("indicatorThickness", 2.0)!; var tabAlignment = parseTabAlignment(widget.control, "tabAlignment", isScrollable ? TabAlignment.start : TabAlignment.fill); + var mouseCursor = + parseMouseCursor(widget.control.attrString("mouseCursor")); + var clipBehavior = Clip.values.firstWhere( + (e) => + e.name.toLowerCase() == + widget.control.attrString("clipBehavior", "")!.toLowerCase(), + orElse: () => Clip.hardEdge); var indicator = indicatorBorderRadius != null || indicatorBorderSide != null || @@ -218,6 +226,7 @@ class _TabsControlState extends State isScrollable: isScrollable, dividerHeight: dividerHeight, enableFeedback: enableFeedback, + mouseCursor: mouseCursor, indicatorWeight: indicatorWeight, dividerColor: dividerColor, indicatorSize: indicatorSize, @@ -234,6 +243,7 @@ class _TabsControlState extends State isScrollable: isScrollable, dividerHeight: dividerHeight, enableFeedback: enableFeedback, + mouseCursor: mouseCursor, indicatorWeight: indicatorWeight, dividerColor: dividerColor, indicatorSize: indicatorSize, @@ -258,6 +268,7 @@ class _TabsControlState extends State Expanded( child: TabBarView( controller: _tabController, + clipBehavior: clipBehavior, children: viewModel.controlViews.map((tabView) { var contentCtrls = tabView.children .where((c) => c.name == "content" && c.isVisible); diff --git a/sdk/python/packages/flet-core/src/flet_core/switch.py b/sdk/python/packages/flet-core/src/flet_core/switch.py index c67602de7..4b21c915c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/switch.py +++ b/sdk/python/packages/flet-core/src/flet_core/switch.py @@ -251,11 +251,11 @@ def label_position(self, value: LabelPosition): # mouse_cursor @property - def mouse_cursor(self) -> MouseCursor: + def mouse_cursor(self) -> Optional[MouseCursor]: return self.__mouse_cursor @mouse_cursor.setter - def mouse_cursor(self, value: MouseCursor): + def mouse_cursor(self, value: Optional[MouseCursor]): self.__mouse_cursor = value self._set_attr( "mouseCursor", diff --git a/sdk/python/packages/flet-core/src/flet_core/tabs.py b/sdk/python/packages/flet-core/src/flet_core/tabs.py index 24890d906..cf1d02055 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tabs.py +++ b/sdk/python/packages/flet-core/src/flet_core/tabs.py @@ -4,6 +4,7 @@ from flet_core.border import BorderSide from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.types import ( AnimationValue, @@ -15,6 +16,7 @@ RotateValue, ScaleValue, TabAlignment, + ClipBehavior, ) @@ -151,13 +153,15 @@ def __init__( indicator_border_side: Optional[BorderSide] = None, indicator_padding: PaddingValue = None, indicator_tab_size: Optional[bool] = None, - secondary: Optional[bool] = None, + is_secondary: Optional[bool] = None, label_color: Optional[str] = None, unselected_label_color: Optional[str] = None, overlay_color: Union[None, str, Dict[MaterialState, str]] = None, divider_height: OptionalNumber = None, indicator_thickness: OptionalNumber = None, enable_feedback: Optional[str] = None, + mouse_cursor: Optional[MouseCursor] = None, + clip_behavior: Optional[ClipBehavior] = None, on_change=None, # # ConstrainedControl and AdaptiveControl @@ -240,7 +244,9 @@ def __init__( self.divider_height = divider_height self.indicator_thickness = indicator_thickness self.enable_feedback = enable_feedback - self.secondary = secondary + self.is_secondary = is_secondary + self.mouse_cursor = mouse_cursor + self.clip_behavior = clip_behavior def _get_control_name(self): return "tabs" @@ -291,14 +297,40 @@ def scrollable(self) -> Optional[bool]: def scrollable(self, value: Optional[bool]): self._set_attr("scrollable", value) - # secondary + # mouse_cursor @property - def secondary(self) -> Optional[bool]: - return self._get_attr("secondary", data_type="bool", def_value=False) + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor - @secondary.setter - def secondary(self, value: Optional[bool]): - self._set_attr("secondary", value) + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", + value.value if isinstance(value, MouseCursor) else value, + ) + + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", + value.value if isinstance(value, ClipBehavior) else value, + ) + + # is_secondary + @property + def is_secondary(self) -> Optional[bool]: + return self._get_attr("isSecondary", data_type="bool", def_value=False) + + @is_secondary.setter + def is_secondary(self, value: Optional[bool]): + self._set_attr("isSecondary", value) # tab_alignment @property From 43cb566bddd49a408a863b00a3a63890ef7ae7da Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:20:35 +0100 Subject: [PATCH 082/103] Slider: mouse_cursor, secondary_track_value, secondary_active_color --- packages/flet/lib/src/controls/slider.dart | 6 +++ .../flet-core/src/flet_core/slider.py | 52 ++++++++++++++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/packages/flet/lib/src/controls/slider.dart b/packages/flet/lib/src/controls/slider.dart index 8f1c512ac..73f501782 100644 --- a/packages/flet/lib/src/controls/slider.dart +++ b/packages/flet/lib/src/controls/slider.dart @@ -6,6 +6,7 @@ import '../models/control.dart'; import '../utils/colors.dart'; import '../utils/debouncer.dart'; import '../utils/desktop.dart'; +import '../utils/mouse.dart'; import 'create_control.dart'; import 'cupertino_slider.dart'; import 'flet_store_mixin.dart'; @@ -130,6 +131,11 @@ class _SliderControlState extends State with FletStoreMixin { onChange(value); } : null, + mouseCursor: + parseMouseCursor(widget.control.attrString("mouseCursor")), + secondaryActiveColor: + widget.control.attrColor("secondaryActiveColor", context), + secondaryTrackValue: widget.control.attrDouble("secondaryTrackValue"), onChangeStart: !disabled ? (double value) { widget.backend.triggerControlEvent( diff --git a/sdk/python/packages/flet-core/src/flet_core/slider.py b/sdk/python/packages/flet-core/src/flet_core/slider.py index 29878c361..9b5fb2c2e 100644 --- a/sdk/python/packages/flet-core/src/flet_core/slider.py +++ b/sdk/python/packages/flet-core/src/flet_core/slider.py @@ -4,6 +4,7 @@ from flet_core.adaptive_control import AdaptiveControl from flet_core.constrained_control import ConstrainedControl from flet_core.control import OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.types import ( AnimationValue, @@ -60,7 +61,10 @@ def __init__( inactive_color: Optional[str] = None, thumb_color: Optional[str] = None, interaction: Optional[SliderInteraction] = None, + secondary_active_color: Optional[str] = None, overlay_color: Union[None, str, Dict[MaterialState, str]] = None, + secondary_track_value: OptionalNumber = None, + mouse_cursor: Optional[MouseCursor] = None, on_change=None, on_change_start=None, on_change_end=None, @@ -148,6 +152,9 @@ def __init__( self.on_change_end = on_change_end self.on_focus = on_focus self.on_blur = on_blur + self.secondary_active_color = secondary_active_color + self.secondary_track_value = secondary_track_value + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "slider" @@ -173,11 +180,11 @@ def value(self, value: OptionalNumber): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) # interaction @@ -202,6 +209,35 @@ def min(self) -> OptionalNumber: def min(self, value: OptionalNumber): self._set_attr("min", value) + # secondary_track_value + @property + def secondary_track_value(self) -> OptionalNumber: + return self._get_attr("secondaryTrackValue", data_type="float") + + @secondary_track_value.setter + def secondary_track_value(self, value: OptionalNumber): + self._set_attr("secondaryTrackValue", value) + + # secondary_active_color + @property + def secondary_active_color(self) -> Optional[str]: + return self._get_attr("secondaryActiveColor") + + @secondary_active_color.setter + def secondary_active_color(self, value: Optional[str]): + self._set_attr("secondaryActiveColor", value) + + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self._get_attr("mouseCursor") + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + # max @property def max(self) -> OptionalNumber: @@ -249,29 +285,29 @@ def autofocus(self, value: Optional[bool]): # active_color @property - def active_color(self): + def active_color(self) -> Optional[str]: return self._get_attr("activeColor") @active_color.setter - def active_color(self, value): + def active_color(self, value: Optional[str]): self._set_attr("activeColor", value) # inactive_color @property - def inactive_color(self): + def inactive_color(self) -> Optional[str]: return self._get_attr("inactiveColor") @inactive_color.setter - def inactive_color(self, value): + def inactive_color(self, value: Optional[str]): self._set_attr("inactiveColor", value) # thumb_color @property - def thumb_color(self): + def thumb_color(self) -> Optional[str]: return self._get_attr("thumbColor") @thumb_color.setter - def thumb_color(self, value): + def thumb_color(self, value: Optional[str]): self._set_attr("thumbColor", value) # on_change From 5b084a91bf7e9e34fc2f1d167018804be3e18e9e Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:25:00 +0100 Subject: [PATCH 083/103] PopupMenuItem: mouse_cursor --- .../lib/src/controls/popup_menu_button.dart | 9 ++++++-- .../src/flet_core/popup_menu_button.py | 22 +++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/flet/lib/src/controls/popup_menu_button.dart b/packages/flet/lib/src/controls/popup_menu_button.dart index 826ddef05..4bcfec70c 100644 --- a/packages/flet/lib/src/controls/popup_menu_button.dart +++ b/packages/flet/lib/src/controls/popup_menu_button.dart @@ -6,6 +6,7 @@ import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; +import '../utils/mouse.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; @@ -123,7 +124,9 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { checked: checked, height: height, padding: padding, - enabled: !disabled, + enabled: !disabled || !cv.control.isDisabled, + mouseCursor: parseMouseCursor( + cv.control.attrString("mouseCursor")), onTap: () { backend.triggerControlEvent(cv.control.id, "click"); }, @@ -133,7 +136,9 @@ class PopupMenuButtonControl extends StatelessWidget with FletStoreMixin { value: cv.control.id, height: height, padding: padding, - enabled: !disabled, + enabled: !disabled || !cv.control.isDisabled, + mouseCursor: parseMouseCursor( + cv.control.attrString("mouseCursor")), onTap: () { backend.triggerControlEvent(cv.control.id, "click"); }, diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 0fe9c29b6..3d45bb41c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -2,6 +2,7 @@ from enum import Enum from typing import Any, List, Optional, Union +from flet_core import MouseCursor from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber @@ -31,6 +32,7 @@ def __init__( content: Optional[Control] = None, height: OptionalNumber = None, padding: PaddingValue = None, + mouse_cursor: Optional[MouseCursor] = None, on_click=None, # # Control @@ -49,6 +51,7 @@ def __init__( self.on_click = on_click self.height = height self.padding = padding + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "popupmenuitem" @@ -69,13 +72,24 @@ def checked(self) -> Optional[bool]: def checked(self, value: Optional[bool]): self._set_attr("checked", value) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self._get_attr("mouseCursor") + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) # text @@ -107,11 +121,11 @@ def padding(self, value: PaddingValue): # content @property - def content(self): + def content(self) -> Optional[Control]: return self.__content @content.setter - def content(self, value): + def content(self, value: Optional[Control]): self.__content = value # on_click From 4189d7ce8315eb6c4271fb71200286f5b35cb45b Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:27:00 +0100 Subject: [PATCH 084/103] NavigationDrawerDestination: bgcolor --- .../lib/src/controls/navigation_drawer.dart | 4 +-- .../src/flet_core/navigation_drawer.py | 30 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/packages/flet/lib/src/controls/navigation_drawer.dart b/packages/flet/lib/src/controls/navigation_drawer.dart index 8b4507f3a..80202f91c 100644 --- a/packages/flet/lib/src/controls/navigation_drawer.dart +++ b/packages/flet/lib/src/controls/navigation_drawer.dart @@ -68,9 +68,7 @@ class _NavigationDrawerControlState extends State var selectedIconContentCtrls = destView.children.where((c) => c.name == "selected_icon_content"); return NavigationDrawerDestination( - // backgroundColor: HexColor.fromString(Theme.of(context), - // destView.control.attrString("bgColor", "")!), - // flutter issue https://github.com/flutter/flutter/issues/138105 + backgroundColor: destView.control.attrColor("bgColor", context), icon: iconContentCtrls.isNotEmpty ? createControl( destView.control, iconContentCtrls.first.id, disabled, diff --git a/sdk/python/packages/flet-core/src/flet_core/navigation_drawer.py b/sdk/python/packages/flet-core/src/flet_core/navigation_drawer.py index 7bad3cea8..1cf87dbf9 100644 --- a/sdk/python/packages/flet-core/src/flet_core/navigation_drawer.py +++ b/sdk/python/packages/flet-core/src/flet_core/navigation_drawer.py @@ -19,7 +19,7 @@ def __init__( icon_content: Optional[Control] = None, selected_icon: Optional[str] = None, selected_icon_content: Optional[Control] = None, - # bgcolor: Optional[str] = None, + bgcolor: Optional[str] = None, # # Control # @@ -27,7 +27,7 @@ def __init__( ): Control.__init__(self, ref=ref) self.label = label - # self.bgcolor = bgcolor + self.bgcolor = bgcolor self.icon = icon self.__icon_content: Optional[Control] = None self.icon_content = icon_content @@ -50,22 +50,22 @@ def _get_children(self): children.append(self.__selected_icon_content) return children - # # bgcolor - # @property - # def bgcolor(self): - # return self._get_attr("bgColor") + # bgcolor + @property + def bgcolor(self) -> Optional[str]: + return self._get_attr("bgColor") - # @bgcolor.setter - # def bgcolor(self, value): - # self._set_attr("bgColor", value) + @bgcolor.setter + def bgcolor(self, value: Optional[str]): + self._set_attr("bgColor", value) # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) # icon_content @@ -79,11 +79,11 @@ def icon_content(self, value: Optional[Control]): # selected_icon @property - def selected_icon(self): + def selected_icon(self) -> Optional[str]: return self._get_attr("selectedIcon") @selected_icon.setter - def selected_icon(self, value): + def selected_icon(self, value: Optional[str]): self._set_attr("selectedIcon", value) # selected_icon_content @@ -97,11 +97,11 @@ def selected_icon_content(self, value: Optional[Control]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) From e5869cea4391415de1e06f8bde76f1ca4b835176 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:32:14 +0100 Subject: [PATCH 085/103] NavigationDestination: bgcolor --- .../controls/cupertino_navigation_bar.dart | 1 + .../flet-core/src/flet_core/navigation_bar.py | 23 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/packages/flet/lib/src/controls/cupertino_navigation_bar.dart b/packages/flet/lib/src/controls/cupertino_navigation_bar.dart index 7ff2541a7..d3322480e 100644 --- a/packages/flet/lib/src/controls/cupertino_navigation_bar.dart +++ b/packages/flet/lib/src/controls/cupertino_navigation_bar.dart @@ -81,6 +81,7 @@ class _CupertinoNavigationBarControlState return BottomNavigationBarItem( tooltip: destView.control.attrString("tooltip", "")!, + backgroundColor: widget.control.attrColor("bgColor", context), icon: iconContentCtrls.isNotEmpty ? createControl( destView.control, iconContentCtrls.first.id, disabled, diff --git a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py index 29133a96c..2f2b443d5 100644 --- a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py @@ -45,6 +45,7 @@ def __init__( icon_content: Optional[Control] = None, selected_icon: Optional[str] = None, selected_icon_content: Optional[Control] = None, + bgcolor: Optional[str] = None, # # Control # @@ -59,6 +60,7 @@ def __init__( self.selected_icon = selected_icon self.__selected_icon_content: Optional[Control] = None self.selected_icon_content = selected_icon_content + self.bgcolor = bgcolor def _get_control_name(self): return "navigationdestination" @@ -77,11 +79,11 @@ def _get_children(self): # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) # icon_content @@ -95,11 +97,11 @@ def icon_content(self, value: Optional[Control]): # selected_icon @property - def selected_icon(self): + def selected_icon(self) -> Optional[str]: return self._get_attr("selectedIcon") @selected_icon.setter - def selected_icon(self, value): + def selected_icon(self, value: Optional[str]): self._set_attr("selectedIcon", value) # selected_icon_content @@ -113,13 +115,22 @@ def selected_icon_content(self, value: Optional[Control]): # label @property - def label(self): + def label(self) -> Optional[str]: return self._get_attr("label") @label.setter - def label(self, value): + def label(self, value: Optional[str]): self._set_attr("label", value) + # bgcolor + @property + def bgcolor(self) -> Optional[str]: + return self._get_attr("bgcolor") + + @bgcolor.setter + def bgcolor(self, value: Optional[str]): + self._set_attr("bgcolor", value) + class NavigationBar(ConstrainedControl, AdaptiveControl): """ From df240ad09b97d6fdb22b5dca25e25acce9660e13 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:37:11 +0100 Subject: [PATCH 086/103] NavigationBar: overlay_color --- .../flet/lib/src/controls/navigation_bar.dart | 4 ++++ .../flet-core/src/flet_core/navigation_bar.py | 19 +++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/packages/flet/lib/src/controls/navigation_bar.dart b/packages/flet/lib/src/controls/navigation_bar.dart index 3dc5c5010..28dbfd6b5 100644 --- a/packages/flet/lib/src/controls/navigation_bar.dart +++ b/packages/flet/lib/src/controls/navigation_bar.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; +import '../utils/colors.dart'; import '../utils/icons.dart'; import 'create_control.dart'; import 'cupertino_navigation_bar.dart'; @@ -88,6 +89,8 @@ class _NavigationBarControlState extends State shadowColor: widget.control.attrColor("shadowColor", context), surfaceTintColor: widget.control.attrColor("surfaceTintColor", context), + overlayColor: parseMaterialStateColor( + Theme.of(context), widget.control, "overlayColor"), indicatorColor: widget.control.attrColor("indicatorColor", context), indicatorShape: parseOutlinedBorder(widget.control, "indicatorShape"), @@ -107,6 +110,7 @@ class _NavigationBarControlState extends State .where((c) => c.name == "selected_icon_content"); return NavigationDestination( + enabled: !disabled || !destView.control.isDisabled, tooltip: destView.control.attrString("tooltip", "")!, icon: iconContentCtrls.isNotEmpty ? createControl( diff --git a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py index 2f2b443d5..fe943482a 100644 --- a/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/navigation_bar.py @@ -1,5 +1,5 @@ from enum import Enum -from typing import Any, List, Optional, Union +from typing import Any, List, Optional, Union, Dict from flet_core.adaptive_control import AdaptiveControl from flet_core.border import Border @@ -13,6 +13,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + MaterialState, ) try: @@ -51,8 +52,10 @@ def __init__( # ref: Optional[Ref] = None, tooltip: Optional[str] = None, + disabled: Optional[bool] = None, + data: Any = None, ): - Control.__init__(self, ref=ref, tooltip=tooltip) + Control.__init__(self, ref=ref, tooltip=tooltip, disabled=disabled, data=data) self.label = label self.icon = icon self.__icon_content: Optional[Control] = None @@ -180,6 +183,7 @@ def __init__( surface_tint_color: Optional[str] = None, border: Optional[Border] = None, animation_duration: Optional[int] = None, + overlay_color: Union[None, str, Dict[MaterialState, str]] = None, on_change=None, # # ConstrainedControl and AdaptiveControl @@ -254,6 +258,7 @@ def __init__( self.border = border self.on_change = on_change self.animation_duration = animation_duration + self.overlay_color = overlay_color def _get_control_name(self): return "navigationbar" @@ -262,6 +267,7 @@ def before_update(self): super().before_update() self._set_attr_json("indicatorShape", self.__indicator_shape) self._set_attr_json("border", self.__border) + self._set_attr_json("overlayColor", self.__overlay_color) def _get_children(self): children = [] @@ -299,6 +305,15 @@ def label_behavior(self, value: Optional[NavigationBarLabelBehavior]): value.value if isinstance(value, NavigationBarLabelBehavior) else value, ) + # overlay_color + @property + def overlay_color(self) -> Union[None, str, Dict[MaterialState, str]]: + return self.__overlay_color + + @overlay_color.setter + def overlay_color(self, value: Union[None, str, Dict[MaterialState, str]]): + self.__overlay_color = value + # bgcolor @property def bgcolor(self): From e5cc38cbec74558fac6f00ce3310b72bcd2207fe Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:39:03 +0100 Subject: [PATCH 087/103] CupertinoTimerPicker: item_extent --- .../flet/lib/src/controls/cupertino_timer_picker.dart | 1 + .../flet-core/src/flet_core/cupertino_timer_picker.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/packages/flet/lib/src/controls/cupertino_timer_picker.dart b/packages/flet/lib/src/controls/cupertino_timer_picker.dart index f1055e646..4b2464c17 100644 --- a/packages/flet/lib/src/controls/cupertino_timer_picker.dart +++ b/packages/flet/lib/src/controls/cupertino_timer_picker.dart @@ -49,6 +49,7 @@ class _CupertinoTimerPickerControlState initialTimerDuration: initialTimerDuration, minuteInterval: minuteInterval, secondInterval: secondInterval, + itemExtent: widget.control.attrDouble("itemExtent", 32.0)!, alignment: parseAlignment(widget.control, "alignment") ?? Alignment.center, backgroundColor: backgroundColor, diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py index efb2ae411..f027a4831 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_timer_picker.py @@ -37,6 +37,7 @@ def __init__( minute_interval: OptionalNumber = None, mode: Optional[CupertinoTimerPickerMode] = None, bgcolor: Optional[str] = None, + item_extent: OptionalNumber = None, on_change=None, # # ConstrainedControl @@ -106,6 +107,7 @@ def __init__( self.on_change = on_change self.second_interval = second_interval self.minute_interval = minute_interval + self.item_extent = item_extent def _get_control_name(self): return "cupertinotimerpicker" @@ -137,6 +139,15 @@ def second_interval(self) -> OptionalNumber: def second_interval(self, value: OptionalNumber): self._set_attr("secondInterval", value) + # item_extent + @property + def item_extent(self) -> OptionalNumber: + return self._get_attr("itemExtent", data_type="float", def_value=32.0) + + @item_extent.setter + def item_extent(self, value: OptionalNumber): + self._set_attr("itemExtent", value) + # minute_interval @property def minute_interval(self) -> OptionalNumber: From 1de76d6869e94c9c468337b69a546ab462cb476c Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 15:48:01 +0100 Subject: [PATCH 088/103] ExpansionTile: dense, enable_feedback, visual_density --- .../flet/lib/src/controls/expansion_tile.dart | 5 ++ .../flet-core/src/flet_core/expansion_tile.py | 75 ++++++++++++++----- 2 files changed, 62 insertions(+), 18 deletions(-) diff --git a/packages/flet/lib/src/controls/expansion_tile.dart b/packages/flet/lib/src/controls/expansion_tile.dart index 3ff5b555f..a51077fde 100644 --- a/packages/flet/lib/src/controls/expansion_tile.dart +++ b/packages/flet/lib/src/controls/expansion_tile.dart @@ -5,6 +5,7 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; import '../utils/edge_insets.dart'; +import '../utils/theme.dart'; import 'create_control.dart'; import 'error.dart'; @@ -103,6 +104,10 @@ class ExpansionTileControl extends StatelessWidget { shape: parseOutlinedBorder(control, "shape"), collapsedShape: parseOutlinedBorder(control, "collapsedShape"), onExpansionChanged: onChange, + visualDensity: + parseVisualDensity(control.attrString("visualDensity"), null), + enableFeedback: control.attrBool("enableFeedback"), + dense: control.attrBool("dense"), leading: leadingCtrls.isNotEmpty ? createControl(control, leadingCtrls.first.id, disabled, parentAdaptive: adaptive) diff --git a/sdk/python/packages/flet-core/src/flet_core/expansion_tile.py b/sdk/python/packages/flet-core/src/flet_core/expansion_tile.py index 923feed0c..e21e6214b 100644 --- a/sdk/python/packages/flet-core/src/flet_core/expansion_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/expansion_tile.py @@ -1,11 +1,13 @@ from enum import Enum from typing import Any, List, Optional, Union -from flet_core import Alignment, OutlinedBorder from flet_core.adaptive_control import AdaptiveControl +from flet_core.alignment import Alignment +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, ClipBehavior, @@ -56,6 +58,9 @@ def __init__( collapsed_icon_color: Optional[str] = None, collapsed_text_color: Optional[str] = None, collapsed_shape: Optional[OutlinedBorder] = None, + dense: Optional[bool] = None, + enable_feedback: Optional[bool] = None, + visual_density: Optional[ThemeVisualDensity] = None, on_change=None, # # ConstrainedControl @@ -88,7 +93,7 @@ def __init__( disabled: Optional[bool] = None, data: Any = None, # - # Adaptive + # AdaptiveControl # adaptive: Optional[bool] = None, ): @@ -147,6 +152,9 @@ def __init__( self.collapsed_text_color = collapsed_text_color self.collapsed_shape = collapsed_shape self.on_change = on_change + self.dense = dense + self.enable_feedback = enable_feedback + self.visual_density = visual_density def _get_control_name(self): return "expansiontile" @@ -217,11 +225,11 @@ def expanded_alignment(self, value: Optional[Alignment]): # expanded_cross_axis_alignment @property - def expanded_cross_axis_alignment(self) -> CrossAxisAlignment: + def expanded_cross_axis_alignment(self) -> Optional[CrossAxisAlignment]: return self.__expanded_cross_axis_alignment @expanded_cross_axis_alignment.setter - def expanded_cross_axis_alignment(self, value: CrossAxisAlignment): + def expanded_cross_axis_alignment(self, value: Optional[CrossAxisAlignment]): self.__expanded_cross_axis_alignment = value self._set_attr( "crossAxisAlignment", @@ -230,11 +238,11 @@ def expanded_cross_axis_alignment(self, value: CrossAxisAlignment): # affinity @property - def affinity(self) -> TileAffinity: + def affinity(self) -> Optional[TileAffinity]: return self.__affinity @affinity.setter - def affinity(self, value: TileAffinity): + def affinity(self, value: Optional[TileAffinity]): self.__affinity = value self._set_attr( "affinity", @@ -277,6 +285,24 @@ def trailing(self) -> Optional[Control]: def trailing(self, value: Optional[Control]): self.__trailing = value + # dense + @property + def dense(self) -> Optional[bool]: + return self._get_attr("dense", data_type="bool") + + @dense.setter + def dense(self, value: Optional[bool]): + self._set_attr("dense", value) + + # enable_feedback + @property + def enable_feedback(self) -> Optional[bool]: + return self._get_attr("enableFeedback", data_type="bool", def_value=True) + + @enable_feedback.setter + def enable_feedback(self, value: Optional[bool]): + self._set_attr("enableFeedback", value) + # clip_behavior @property def clip_behavior(self) -> Optional[ClipBehavior]: @@ -289,6 +315,19 @@ def clip_behavior(self, value: Optional[ClipBehavior]): "clipBehavior", value.value if isinstance(value, ClipBehavior) else value ) + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + # maintain_state @property def maintain_state(self) -> Optional[bool]: @@ -318,56 +357,56 @@ def shape(self, value: Optional[OutlinedBorder]): # text_color @property - def text_color(self): + def text_color(self) -> Optional[str]: return self._get_attr("textColor") @text_color.setter - def text_color(self, value): + def text_color(self, value: Optional[str]): self._set_attr("textColor", value) # icon_color @property - def icon_color(self): + def icon_color(self) -> Optional[str]: return self._get_attr("iconColor") @icon_color.setter - def icon_color(self, value): + def icon_color(self, value: Optional[str]): self._set_attr("iconColor", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgColor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgColor", value) # collapsed_bgcolor @property - def collapsed_bgcolor(self): + def collapsed_bgcolor(self) -> Optional[str]: return self._get_attr("collapsedBgColor") @collapsed_bgcolor.setter - def collapsed_bgcolor(self, value): + def collapsed_bgcolor(self, value: Optional[str]): self._set_attr("collapsedBgColor", value) # collapsed_icon_color @property - def collapsed_icon_color(self): + def collapsed_icon_color(self) -> Optional[str]: return self._get_attr("collapsedIconColor") @collapsed_icon_color.setter - def collapsed_icon_color(self, value): + def collapsed_icon_color(self, value: Optional[str]): self._set_attr("collapsedIconColor", value) # collapsed_text_color @property - def collapsed_text_color(self): + def collapsed_text_color(self) -> Optional[str]: return self._get_attr("collapsedTextColor") @collapsed_text_color.setter - def collapsed_text_color(self, value): + def collapsed_text_color(self, value: Optional[str]): self._set_attr("collapsedTextColor", value) # collapsed_shape From a1f6ac3a54685730fae7590ef72c8b90b532b9dc Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:00:32 +0100 Subject: [PATCH 089/103] SearchBar: keyboard_type, view_surface_tint_color, autofocus --- .../flet/lib/src/controls/search_anchor.dart | 17 ++++++ .../flet-core/src/flet_core/search_bar.py | 57 +++++++++++++++---- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/packages/flet/lib/src/controls/search_anchor.dart b/packages/flet/lib/src/controls/search_anchor.dart index 6c254f9c5..9f6eaeaf8 100644 --- a/packages/flet/lib/src/controls/search_anchor.dart +++ b/packages/flet/lib/src/controls/search_anchor.dart @@ -1,11 +1,13 @@ import 'dart:convert'; +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/colors.dart'; +import '../utils/form_field.dart'; import '../utils/text.dart'; import 'create_control.dart'; @@ -96,6 +98,14 @@ class _SearchAnchorControlState extends State { TextStyle? viewHintTextStyle = parseTextStyle(Theme.of(context), widget.control, "viewHintTextStyle"); + var textCapitalization = TextCapitalization.values.firstWhereOrNull( + (c) => + c.name.toLowerCase() == + widget.control.attrString("capitalization", "")!, + ); + TextInputType keyboardType = + parseTextInputType(widget.control.attrString("keyboardType", "")!); + var method = widget.control.attrString("method"); if (method != null) { @@ -166,9 +176,16 @@ class _SearchAnchorControlState extends State { .triggerControlEvent(widget.control.id, "change", value); } : null, + viewSurfaceTintColor: + widget.control.attrColor("viewSurfaceTintColor", context), + textCapitalization: textCapitalization, + keyboardType: keyboardType, builder: (BuildContext context, SearchController controller) { return SearchBar( controller: controller, + keyboardType: keyboardType, + textCapitalization: textCapitalization, + autoFocus: widget.control.attrBool("autoFocus", false)!, hintText: widget.control.attrString("barHintText"), backgroundColor: parseMaterialStateColor( Theme.of(context), widget.control, "barBgcolor"), diff --git a/sdk/python/packages/flet-core/src/flet_core/search_bar.py b/sdk/python/packages/flet-core/src/flet_core/search_bar.py index ba1dce5c0..84c76a997 100644 --- a/sdk/python/packages/flet-core/src/flet_core/search_bar.py +++ b/sdk/python/packages/flet-core/src/flet_core/search_bar.py @@ -7,7 +7,7 @@ from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref from flet_core.text_style import TextStyle -from flet_core.textfield import TextCapitalization +from flet_core.textfield import TextCapitalization, KeyboardType from flet_core.types import ( AnimationValue, MaterialState, @@ -47,8 +47,11 @@ def __init__( view_header_text_style: Optional[TextStyle] = None, view_hint_text_style: Optional[TextStyle] = None, divider_color: Optional[str] = None, + capitalization: Optional[TextCapitalization] = None, full_screen: Optional[bool] = None, - capitalization: TextCapitalization = TextCapitalization.NONE, + keyboard_type: Optional[KeyboardType] = None, + view_surface_tint_color: Optional[str] = None, + autofocus: Optional[bool] = None, on_tap=None, on_submit=None, on_change=None, @@ -128,6 +131,9 @@ def __init__( self.on_tap = on_tap self.on_submit = on_submit self.on_change = on_change + self.keyboard_type = keyboard_type + self.view_surface_tint_color = view_surface_tint_color + self.autofocus = autofocus def _get_control_name(self): return "searchbar" @@ -246,6 +252,24 @@ def view_leading(self) -> Optional[Control]: def view_leading(self, value: Optional[Control]): self.__view_leading = value + # view_surface_tint_color + @property + def view_surface_tint_color(self) -> Optional[str]: + return self._get_attr("viewSurfaceTintColor") + + @view_surface_tint_color.setter + def view_surface_tint_color(self, value: Optional[str]): + self._set_attr("viewSurfaceTintColor", value) + + # autofocus + @property + def autofocus(self) -> Optional[bool]: + return self._get_attr("autofocus", data_type="bool", def_value=False) + + @autofocus.setter + def autofocus(self, value: Optional[bool]): + self._set_attr("autofocus", value) + # view_trailing @property def view_trailing(self) -> Optional[List[Control]]: @@ -266,38 +290,38 @@ def view_elevation(self, value: OptionalNumber): # view_bgcolor @property - def view_bgcolor(self): + def view_bgcolor(self) -> Optional[str]: return self._get_attr("viewBgcolor") @view_bgcolor.setter - def view_bgcolor(self, value): + def view_bgcolor(self, value: Optional[str]): self._set_attr("viewBgcolor", value) # divider_color @property - def divider_color(self): + def divider_color(self) -> Optional[str]: return self._get_attr("dividerColor") @divider_color.setter - def divider_color(self, value): + def divider_color(self, value: Optional[str]): self._set_attr("dividerColor", value) # bar_hint_text @property - def bar_hint_text(self): + def bar_hint_text(self) -> Optional[str]: return self._get_attr("barHintText") @bar_hint_text.setter - def bar_hint_text(self, value): + def bar_hint_text(self, value: Optional[str]): self._set_attr("barHintText", value) # view_hint_text @property - def view_hint_text(self): + def view_hint_text(self) -> Optional[str]: return self._get_attr("viewHintText") @view_hint_text.setter - def view_hint_text(self, value): + def view_hint_text(self, value: Optional[str]): self._set_attr("viewHintText", value) # view_shape @@ -340,6 +364,19 @@ def capitalization(self, value: TextCapitalization): value.value if isinstance(value, TextCapitalization) else value, ) + # keyboard_type + @property + def keyboard_type(self) -> KeyboardType: + return self.__keyboard_type + + @keyboard_type.setter + def keyboard_type(self, value: KeyboardType): + self.__keyboard_type = value + self._set_attr( + "keyboardType", + value.value if isinstance(value, KeyboardType) else value, + ) + # view_header_text_style @property def view_header_text_style(self): From 3b4cb65da7eabf65a52ec67004a3c5fbb334b07d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:22:08 +0100 Subject: [PATCH 090/103] NavigationRail: (un)selected_label_text_style | Destination: indicator_color, indicator_shape --- .../lib/src/controls/navigation_rail.dart | 10 +++ .../src/flet_core/navigation_rail.py | 76 ++++++++++++++++--- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/packages/flet/lib/src/controls/navigation_rail.dart b/packages/flet/lib/src/controls/navigation_rail.dart index 5d588222b..28ec65d40 100644 --- a/packages/flet/lib/src/controls/navigation_rail.dart +++ b/packages/flet/lib/src/controls/navigation_rail.dart @@ -5,6 +5,7 @@ import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; +import '../utils/text.dart'; import 'create_control.dart'; import 'error.dart'; import 'flet_store_mixin.dart'; @@ -90,6 +91,10 @@ class _NavigationRailControlState extends State labelType: extended ? NavigationRailLabelType.none : labelType, extended: extended, elevation: widget.control.attrDouble("elevation", 0), + selectedLabelTextStyle: parseTextStyle( + Theme.of(context), widget.control, "selectedLabelTextStyle"), + unselectedLabelTextStyle: parseTextStyle(Theme.of(context), + widget.control, "unselectedLabelTextStyle"), indicatorShape: parseOutlinedBorder(widget.control, "indicatorShape"), minWidth: widget.control.attrDouble("minWidth"), @@ -125,7 +130,12 @@ class _NavigationRailControlState extends State .where((c) => c.name == "selected_icon_content"); return NavigationRailDestination( + disabled: disabled || destView.control.isDisabled, padding: parseEdgeInsets(destView.control, "padding"), + indicatorColor: + destView.control.attrColor("indicatorColor", context), + indicatorShape: + parseOutlinedBorder(destView.control, "indicatorShape"), icon: iconContentCtrls.isNotEmpty ? createControl(destView.control, iconContentCtrls.first.id, disabled, diff --git a/sdk/python/packages/flet-core/src/flet_core/navigation_rail.py b/sdk/python/packages/flet-core/src/flet_core/navigation_rail.py index 71bd3041b..0894f36c1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/navigation_rail.py +++ b/sdk/python/packages/flet-core/src/flet_core/navigation_rail.py @@ -1,10 +1,11 @@ from enum import Enum from typing import Any, List, Optional, Union -from flet_core import OutlinedBorder +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber from flet_core.ref import Ref +from flet_core.text_style import TextStyle from flet_core.types import ( AnimationValue, OffsetValue, @@ -38,12 +39,16 @@ def __init__( label: Optional[str] = None, label_content: Optional[Control] = None, padding: PaddingValue = None, + indicator_color: Optional[str] = None, + indicator_shape: Optional[OutlinedBorder] = None, # # Control # ref: Optional[Ref] = None, + disabled: Optional[bool] = None, + data: Any = None, ): - Control.__init__(self, ref=ref) + Control.__init__(self, ref=ref, disabled=disabled, data=data) self.label = label self.icon = icon self.__icon_content: Optional[Control] = None @@ -54,6 +59,8 @@ def __init__( self.__label_content: Optional[Control] = None self.label_content = label_content self.padding = padding + self.indicator_color = indicator_color + self.indicator_shape = indicator_shape def _get_control_name(self): return "navigationraildestination" @@ -61,6 +68,8 @@ def _get_control_name(self): def before_update(self): super().before_update() self._set_attr_json("padding", self.__padding) + if isinstance(self.__indicator_shape, OutlinedBorder): + self._set_attr_json("indicatorShape", self.__indicator_shape) def _get_children(self): children = [] @@ -79,13 +88,31 @@ def _get_children(self): # icon @property - def icon(self): + def icon(self) -> Optional[str]: return self._get_attr("icon") @icon.setter - def icon(self, value): + def icon(self, value: Optional[str]): self._set_attr("icon", value) + # indicator_color + @property + def indicator_color(self) -> Optional[str]: + return self._get_attr("indicatorColor") + + @indicator_color.setter + def indicator_color(self, value: Optional[str]): + self._set_attr("indicatorColor", value) + + # indicator_shape + @property + def indicator_shape(self) -> Optional[OutlinedBorder]: + return self.__indicator_shape + + @indicator_shape.setter + def indicator_shape(self, value: Optional[OutlinedBorder]): + self.__indicator_shape = value + # icon_content @property def icon_content(self) -> Optional[Control]: @@ -212,6 +239,8 @@ def __init__( min_width: OptionalNumber = None, min_extended_width: OptionalNumber = None, group_alignment: OptionalNumber = None, + selected_label_text_style: Optional[TextStyle] = None, + unselected_label_text_style: Optional[TextStyle] = None, on_change=None, # # ConstrainedControl @@ -287,13 +316,24 @@ def __init__( self.min_extended_width = min_extended_width self.group_alignment = group_alignment self.on_change = on_change + self.selected_label_text_style = selected_label_text_style + self.unselected_label_text_style = unselected_label_text_style def _get_control_name(self): return "navigationrail" def before_update(self): super().before_update() - self._set_attr_json("indicatorShape", self.__indicator_shape) + if isinstance(self.__indicator_shape, OutlinedBorder): + self._set_attr_json("indicatorShape", self.__indicator_shape) + if isinstance(self.__selected_label_text_style, TextStyle): + self._set_attr_json( + "selectedLabelTextStyle", self.__selected_label_text_style + ) + if isinstance(self.__unselected_label_text_style, TextStyle): + self._set_attr_json( + "unselectedLabelTextStyle", self.__unselected_label_text_style + ) def _get_children(self): children = [] @@ -357,20 +397,20 @@ def indicator_shape(self, value: Optional[OutlinedBorder]): # indicator_color @property - def indicator_color(self): + def indicator_color(self) -> Optional[str]: return self._get_attr("indicatorColor") @indicator_color.setter - def indicator_color(self, value): + def indicator_color(self, value: Optional[str]): self._set_attr("indicatorColor", value) # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter - def bgcolor(self, value): + def bgcolor(self, value: Optional[str]): self._set_attr("bgcolor", value) # elevation @@ -409,6 +449,24 @@ def trailing(self) -> Optional[Control]: def trailing(self, value: Optional[Control]): self.__trailing = value + # selected_label_text_style + @property + def selected_label_text_style(self) -> Optional[TextStyle]: + return self.__selected_label_text_style + + @selected_label_text_style.setter + def selected_label_text_style(self, value: Optional[TextStyle]): + self.__selected_label_text_style = value + + # unselected_label_text_style + @property + def unselected_label_text_style(self) -> Optional[TextStyle]: + return self.__unselected_label_text_style + + @unselected_label_text_style.setter + def unselected_label_text_style(self, value: Optional[TextStyle]): + self.__unselected_label_text_style = value + # min_width @property def min_width(self) -> OptionalNumber: From 5008f82b5eabc81229e21a3b0d59228f4b693c38 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:29:16 +0100 Subject: [PATCH 091/103] IconButton: mouse_cursor, visual_density --- .../flet/lib/src/controls/icon_button.dart | 10 ++++++ .../flet-core/src/flet_core/icon_button.py | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/packages/flet/lib/src/controls/icon_button.dart b/packages/flet/lib/src/controls/icon_button.dart index 81131f6c0..9ee79f3b0 100644 --- a/packages/flet/lib/src/controls/icon_button.dart +++ b/packages/flet/lib/src/controls/icon_button.dart @@ -7,6 +7,8 @@ import '../utils/buttons.dart'; import '../utils/edge_insets.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; +import '../utils/mouse.dart'; +import '../utils/theme.dart'; import 'create_control.dart'; import 'cupertino_button.dart'; import 'error.dart'; @@ -100,6 +102,10 @@ class _IconButtonControlState extends State String url = widget.control.attrString("url", "")!; String? urlTarget = widget.control.attrString("urlTarget"); bool disabled = widget.control.isDisabled || widget.parentDisabled; + var mouseCursor = + parseMouseCursor(widget.control.attrString("mouseCursor"), null); + var visualDensity = + parseVisualDensity(widget.control.attrString("visualDensity"), null); Function()? onPressed = disabled ? null @@ -146,6 +152,8 @@ class _IconButtonControlState extends State color: iconColor, ), iconSize: iconSize, + mouseCursor: mouseCursor, + visualDensity: visualDensity, tooltip: tooltip, style: style, isSelected: selected, @@ -168,6 +176,8 @@ class _IconButtonControlState extends State splashRadius: splashRadius, onPressed: onPressed, iconSize: iconSize, + mouseCursor: mouseCursor, + visualDensity: visualDensity, style: style, tooltip: tooltip, isSelected: selected, diff --git a/sdk/python/packages/flet-core/src/flet_core/icon_button.py b/sdk/python/packages/flet-core/src/flet_core/icon_button.py index 4a63f611d..fe08b0419 100644 --- a/sdk/python/packages/flet-core/src/flet_core/icon_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/icon_button.py @@ -6,7 +6,9 @@ from flet_core.buttons import ButtonStyle from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, OffsetValue, @@ -81,6 +83,8 @@ def __init__( enable_feedback: Optional[bool] = None, url: Optional[str] = None, url_target: Optional[UrlTarget] = None, + mouse_cursor: Optional[MouseCursor] = None, + visual_density: Optional[ThemeVisualDensity] = None, on_click=None, on_focus=None, on_blur=None, @@ -172,6 +176,8 @@ def __init__( self.on_click = on_click self.on_focus = on_focus self.on_blur = on_blur + self.mouse_cursor = mouse_cursor + self.visual_density = visual_density def _get_control_name(self): return "iconbutton" @@ -369,6 +375,31 @@ def url_target(self, value: Optional[UrlTarget]): "urlTarget", value.value if isinstance(value, UrlTarget) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + # on_click @property def on_click(self): From b646785e9c0ff7ca50d0ab16cab9f4800dcabc80 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:32:05 +0100 Subject: [PATCH 092/103] Radio: mouse_cursor --- packages/flet/lib/src/controls/radio.dart | 3 +++ .../packages/flet-core/src/flet_core/radio.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/flet/lib/src/controls/radio.dart b/packages/flet/lib/src/controls/radio.dart index 9cbad84f1..68ea41610 100644 --- a/packages/flet/lib/src/controls/radio.dart +++ b/packages/flet/lib/src/controls/radio.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/colors.dart'; +import '../utils/mouse.dart'; import '../utils/text.dart'; import 'create_control.dart'; import 'cupertino_radio.dart'; @@ -111,6 +112,8 @@ class _RadioControlState extends State with FletStoreMixin { autofocus: autofocus, focusNode: _focusNode, groupValue: groupValue, + mouseCursor: parseMouseCursor( + widget.control.attrString("mouseCursor"), null), value: value, activeColor: widget.control.attrColor("activeColor", context), focusColor: widget.control.attrColor("focusColor", context), diff --git a/sdk/python/packages/flet-core/src/flet_core/radio.py b/sdk/python/packages/flet-core/src/flet_core/radio.py index 5e59260ba..030c3b37d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/radio.py +++ b/sdk/python/packages/flet-core/src/flet_core/radio.py @@ -3,6 +3,7 @@ from flet_core.adaptive_control import AdaptiveControl from flet_core.constrained_control import ConstrainedControl from flet_core.control import OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.text_style import TextStyle from flet_core.theme import ThemeVisualDensity @@ -67,6 +68,7 @@ def __init__( splash_radius: OptionalNumber = None, toggleable: Optional[bool] = None, visual_density: Optional[ThemeVisualDensity] = None, + mouse_cursor: Optional[MouseCursor] = None, on_focus=None, on_blur=None, # @@ -149,6 +151,7 @@ def __init__( self.splash_radius = splash_radius self.toggleable = toggleable self.visual_density = visual_density + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "radio" @@ -239,6 +242,18 @@ def label_position(self, value: LabelPosition): "labelPosition", value.value if isinstance(value, LabelPosition) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + # label_style @property def label_style(self) -> Optional[TextStyle]: From efd37fd73c4c91271301113c6faaeaf7bd966fcc Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:33:45 +0100 Subject: [PATCH 093/103] FAB: mouse_cursor --- .../lib/src/controls/floating_action_button.dart | 5 +++++ .../src/flet_core/floating_action_button.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/flet/lib/src/controls/floating_action_button.dart b/packages/flet/lib/src/controls/floating_action_button.dart index f46970eab..9b35d8406 100644 --- a/packages/flet/lib/src/controls/floating_action_button.dart +++ b/packages/flet/lib/src/controls/floating_action_button.dart @@ -5,6 +5,7 @@ import '../models/control.dart'; import '../utils/borders.dart'; import '../utils/icons.dart'; import '../utils/launch_url.dart'; +import '../utils/mouse.dart'; import 'create_control.dart'; import 'error.dart'; @@ -77,6 +78,7 @@ class FloatingActionButtonControl extends StatelessWidget { heroTag: control.id, autofocus: autofocus, onPressed: onPressed, + mouseCursor: parseMouseCursor(control.attrString("mouseCursor")), backgroundColor: bgColor, foregroundColor: foregroundColor, hoverColor: hoverColor, @@ -99,6 +101,7 @@ class FloatingActionButtonControl extends StatelessWidget { heroTag: control.id, autofocus: autofocus, onPressed: onPressed, + mouseCursor: parseMouseCursor(control.attrString("mouseCursor")), backgroundColor: bgColor, foregroundColor: foregroundColor, hoverColor: hoverColor, @@ -120,6 +123,7 @@ class FloatingActionButtonControl extends StatelessWidget { heroTag: control.id, autofocus: autofocus, onPressed: onPressed, + mouseCursor: parseMouseCursor(control.attrString("mouseCursor")), backgroundColor: bgColor, foregroundColor: foregroundColor, hoverColor: hoverColor, @@ -142,6 +146,7 @@ class FloatingActionButtonControl extends StatelessWidget { heroTag: control.id, autofocus: autofocus, onPressed: onPressed, + mouseCursor: parseMouseCursor(control.attrString("mouseCursor")), label: Text(text), icon: Icon(icon), backgroundColor: bgColor, diff --git a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py index 344603b27..f7c1ecb6c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/floating_action_button.py @@ -3,6 +3,7 @@ from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref from flet_core.types import ( AnimationValue, @@ -84,6 +85,7 @@ def __init__( enable_feedback: Optional[bool] = None, url: Optional[str] = None, url_target: Optional[UrlTarget] = None, + mouse_cursor: Optional[MouseCursor] = None, on_click=None, # # ConstrainedControl @@ -166,6 +168,7 @@ def __init__( self.highlight_elevation = highlight_elevation self.hover_elevation = hover_elevation self.enable_feedback = enable_feedback + self.mouse_cursor = mouse_cursor def _get_control_name(self): return "floatingactionbutton" @@ -228,6 +231,18 @@ def url_target(self, value: Optional[UrlTarget]): "urlTarget", value.value if isinstance(value, UrlTarget) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + # on_click @property def on_click(self): From 1ae31ba06017b1a60746cfd68502216ebce4bc8d Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 16:51:37 +0100 Subject: [PATCH 094/103] DataTable: clip_behavior --- packages/flet/lib/src/controls/datatable.dart | 5 +++++ .../packages/flet-core/src/flet_core/datatable.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/flet/lib/src/controls/datatable.dart b/packages/flet/lib/src/controls/datatable.dart index 98127e08d..74967450f 100644 --- a/packages/flet/lib/src/controls/datatable.dart +++ b/packages/flet/lib/src/controls/datatable.dart @@ -72,9 +72,14 @@ class _DataTableControlState extends State verticalInside: verticalLines ?? BorderSide.none); } + Clip clipBehavior = Clip.values.firstWhere( + (c) => c.toString() == widget.control.attrString("clipBehavior", "")!, + orElse: () => Clip.none); + return DataTable( decoration: decoration, border: tableBorder, + clipBehavior: clipBehavior, checkboxHorizontalMargin: widget.control.attrDouble("checkboxHorizontalMargin"), columnSpacing: widget.control.attrDouble("columnSpacing"), diff --git a/sdk/python/packages/flet-core/src/flet_core/datatable.py b/sdk/python/packages/flet-core/src/flet_core/datatable.py index 0bbafc950..095015f57 100644 --- a/sdk/python/packages/flet-core/src/flet_core/datatable.py +++ b/sdk/python/packages/flet-core/src/flet_core/datatable.py @@ -18,6 +18,7 @@ ResponsiveNumber, RotateValue, ScaleValue, + ClipBehavior, ) @@ -325,6 +326,7 @@ def __init__( heading_row_height: OptionalNumber = None, heading_text_style: Optional[TextStyle] = None, horizontal_margin: OptionalNumber = None, + clip_behavior: Optional[ClipBehavior] = None, on_select_all=None, # # ConstrainedControl @@ -412,6 +414,7 @@ def __init__( self.sort_ascending = sort_ascending self.sort_column_index = sort_column_index self.on_select_all = on_select_all + self.clip_behavior = clip_behavior def _get_control_name(self): return "datatable" @@ -641,6 +644,18 @@ def sort_column_index(self) -> Optional[int]: def sort_column_index(self, value: Optional[int]): self._set_attr("sortColumnIndex", value) + # clip_behavior + @property + def clip_behavior(self) -> Optional[ClipBehavior]: + return self.__clip_behavior + + @clip_behavior.setter + def clip_behavior(self, value: Optional[ClipBehavior]): + self.__clip_behavior = value + self._set_attr( + "clipBehavior", value.value if isinstance(value, ClipBehavior) else value + ) + # on_select_all @property def on_select_all(self): From e3106489df65292ed15b495a608de429e23079f6 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 21:04:45 +0100 Subject: [PATCH 095/103] DatePicker: on_entry_mode_change --- .../flet/lib/src/controls/date_picker.dart | 20 ++----- .../flet-core/src/flet_core/date_picker.py | 53 ++++++++++++++++--- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/packages/flet/lib/src/controls/date_picker.dart b/packages/flet/lib/src/controls/date_picker.dart index 27417c6f1..d93f889fc 100644 --- a/packages/flet/lib/src/controls/date_picker.dart +++ b/packages/flet/lib/src/controls/date_picker.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/form_field.dart'; import '../utils/icons.dart'; -import 'form_field.dart'; class DatePickerControl extends StatefulWidget { final Control? parent; @@ -34,7 +34,6 @@ class _DatePickerControlState extends State { DateTime? firstDate = widget.control.attrDateTime("firstDate"); DateTime? lastDate = widget.control.attrDateTime("lastDate"); DateTime? currentDate = widget.control.attrDateTime("currentDate"); - //String? localeString = widget.control.attrString("locale"); String? helpText = widget.control.attrString("helpText"); String? cancelText = widget.control.attrString("cancelText"); String? confirmText = widget.control.attrString("confirmText"); @@ -62,13 +61,6 @@ class _DatePickerControlState extends State { IconData? switchToInputEntryModeIcon = parseIcon(widget.control.attrString("switchToInputEntryModeIcon", "")!); - //Locale locale; - // if (localeString == null) { - // locale = Localizations.localeOf(context); - // } else { - // //locale = Locale(localeString); - // } - void onClosed(DateTime? dateValue) { String stringValue; String eventName; @@ -103,6 +95,10 @@ class _DatePickerControlState extends State { initialEntryMode: datePickerEntryMode, fieldHintText: fieldHintText, fieldLabelText: fieldLabelText, + onDatePickerModeChange: (DatePickerEntryMode mode) { + widget.backend.triggerControlEvent( + widget.control.id, "entryModeChange", mode.name); + }, switchToCalendarEntryModeIcon: switchToCalendarEntryModeIcon != null ? Icon(switchToCalendarEntryModeIcon) : null, @@ -111,12 +107,6 @@ class _DatePickerControlState extends State { : null, ); - // dialog = Localizations.override( - // context: context, - // locale: locale, - // child: dialog, - // ); - return dialog; } diff --git a/sdk/python/packages/flet-core/src/flet_core/date_picker.py b/sdk/python/packages/flet-core/src/flet_core/date_picker.py index 9a39a0439..108c99dc4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/date_picker.py @@ -1,8 +1,11 @@ +import json from datetime import date, datetime from enum import Enum from typing import Any, Optional, Union +from flet_core import ControlEvent from flet_core.control import Control, OptionalNumber +from flet_core.event_handler import EventHandler from flet_core.ref import Ref from flet_core.textfield import KeyboardType from flet_core.types import ResponsiveNumber @@ -26,6 +29,11 @@ class DatePickerEntryMode(Enum): INPUT_ONLY = "inputOnly" +class DatePickerEntryModeChangeEvent(ControlEvent): + def __init__(self, mode) -> None: + self.mode: Optional[DatePickerEntryMode] = DatePickerEntryMode(mode) + + class DatePicker(Control): """ A Material-style date picker dialog. @@ -118,12 +126,22 @@ def __init__( disabled=disabled, data=data, ) + + def convert_entry_mode_event_data(e): + d = json.loads(e.data) + self.__result = DatePickerEntryModeChangeEvent(**d) + return self.__result + + self.__on_entry_mode_change = EventHandler(convert_entry_mode_event_data) + self._add_event_handler( + "entryModeChange", self.__on_entry_mode_change.get_handler() + ) + self.value = value self.first_date = first_date self.last_date = last_date self.current_date = current_date self.keyboard_type = keyboard_type - # self.locale = locale self.help_text = help_text self.cancel_text = cancel_text self.confirm_text = confirm_text @@ -182,7 +200,9 @@ def value(self, value: Optional[Union[datetime, str]]): @property def first_date(self) -> Optional[datetime]: value_string = self._get_attr("firstDate", def_value=None) - return datetime.fromisoformat(value_string) if value_string is not None else None + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) @first_date.setter def first_date(self, value: Optional[Union[datetime, str]]): @@ -194,7 +214,9 @@ def first_date(self, value: Optional[Union[datetime, str]]): @property def last_date(self) -> Optional[datetime]: value_string = self._get_attr("lastDate", def_value=None) - return datetime.fromisoformat(value_string) if value_string is not None else None + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) @last_date.setter def last_date(self, value: Optional[Union[datetime, str]]): @@ -206,7 +228,9 @@ def last_date(self, value: Optional[Union[datetime, str]]): @property def current_date(self) -> Optional[datetime]: value_string = self._get_attr("currentDate", def_value=None) - return datetime.fromisoformat(value_string) if value_string is not None else None + return ( + datetime.fromisoformat(value_string) if value_string is not None else None + ) @current_date.setter def current_date(self, value: Optional[Union[datetime, str]]): @@ -285,7 +309,9 @@ def keyboard_type(self) -> Optional[KeyboardType]: @keyboard_type.setter def keyboard_type(self, value: Optional[KeyboardType]): self.__keyboard_type = value - self._set_attr("keyboardType", value.value if isinstance(value, KeyboardType) else value) + self._set_attr( + "keyboardType", value.value if isinstance(value, KeyboardType) else value + ) # date_picker_mode @property @@ -295,7 +321,10 @@ def date_picker_mode(self) -> Optional[DatePickerMode]: @date_picker_mode.setter def date_picker_mode(self, value: Optional[DatePickerMode]): self.__date_picker_mode = value - self._set_attr("datePickerMode", value.value if isinstance(value, DatePickerMode) else value) + self._set_attr( + "datePickerMode", + value.value if isinstance(value, DatePickerMode) else value, + ) # date_picker_entry_mode @property @@ -306,7 +335,8 @@ def date_picker_entry_mode(self) -> Optional[DatePickerEntryMode]: def date_picker_entry_mode(self, value: Optional[DatePickerEntryMode]): self.__date_picker_entry_mode = value self._set_attr( - "datePickerEntryMode", value.value if isinstance(value, DatePickerEntryMode) else value + "datePickerEntryMode", + value.value if isinstance(value, DatePickerEntryMode) else value, ) # switch_to_calendar_icon @@ -344,3 +374,12 @@ def on_dismiss(self): @on_dismiss.setter def on_dismiss(self, handler): self._add_event_handler("dismiss", handler) + + # on_entry_mode_change + @property + def on_entry_mode_change(self): + return self.__on_entry_mode_change + + @on_entry_mode_change.setter + def on_entry_mode_change(self, handler): + self.__on_entry_mode_change.subscribe(handler) From 0052708f60d3531a049496d2abcfda1770d8307a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 21:31:03 +0100 Subject: [PATCH 096/103] ListTile: title_alignment, icon_color, text_color, shape, visual_density, mouse_cursor, title_text_style, subtitle_text_style, leading_and_trailing_text_style --- packages/flet/lib/src/controls/list_tile.dart | 29 +++ .../flet-core/src/flet_core/list_tile.py | 172 ++++++++++++++++-- 2 files changed, 187 insertions(+), 14 deletions(-) diff --git a/packages/flet/lib/src/controls/list_tile.dart b/packages/flet/lib/src/controls/list_tile.dart index 128c34bec..046a6cfbd 100644 --- a/packages/flet/lib/src/controls/list_tile.dart +++ b/packages/flet/lib/src/controls/list_tile.dart @@ -1,9 +1,14 @@ +import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; import '../utils/edge_insets.dart'; import '../utils/launch_url.dart'; +import '../utils/mouse.dart'; +import '../utils/text.dart'; +import '../utils/theme.dart'; import 'create_control.dart'; import 'cupertino_list_tile.dart'; import 'flet_store_mixin.dart'; @@ -68,6 +73,13 @@ class ListTileControl extends StatelessWidget with FletStoreMixin { var trailingCtrls = children.where((c) => c.name == "trailing" && c.isVisible); + var titleAlignment = ListTileTitleAlignment.values.firstWhereOrNull((e) => + e.name.toLowerCase() == + control.attrString("titleAlignment", "")!.toLowerCase()); + var style = ListTileStyle.values.firstWhereOrNull((e) => + e.name.toLowerCase() == + control.attrString("style", "")!.toLowerCase()); + bool selected = control.attrBool("selected", false)!; bool dense = control.attrBool("dense", false)!; bool isThreeLine = control.attrBool("isThreeLine", false)!; @@ -125,6 +137,23 @@ class ListTileControl extends StatelessWidget with FletStoreMixin { tileColor: control.attrColor("bgcolor", context), splashColor: control.attrColor("bgcolorActivated", context), hoverColor: control.attrColor("hoverColor", context), + iconColor: control.attrColor("iconColor", context), + textColor: control.attrColor("textColor", context), + mouseCursor: parseMouseCursor(control.attrString("mouseCursor")), + visualDensity: + parseVisualDensity(control.attrString("visualDensity"), null), + shape: parseOutlinedBorder(control, "shape"), + titleTextStyle: + parseTextStyle(Theme.of(context), control, "titleTextStyle"), + leadingAndTrailingTextStyle: parseTextStyle( + Theme.of(context), control, "leadingAndTrailingTextStyle"), + subtitleTextStyle: + parseTextStyle(Theme.of(context), control, "subtitleTextStyle"), + titleAlignment: titleAlignment, + style: style, + onFocusChange: (bool hasFocus) { + backend.triggerControlEvent(control.id, hasFocus ? "focus" : "blur"); + }, leading: leadingCtrls.isNotEmpty ? createControl(control, leadingCtrls.first.id, disabled, parentAdaptive: adaptive) diff --git a/sdk/python/packages/flet-core/src/flet_core/list_tile.py b/sdk/python/packages/flet-core/src/flet_core/list_tile.py index 04c1b3a4c..0dce3a937 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_tile.py @@ -1,6 +1,7 @@ from enum import Enum from typing import Any, Optional, Union +from flet_core import MouseCursor, TextStyle, ThemeVisualDensity, OutlinedBorder from flet_core.adaptive_control import AdaptiveControl from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber @@ -16,6 +17,14 @@ ) +class ListTileTitleAlignment(Enum): + TOP = "top" + CENTER = "center" + BOTTOM = "bottom" + THREE_LINE = "threeLine" + TITLE_HEIGHT = "titleHeight" + + class ListTileStyle(Enum): LIST = "list" DRAWER = "drawer" @@ -86,6 +95,15 @@ def __init__( min_vertical_padding: OptionalNumber = None, url: Optional[str] = None, url_target: Optional[UrlTarget] = None, + title_alignment: Optional[ListTileTitleAlignment] = None, + icon_color: Optional[str] = None, + text_color: Optional[str] = None, + shape: Optional[OutlinedBorder] = None, + visual_density: Optional[ThemeVisualDensity] = None, + mouse_cursor: Optional[MouseCursor] = None, + title_text_style: Optional[TextStyle] = None, + subtitle_text_style: Optional[TextStyle] = None, + leading_and_trailing_text_style: Optional[TextStyle] = None, on_click=None, on_long_press=None, # @@ -177,6 +195,15 @@ def __init__( self.horizontal_spacing = horizontal_spacing self.min_leading_width = min_leading_width self.min_vertical_padding = min_vertical_padding + self.title_alignment = title_alignment + self.icon_color = icon_color + self.text_color = text_color + self.shape = shape + self.visual_density = visual_density + self.mouse_cursor = mouse_cursor + self.title_text_style = title_text_style + self.subtitle_text_style = subtitle_text_style + self.leading_and_trailing_text_style = leading_and_trailing_text_style def _get_control_name(self): return "listtile" @@ -184,6 +211,16 @@ def _get_control_name(self): def before_update(self): super().before_update() self._set_attr_json("contentPadding", self.__content_padding) + if isinstance(self.__shape, OutlinedBorder): + self._set_attr_json("shape", self.__shape) + if isinstance(self.__title_text_style, TextStyle): + self._set_attr_json("titleTextStyle", self.__title_text_style) + if isinstance(self.__subtitle_text_style, TextStyle): + self._set_attr_json("subtitleTextStyle", self.__subtitle_text_style) + if isinstance(self.__leading_and_trailing_text_style, TextStyle): + self._set_attr_json( + "leadingAndTrailingTextStyle", self.__leading_and_trailing_text_style + ) def _get_children(self): children = [] @@ -212,7 +249,7 @@ def content_padding(self, value: PaddingValue): # bgcolor @property - def bgcolor(self): + def bgcolor(self) -> Optional[str]: return self._get_attr("bgcolor") @bgcolor.setter @@ -221,7 +258,7 @@ def bgcolor(self, value: Optional[str]): # selected_color @property - def selected_color(self): + def selected_color(self) -> Optional[str]: return self._get_attr("selectedColor") @selected_color.setter @@ -230,7 +267,7 @@ def selected_color(self, value: Optional[str]): # selected_tile_color @property - def selected_tile_color(self): + def selected_tile_color(self) -> Optional[str]: return self._get_attr("selectedTileColor") @selected_tile_color.setter @@ -239,7 +276,7 @@ def selected_tile_color(self, value: Optional[str]): # bgcolor_activated @property - def bgcolor_activated(self): + def bgcolor_activated(self) -> Optional[str]: return self._get_attr("bgcolorActivated") @bgcolor_activated.setter @@ -248,7 +285,7 @@ def bgcolor_activated(self, value: Optional[str]): # min_leading_width @property - def min_leading_width(self): + def min_leading_width(self) -> OptionalNumber: return self._get_attr("minLeadingWidth", data_type="float", def_value=40) @min_leading_width.setter @@ -257,7 +294,7 @@ def min_leading_width(self, value: OptionalNumber): # horizontal_spacing @property - def horizontal_spacing(self): + def horizontal_spacing(self) -> OptionalNumber: return self._get_attr("horizontalSpacing", data_type="float", def_value=16) @horizontal_spacing.setter @@ -266,11 +303,11 @@ def horizontal_spacing(self, value: OptionalNumber): # hover_color @property - def hover_color(self): + def hover_color(self) -> Optional[str]: return self._get_attr("hoverColor") @hover_color.setter - def hover_color(self, value): + def hover_color(self, value: Optional[str]): self._set_attr("hoverColor", value) # leading @@ -348,6 +385,19 @@ def style(self, value: Optional[ListTileStyle]): "style", value.value if isinstance(value, ListTileStyle) else value ) + # title_alignment + @property + def title_alignment(self) -> Optional[ListTileTitleAlignment]: + return self.__title_alignment + + @title_alignment.setter + def title_alignment(self, value: Optional[ListTileTitleAlignment]): + self.__title_alignment = value + self._set_attr( + "titleAlignment", + value.value if isinstance(value, ListTileTitleAlignment) else value, + ) + # selected @property def selected(self) -> Optional[bool]: @@ -386,13 +436,31 @@ def toggle_inputs(self, value: Optional[bool]): # url @property - def url(self): + def url(self) -> Optional[str]: return self._get_attr("url") @url.setter - def url(self, value): + def url(self, value: Optional[str]): self._set_attr("url", value) + # icon_color + @property + def icon_color(self) -> Optional[str]: + return self._get_attr("iconColor") + + @icon_color.setter + def icon_color(self, value: Optional[str]): + self._set_attr("iconColor", value) + + # text_color + @property + def text_color(self) -> Optional[str]: + return self._get_attr("textColor") + + @text_color.setter + def text_color(self, value: Optional[str]): + self._set_attr("textColor", value) + # url_target @property def url_target(self) -> Optional[UrlTarget]: @@ -405,6 +473,67 @@ def url_target(self, value: Optional[UrlTarget]): "urlTarget", value.value if isinstance(value, UrlTarget) else value ) + # mouse_cursor + @property + def mouse_cursor(self) -> Optional[MouseCursor]: + return self.__mouse_cursor + + @mouse_cursor.setter + def mouse_cursor(self, value: Optional[MouseCursor]): + self.__mouse_cursor = value + self._set_attr( + "mouseCursor", value.value if isinstance(value, MouseCursor) else value + ) + + # visual_density + @property + def visual_density(self) -> Optional[ThemeVisualDensity]: + return self.__visual_density + + @visual_density.setter + def visual_density(self, value: Optional[ThemeVisualDensity]): + self.__visual_density = value + self._set_attr( + "visualDensity", + value.value if isinstance(value, ThemeVisualDensity) else value, + ) + + # shape + @property + def shape(self) -> Optional[OutlinedBorder]: + return self.__shape + + @shape.setter + def shape(self, value: Optional[OutlinedBorder]): + self.__shape = value + + # title_text_style + @property + def title_text_style(self) -> Optional[TextStyle]: + return self.__title_text_style + + @title_text_style.setter + def title_text_style(self, value: Optional[TextStyle]): + self.__title_text_style = value + + # subtitle_text_style + @property + def subtitle_text_style(self) -> Optional[TextStyle]: + return self.__subtitle_text_style + + @subtitle_text_style.setter + def subtitle_text_style(self, value: Optional[TextStyle]): + self.__subtitle_text_style = value + + # leading_and_trailing_text_style + @property + def leading_and_trailing_text_style(self) -> Optional[TextStyle]: + return self.__leading_and_trailing_text_style + + @leading_and_trailing_text_style.setter + def leading_and_trailing_text_style(self, value: Optional[TextStyle]): + self.__leading_and_trailing_text_style = value + # on_click @property def on_click(self): @@ -413,10 +542,7 @@ def on_click(self): @on_click.setter def on_click(self, handler): self._add_event_handler("click", handler) - if handler is not None: - self._set_attr("onclick", True) - else: - self._set_attr("onclick", None) + self._set_attr("onclick", True if handler is not None else None) # on_long_press @property @@ -427,3 +553,21 @@ def on_long_press(self): def on_long_press(self, handler): self._add_event_handler("long_press", handler) self._set_attr("onLongPress", 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) From 862810f3c70bf8b233b2f1f02fd2132e9b4d92a8 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 21:43:00 +0100 Subject: [PATCH 097/103] TimePicker: on_entry_mode_change --- .../flet/lib/src/controls/time_picker.dart | 4 ++ .../flet-core/src/flet_core/date_picker.py | 2 + .../flet-core/src/flet_core/time_picker.py | 46 +++++++++++++++---- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/packages/flet/lib/src/controls/time_picker.dart b/packages/flet/lib/src/controls/time_picker.dart index b3a88e176..0d27284d4 100644 --- a/packages/flet/lib/src/controls/time_picker.dart +++ b/packages/flet/lib/src/controls/time_picker.dart @@ -82,6 +82,10 @@ class _TimePickerControlState extends State { errorInvalidText: errorInvalidText, initialEntryMode: timePickerEntryMode, orientation: orientation, + onEntryModeChanged: (TimePickerEntryMode mode) { + widget.backend.triggerControlEvent( + widget.control.id, "entryModeChange", mode.name); + }, ); return dialog; diff --git a/sdk/python/packages/flet-core/src/flet_core/date_picker.py b/sdk/python/packages/flet-core/src/flet_core/date_picker.py index 108c99dc4..bcb6f18ea 100644 --- a/sdk/python/packages/flet-core/src/flet_core/date_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/date_picker.py @@ -101,6 +101,7 @@ def __init__( switch_to_input_icon: Optional[str] = None, on_change=None, on_dismiss=None, + on_entry_mode_change=None, # # ConstrainedControl # @@ -156,6 +157,7 @@ def convert_entry_mode_event_data(e): self.on_change = on_change self.on_dismiss = on_dismiss self.open = open + self.on_entry_mode_change = on_entry_mode_change def _get_control_name(self): return "datepicker" diff --git a/sdk/python/packages/flet-core/src/flet_core/time_picker.py b/sdk/python/packages/flet-core/src/flet_core/time_picker.py index 03a3b8c2e..14b78ec16 100644 --- a/sdk/python/packages/flet-core/src/flet_core/time_picker.py +++ b/sdk/python/packages/flet-core/src/flet_core/time_picker.py @@ -1,8 +1,11 @@ +import json from datetime import time from enum import Enum from typing import Any, Optional, Union +from flet_core import ControlEvent from flet_core.control import Control, OptionalNumber +from flet_core.event_handler import EventHandler from flet_core.ref import Ref from flet_core.types import Orientation, ResponsiveNumber from flet_core.utils import deprecated @@ -15,16 +18,21 @@ class TimePickerEntryMode(Enum): INPUT_ONLY = "inputOnly" +class TimePickerEntryModeChangeEvent(ControlEvent): + def __init__(self, mode) -> None: + self.mode: Optional[TimePickerEntryMode] = TimePickerEntryMode(mode) + + class TimePicker(Control): """ - A Material-style time picker dialog. + A Material-style time picker dialog. - It is added to [`page.overlay`](page#overlay) and called using its `pick_time()` method. + It is added to [`page.overlay`](page#overlay) and called using its `pick_time()` method. - Depending on the `time_picker_entry_mode`, it will show either a Dial or an Input (hour and minute text fields) for picking a time. + Depending on the `time_picker_entry_mode`, it will show either a Dial or an Input (hour and minute text fields) for picking a time. - Example: - ``` + Example: + ``` import datetime import flet as ft @@ -55,11 +63,11 @@ def dismissed(e): ft.app(target=main) - ``` + ``` - ----- + ----- - Online docs: https://flet.dev/docs/controls/time_picker + Online docs: https://flet.dev/docs/controls/time_picker """ def __init__( @@ -76,6 +84,7 @@ def __init__( orientation: Optional[Orientation] = None, on_change=None, on_dismiss=None, + on_entry_mode_change=None, # # Control # @@ -101,6 +110,17 @@ def __init__( disabled=disabled, data=data, ) + + def convert_entry_mode_event_data(e): + d = json.loads(e.data) + self.__result = TimePickerEntryModeChangeEvent(**d) + return self.__result + + self.__on_entry_mode_change = EventHandler(convert_entry_mode_event_data) + self._add_event_handler( + "entryModeChange", self.__on_entry_mode_change.get_handler() + ) + self.value = value self.help_text = help_text self.cancel_text = cancel_text @@ -113,6 +133,7 @@ def __init__( self.on_change = on_change self.on_dismiss = on_dismiss self.open = open + self.on_entry_mode_change = on_entry_mode_change def _get_control_name(self): return "timepicker" @@ -252,3 +273,12 @@ def on_dismiss(self): @on_dismiss.setter def on_dismiss(self, handler): self._add_event_handler("dismiss", handler) + + # on_entry_mode_change + @property + def on_entry_mode_change(self): + return self.__on_entry_mode_change + + @on_entry_mode_change.setter + def on_entry_mode_change(self, handler): + self.__on_entry_mode_change.subscribe(handler) From dceaa26d4a485755c5041e0db035ae2747916796 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 21:43:30 +0100 Subject: [PATCH 098/103] Cleanup --- .../flet/lib/src/controls/cupertino_textfield.dart | 2 +- packages/flet/lib/src/controls/dropdown.dart | 2 +- packages/flet/lib/src/controls/piechart.dart | 2 -- packages/flet/lib/src/controls/progress_bar.dart | 2 +- packages/flet/lib/src/controls/textfield.dart | 2 +- .../flet/lib/src/{controls => utils}/form_field.dart | 10 +++++----- 6 files changed, 9 insertions(+), 11 deletions(-) rename packages/flet/lib/src/{controls => utils}/form_field.dart (97%) diff --git a/packages/flet/lib/src/controls/cupertino_textfield.dart b/packages/flet/lib/src/controls/cupertino_textfield.dart index c4c5277b4..cd80d598f 100644 --- a/packages/flet/lib/src/controls/cupertino_textfield.dart +++ b/packages/flet/lib/src/controls/cupertino_textfield.dart @@ -6,12 +6,12 @@ import 'package:flutter/services.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; +import '../utils/form_field.dart'; import '../utils/gradient.dart'; import '../utils/shadows.dart'; import '../utils/text.dart'; import '../utils/textfield.dart'; import 'create_control.dart'; -import 'form_field.dart'; import 'textfield.dart'; class CupertinoTextFieldControl extends StatefulWidget { diff --git a/packages/flet/lib/src/controls/dropdown.dart b/packages/flet/lib/src/controls/dropdown.dart index fb1100c2b..9ebbdce2e 100644 --- a/packages/flet/lib/src/controls/dropdown.dart +++ b/packages/flet/lib/src/controls/dropdown.dart @@ -5,10 +5,10 @@ import '../models/control.dart'; import '../utils/alignment.dart'; import '../utils/borders.dart'; import '../utils/edge_insets.dart'; +import '../utils/form_field.dart'; import '../utils/text.dart'; import 'create_control.dart'; import 'flet_store_mixin.dart'; -import 'form_field.dart'; class DropdownControl extends StatefulWidget { final Control? parent; diff --git a/packages/flet/lib/src/controls/piechart.dart b/packages/flet/lib/src/controls/piechart.dart index 819309746..853e0afb4 100644 --- a/packages/flet/lib/src/controls/piechart.dart +++ b/packages/flet/lib/src/controls/piechart.dart @@ -18,8 +18,6 @@ import 'create_control.dart'; class PieChartEventData extends Equatable { final String eventType; final int? sectionIndex; - // final double? angle; - // final double? radius; const PieChartEventData( {required this.eventType, required this.sectionIndex}); diff --git a/packages/flet/lib/src/controls/progress_bar.dart b/packages/flet/lib/src/controls/progress_bar.dart index c6661857e..bb3ec3154 100644 --- a/packages/flet/lib/src/controls/progress_bar.dart +++ b/packages/flet/lib/src/controls/progress_bar.dart @@ -1,7 +1,7 @@ -import 'package:flet/src/utils/borders.dart'; import 'package:flutter/material.dart'; import '../models/control.dart'; +import '../utils/borders.dart'; import 'create_control.dart'; class ProgressBarControl extends StatelessWidget { diff --git a/packages/flet/lib/src/controls/textfield.dart b/packages/flet/lib/src/controls/textfield.dart index 86f469a7a..8039258ba 100644 --- a/packages/flet/lib/src/controls/textfield.dart +++ b/packages/flet/lib/src/controls/textfield.dart @@ -4,12 +4,12 @@ import 'package:flutter/services.dart'; import '../flet_control_backend.dart'; import '../models/control.dart'; import '../utils/borders.dart'; +import '../utils/form_field.dart'; import '../utils/text.dart'; import '../utils/textfield.dart'; import 'create_control.dart'; import 'cupertino_textfield.dart'; import 'flet_store_mixin.dart'; -import 'form_field.dart'; class TextFieldControl extends StatefulWidget { final Control? parent; diff --git a/packages/flet/lib/src/controls/form_field.dart b/packages/flet/lib/src/utils/form_field.dart similarity index 97% rename from packages/flet/lib/src/controls/form_field.dart rename to packages/flet/lib/src/utils/form_field.dart index 86933a120..31a2f7d52 100644 --- a/packages/flet/lib/src/controls/form_field.dart +++ b/packages/flet/lib/src/utils/form_field.dart @@ -1,12 +1,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../controls/create_control.dart'; import '../models/control.dart'; -import '../utils/borders.dart'; -import '../utils/edge_insets.dart'; -import '../utils/icons.dart'; -import '../utils/text.dart'; -import 'create_control.dart'; +import 'borders.dart'; +import 'edge_insets.dart'; +import 'icons.dart'; +import 'text.dart'; enum FormFieldInputBorder { outline, underline, none } From 5a2882b57983e9fea9e87907d61d2fb0f4c02f12 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Thu, 28 Mar 2024 21:56:24 +0100 Subject: [PATCH 099/103] Fix failing CI concerning circular import --- sdk/python/packages/flet-core/src/flet_core/list_tile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/list_tile.py b/sdk/python/packages/flet-core/src/flet_core/list_tile.py index 0dce3a937..0461fa5c4 100644 --- a/sdk/python/packages/flet-core/src/flet_core/list_tile.py +++ b/sdk/python/packages/flet-core/src/flet_core/list_tile.py @@ -1,11 +1,14 @@ from enum import Enum from typing import Any, Optional, Union -from flet_core import MouseCursor, TextStyle, ThemeVisualDensity, OutlinedBorder from flet_core.adaptive_control import AdaptiveControl +from flet_core.buttons import OutlinedBorder from flet_core.constrained_control import ConstrainedControl from flet_core.control import Control, OptionalNumber +from flet_core.gesture_detector import MouseCursor from flet_core.ref import Ref +from flet_core.text_style import TextStyle +from flet_core.theme import ThemeVisualDensity from flet_core.types import ( AnimationValue, OffsetValue, From f216bfc3b90297e19bdc21491925ff252bd3ed29 Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 1 Apr 2024 02:06:39 +0200 Subject: [PATCH 100/103] Cleanup --- sdk/python/packages/flet-core/src/flet_core/alert_dialog.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/types.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py index eb38c6006..31235ec6c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py +++ b/sdk/python/packages/flet-core/src/flet_core/alert_dialog.py @@ -75,7 +75,7 @@ def __init__( title_padding: PaddingValue = None, content_padding: PaddingValue = None, actions_padding: PaddingValue = None, - actions_alignment: MainAxisAlignment = None, + actions_alignment: Optional[MainAxisAlignment] = None, shape: Optional[OutlinedBorder] = None, inset_padding: PaddingValue = None, icon_padding: PaddingValue = None, @@ -350,11 +350,11 @@ def actions_padding(self, value: PaddingValue): # actions_alignment @property - def actions_alignment(self) -> MainAxisAlignment: + def actions_alignment(self) -> Optional[MainAxisAlignment]: return self.__actions_alignment @actions_alignment.setter - def actions_alignment(self, value: MainAxisAlignment): + def actions_alignment(self, value: Optional[MainAxisAlignment]): self.__actions_alignment = value self._set_attr( "actionsAlignment", diff --git a/sdk/python/packages/flet-core/src/flet_core/types.py b/sdk/python/packages/flet-core/src/flet_core/types.py index a0b61b92d..101854174 100644 --- a/sdk/python/packages/flet-core/src/flet_core/types.py +++ b/sdk/python/packages/flet-core/src/flet_core/types.py @@ -34,6 +34,9 @@ class WebRenderer(Enum): class UrlTarget(Enum): BLANK = "blank" SELF = "_self" + PARENT = "_parent" + TOP = "_top" + UNFENCED_TOP = "_unfencedTop" PaddingValue = Union[None, int, float, Padding] @@ -91,7 +94,6 @@ class MaterialState(Enum): class MainAxisAlignment(Enum): - NONE = None START = "start" END = "end" CENTER = "center" From 83432db9f50927406446589e47bd1cfffda8a72a Mon Sep 17 00:00:00 2001 From: ndonkoHenri Date: Mon, 1 Apr 2024 02:35:52 +0200 Subject: [PATCH 101/103] Remove None from enums --- .../packages/flet-core/src/flet_core/canvas/color.py | 6 +++--- .../packages/flet-core/src/flet_core/canvas/text.py | 2 +- .../flet-core/src/flet_core/charts/bar_chart_rod.py | 6 +++--- .../src/flet_core/charts/line_chart_data_point.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/checkbox.py | 2 +- sdk/python/packages/flet-core/src/flet_core/column.py | 4 ++-- sdk/python/packages/flet-core/src/flet_core/container.py | 6 +++--- .../flet-core/src/flet_core/cupertino_checkbox.py | 6 +++--- .../packages/flet-core/src/flet_core/cupertino_radio.py | 6 +++--- .../flet-core/src/flet_core/cupertino_textfield.py | 8 ++++---- sdk/python/packages/flet-core/src/flet_core/image.py | 6 +++--- .../packages/flet-core/src/flet_core/popup_menu_button.py | 2 +- .../flet-core/src/flet_core/pubsub/pubsub_client.py | 2 -- sdk/python/packages/flet-core/src/flet_core/radio.py | 6 +++--- .../packages/flet-core/src/flet_core/responsive_row.py | 4 ++-- sdk/python/packages/flet-core/src/flet_core/row.py | 4 ++-- .../packages/flet-core/src/flet_core/shader_mask.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/switch.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/text.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/textfield.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/tooltip.py | 6 +++--- sdk/python/packages/flet-core/src/flet_core/types.py | 5 ----- sdk/python/packages/flet-core/src/flet_core/view.py | 4 ++-- sdk/python/packages/flet-core/tests/test_text.py | 3 +-- sdk/python/packages/flet-core/tests/test_tooltip.py | 3 +-- 25 files changed, 56 insertions(+), 65 deletions(-) diff --git a/sdk/python/packages/flet-core/src/flet_core/canvas/color.py b/sdk/python/packages/flet-core/src/flet_core/canvas/color.py index 230fb39c0..98c179328 100644 --- a/sdk/python/packages/flet-core/src/flet_core/canvas/color.py +++ b/sdk/python/packages/flet-core/src/flet_core/canvas/color.py @@ -8,7 +8,7 @@ class Color(Shape): def __init__( self, color: Optional[str] = None, - blend_mode: BlendMode = BlendMode.NONE, + blend_mode: Optional[BlendMode] = None, # # Control # @@ -39,11 +39,11 @@ def color(self, value: Optional[str]): # blend_mode @property - def blend_mode(self) -> BlendMode: + def blend_mode(self) -> Optional[BlendMode]: return self.__blend_mode @blend_mode.setter - def blend_mode(self, value: BlendMode): + def blend_mode(self, value: Optional[BlendMode]): self.__blend_mode = value self._set_attr( "blendMode", value.value if isinstance(value, BlendMode) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/canvas/text.py b/sdk/python/packages/flet-core/src/flet_core/canvas/text.py index 1ed06b6d1..990fda12c 100644 --- a/sdk/python/packages/flet-core/src/flet_core/canvas/text.py +++ b/sdk/python/packages/flet-core/src/flet_core/canvas/text.py @@ -17,7 +17,7 @@ def __init__( style: Optional[TextStyle] = None, spans: Optional[List[InlineSpan]] = None, alignment: Optional[Alignment] = None, - text_align: TextAlign = TextAlign.NONE, + text_align: Optional[TextAlign] = None, max_lines: Optional[int] = None, max_width: OptionalNumber = None, ellipsis: Optional[str] = None, diff --git a/sdk/python/packages/flet-core/src/flet_core/charts/bar_chart_rod.py b/sdk/python/packages/flet-core/src/flet_core/charts/bar_chart_rod.py index a4e47056e..80de5f5e5 100644 --- a/sdk/python/packages/flet-core/src/flet_core/charts/bar_chart_rod.py +++ b/sdk/python/packages/flet-core/src/flet_core/charts/bar_chart_rod.py @@ -28,7 +28,7 @@ def __init__( show_tooltip: Optional[bool] = None, tooltip: Optional[str] = None, tooltip_style: Optional[TextStyle] = None, - tooltip_align: TextAlign = TextAlign.NONE, + tooltip_align: Optional[TextAlign] = None, # # Control # @@ -214,11 +214,11 @@ def tooltip(self, value: Optional[str]): # tooltip_align @property - def tooltip_align(self) -> TextAlign: + def tooltip_align(self) -> Optional[TextAlign]: return self.__tooltip_align @tooltip_align.setter - def tooltip_align(self, value: TextAlign): + def tooltip_align(self, value: Optional[TextAlign]): self.__tooltip_align = value self._set_attr( "tooltipAlign", value.value if isinstance(value, TextAlign) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/charts/line_chart_data_point.py b/sdk/python/packages/flet-core/src/flet_core/charts/line_chart_data_point.py index 491dc5b0e..45c32eb97 100644 --- a/sdk/python/packages/flet-core/src/flet_core/charts/line_chart_data_point.py +++ b/sdk/python/packages/flet-core/src/flet_core/charts/line_chart_data_point.py @@ -17,7 +17,7 @@ def __init__( show_tooltip: Optional[bool] = None, tooltip: Optional[str] = None, tooltip_style: Optional[TextStyle] = None, - tooltip_align: TextAlign = TextAlign.NONE, + tooltip_align: Optional[TextAlign] = None, point: Union[None, bool, ChartPointShape] = None, selected_point: Union[None, bool, ChartPointShape] = None, show_above_line: Optional[bool] = None, @@ -114,11 +114,11 @@ def tooltip(self, value: Optional[str]): # tooltip_align @property - def tooltip_align(self) -> TextAlign: + def tooltip_align(self) -> Optional[TextAlign]: return self.__tooltip_align @tooltip_align.setter - def tooltip_align(self, value: TextAlign): + def tooltip_align(self, value: Optional[TextAlign]): self.__tooltip_align = value self._set_attr( "tooltipAlign", value.value if isinstance(value, TextAlign) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/checkbox.py b/sdk/python/packages/flet-core/src/flet_core/checkbox.py index 43a04bd83..715c01967 100644 --- a/sdk/python/packages/flet-core/src/flet_core/checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/checkbox.py @@ -58,7 +58,7 @@ def __init__( self, label: Optional[str] = None, value: Optional[bool] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, label_style: Optional[TextStyle] = None, tristate: Optional[bool] = None, autofocus: Optional[bool] = None, diff --git a/sdk/python/packages/flet-core/src/flet_core/column.py b/sdk/python/packages/flet-core/src/flet_core/column.py index 15fe89f5c..eaf4d6816 100644 --- a/sdk/python/packages/flet-core/src/flet_core/column.py +++ b/sdk/python/packages/flet-core/src/flet_core/column.py @@ -57,8 +57,8 @@ def main(page: ft.Page): def __init__( self, controls: Optional[List[Control]] = None, - alignment: MainAxisAlignment = MainAxisAlignment.NONE, - horizontal_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, + alignment: Optional[MainAxisAlignment] = None, + horizontal_alignment: Optional[CrossAxisAlignment] = None, spacing: OptionalNumber = None, tight: Optional[bool] = None, wrap: Optional[bool] = None, diff --git a/sdk/python/packages/flet-core/src/flet_core/container.py b/sdk/python/packages/flet-core/src/flet_core/container.py index b724601ab..4f5d78417 100644 --- a/sdk/python/packages/flet-core/src/flet_core/container.py +++ b/sdk/python/packages/flet-core/src/flet_core/container.py @@ -67,7 +67,7 @@ def __init__( alignment: Optional[Alignment] = None, bgcolor: Optional[str] = None, gradient: Optional[Gradient] = None, - blend_mode: BlendMode = BlendMode.NONE, + blend_mode: Optional[BlendMode] = None, border: Optional[Border] = None, border_radius: BorderRadiusValue = None, image_src: Optional[str] = None, @@ -269,11 +269,11 @@ def gradient(self, value: Optional[Gradient]): # blend_mode @property - def blend_mode(self) -> BlendMode: + def blend_mode(self) -> Optional[BlendMode]: return self.__blend_mode @blend_mode.setter - def blend_mode(self, value: BlendMode): + def blend_mode(self, value: Optional[BlendMode]): self.__blend_mode = value self._set_attr( "blendMode", value.value if isinstance(value, BlendMode) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_checkbox.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_checkbox.py index 43cd9e1e0..d5e0584e0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_checkbox.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_checkbox.py @@ -40,7 +40,7 @@ def main(page): def __init__( self, label: Optional[str] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, value: Optional[bool] = None, tristate: Optional[bool] = None, autofocus: Optional[bool] = None, @@ -159,11 +159,11 @@ def label(self, value): # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py index 75e78f1ed..16aeabd48 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_radio.py @@ -31,7 +31,7 @@ def __init__( self, label: Optional[str] = None, value: Optional[str] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, fill_color: Optional[str] = None, active_color: Optional[str] = None, inactive_color: Optional[str] = None, @@ -141,11 +141,11 @@ def label(self, value: Optional[str]): # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/cupertino_textfield.py b/sdk/python/packages/flet-core/src/flet_core/cupertino_textfield.py index c6455f3d9..6022690cf 100644 --- a/sdk/python/packages/flet-core/src/flet_core/cupertino_textfield.py +++ b/sdk/python/packages/flet-core/src/flet_core/cupertino_textfield.py @@ -43,7 +43,7 @@ def __init__( value: Optional[str] = None, placeholder_style: Optional[TextStyle] = None, gradient: Optional[Gradient] = None, - blend_mode: BlendMode = BlendMode.NONE, + blend_mode: Optional[BlendMode] = None, shadow: Union[None, BoxShadow, List[BoxShadow]] = None, prefix_visibility_mode: Optional[VisibilityMode] = None, suffix_visibility_mode: Optional[VisibilityMode] = None, @@ -61,7 +61,7 @@ def __init__( can_reveal_password: Optional[bool] = None, read_only: Optional[bool] = None, shift_enter: Optional[bool] = None, - text_align: TextAlign = TextAlign.NONE, + text_align: Optional[TextAlign] = None, autofocus: Optional[bool] = None, capitalization: TextCapitalization = TextCapitalization.NONE, autocorrect: Optional[bool] = None, @@ -249,11 +249,11 @@ def gradient(self, value: Optional[Gradient]): # blend_mode @property - def blend_mode(self) -> BlendMode: + def blend_mode(self) -> Optional[BlendMode]: return self.__blend_mode @blend_mode.setter - def blend_mode(self, value: BlendMode): + def blend_mode(self, value: Optional[BlendMode]): self.__blend_mode = value self._set_attr( "blendMode", value.value if isinstance(value, BlendMode) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/image.py b/sdk/python/packages/flet-core/src/flet_core/image.py index 31c9aea93..ceff7fc9f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/image.py +++ b/sdk/python/packages/flet-core/src/flet_core/image.py @@ -59,7 +59,7 @@ def __init__( fit: Optional[ImageFit] = None, border_radius: BorderRadiusValue = None, color: Optional[str] = None, - color_blend_mode: BlendMode = BlendMode.NONE, + color_blend_mode: Optional[BlendMode] = None, gapless_playback: Optional[bool] = None, semantics_label: Optional[str] = None, exclude_from_semantics: Optional[bool] = None, @@ -225,11 +225,11 @@ def color(self, value): # color_blend_mode @property - def color_blend_mode(self) -> BlendMode: + def color_blend_mode(self) -> Optional[BlendMode]: return self.__blend_mode @color_blend_mode.setter - def color_blend_mode(self, value: BlendMode): + def color_blend_mode(self, value: Optional[BlendMode]): self.__blend_mode = value self._set_attr( "colorBlendMode", value.value if isinstance(value, BlendMode) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py index 3d45bb41c..36afa4208 100644 --- a/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py +++ b/sdk/python/packages/flet-core/src/flet_core/popup_menu_button.py @@ -382,7 +382,7 @@ def icon_size(self, value: OptionalNumber): # enable_feedback @property def enable_feedback(self) -> Optional[bool]: - return self._get_attr("enableFeedback", data_type="bool", def_val=True) + return self._get_attr("enableFeedback", data_type="bool", def_value=True) @enable_feedback.setter def enable_feedback(self, value: Optional[bool]): diff --git a/sdk/python/packages/flet-core/src/flet_core/pubsub/pubsub_client.py b/sdk/python/packages/flet-core/src/flet_core/pubsub/pubsub_client.py index 6529e9910..f79a33a3f 100644 --- a/sdk/python/packages/flet-core/src/flet_core/pubsub/pubsub_client.py +++ b/sdk/python/packages/flet-core/src/flet_core/pubsub/pubsub_client.py @@ -2,9 +2,7 @@ from typing import Any, Callable import flet_core -from flet_core.locks import NopeLock from flet_core.pubsub.pubsub_hub import PubSubHub -from flet_core.utils.concurrency_utils import is_pyodide from flet_core.utils.deprecated import deprecated logger = logging.getLogger(flet_core.__name__) diff --git a/sdk/python/packages/flet-core/src/flet_core/radio.py b/sdk/python/packages/flet-core/src/flet_core/radio.py index 030c3b37d..6199a2f0d 100644 --- a/sdk/python/packages/flet-core/src/flet_core/radio.py +++ b/sdk/python/packages/flet-core/src/flet_core/radio.py @@ -56,7 +56,7 @@ def button_clicked(e): def __init__( self, label: Optional[str] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, label_style: Optional[TextStyle] = None, value: Optional[str] = None, autofocus: Optional[bool] = None, @@ -232,11 +232,11 @@ def label(self, value): # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/responsive_row.py b/sdk/python/packages/flet-core/src/flet_core/responsive_row.py index 9b97e57ee..93c7054c0 100644 --- a/sdk/python/packages/flet-core/src/flet_core/responsive_row.py +++ b/sdk/python/packages/flet-core/src/flet_core/responsive_row.py @@ -52,8 +52,8 @@ def __init__( self, controls: Optional[List[Control]] = None, columns: Optional[ResponsiveNumber] = None, - alignment: MainAxisAlignment = MainAxisAlignment.NONE, - vertical_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, + alignment: Optional[MainAxisAlignment] = None, + vertical_alignment: Optional[CrossAxisAlignment] = None, spacing: Optional[ResponsiveNumber] = None, run_spacing: Optional[ResponsiveNumber] = None, rtl: Optional[bool] = None, diff --git a/sdk/python/packages/flet-core/src/flet_core/row.py b/sdk/python/packages/flet-core/src/flet_core/row.py index 1dafc6716..e12afbfce 100644 --- a/sdk/python/packages/flet-core/src/flet_core/row.py +++ b/sdk/python/packages/flet-core/src/flet_core/row.py @@ -60,8 +60,8 @@ def main(page: ft.Page): def __init__( self, controls: Optional[List[Control]] = None, - alignment: MainAxisAlignment = MainAxisAlignment.NONE, - vertical_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, + alignment: Optional[MainAxisAlignment] = None, + vertical_alignment: Optional[CrossAxisAlignment] = None, spacing: OptionalNumber = None, tight: Optional[bool] = None, wrap: Optional[bool] = None, diff --git a/sdk/python/packages/flet-core/src/flet_core/shader_mask.py b/sdk/python/packages/flet-core/src/flet_core/shader_mask.py index 58135e46d..82a4446c1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/shader_mask.py +++ b/sdk/python/packages/flet-core/src/flet_core/shader_mask.py @@ -55,7 +55,7 @@ def main(page: ft.Page): def __init__( self, content: Optional[Control] = None, - blend_mode: BlendMode = BlendMode.NONE, + blend_mode: Optional[BlendMode] = None, shader: Optional[Gradient] = None, border_radius: BorderRadiusValue = None, # @@ -149,11 +149,11 @@ def content(self, value: Optional[Control]): # blend_mode @property - def blend_mode(self) -> BlendMode: + def blend_mode(self) -> Optional[BlendMode]: return self.__blend_mode @blend_mode.setter - def blend_mode(self, value: BlendMode): + def blend_mode(self, value: Optional[BlendMode]): self.__blend_mode = value self._set_attr( "blendMode", value.value if isinstance(value, BlendMode) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/switch.py b/sdk/python/packages/flet-core/src/flet_core/switch.py index 4b21c915c..878e4d889 100644 --- a/sdk/python/packages/flet-core/src/flet_core/switch.py +++ b/sdk/python/packages/flet-core/src/flet_core/switch.py @@ -54,7 +54,7 @@ def theme_changed(e): def __init__( self, label: Optional[str] = None, - label_position: LabelPosition = LabelPosition.NONE, + label_position: Optional[LabelPosition] = None, label_style: Optional[TextStyle] = None, value: Optional[bool] = None, autofocus: Optional[bool] = None, @@ -239,11 +239,11 @@ def label_style(self, value: Optional[TextStyle]): # label_position @property - def label_position(self) -> LabelPosition: + def label_position(self) -> Optional[LabelPosition]: return self.__label_position @label_position.setter - def label_position(self, value: LabelPosition): + def label_position(self, value: Optional[LabelPosition]): self.__label_position = value self._set_attr( "labelPosition", value.value if isinstance(value, LabelPosition) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/text.py b/sdk/python/packages/flet-core/src/flet_core/text.py index 77efc8ae7..fb21935c1 100644 --- a/sdk/python/packages/flet-core/src/flet_core/text.py +++ b/sdk/python/packages/flet-core/src/flet_core/text.py @@ -82,7 +82,7 @@ def __init__( self, value: Optional[str] = None, spans: Optional[List[TextSpan]] = None, - text_align: TextAlign = TextAlign.NONE, + text_align: Optional[TextAlign] = None, font_family: Optional[str] = None, size: OptionalNumber = None, weight: Optional[FontWeight] = None, @@ -210,11 +210,11 @@ def spans(self, value: Optional[List[TextSpan]]): # text_align @property - def text_align(self) -> TextAlign: + def text_align(self) -> Optional[TextAlign]: return self.__text_align @text_align.setter - def text_align(self, value: TextAlign): + def text_align(self, value: Optional[TextAlign]): self.__text_align = value self._set_attr( "textAlign", value.value if isinstance(value, TextAlign) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/textfield.py b/sdk/python/packages/flet-core/src/flet_core/textfield.py index e86f73b2e..73d998c53 100644 --- a/sdk/python/packages/flet-core/src/flet_core/textfield.py +++ b/sdk/python/packages/flet-core/src/flet_core/textfield.py @@ -108,7 +108,7 @@ def __init__( can_reveal_password: Optional[bool] = None, read_only: Optional[bool] = None, shift_enter: Optional[bool] = None, - text_align: TextAlign = TextAlign.NONE, + text_align: Optional[TextAlign] = None, autofocus: Optional[bool] = None, capitalization: TextCapitalization = TextCapitalization.NONE, autocorrect: Optional[bool] = None, @@ -346,11 +346,11 @@ def keyboard_type(self, value: Optional[KeyboardType]): # text_align @property - def text_align(self) -> TextAlign: + def text_align(self) -> Optional[TextAlign]: return self.__text_align @text_align.setter - def text_align(self, value: TextAlign): + def text_align(self, value: Optional[TextAlign]): self.__text_align = value self._set_attr( "textAlign", value.value if isinstance(value, TextAlign) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/tooltip.py b/sdk/python/packages/flet-core/src/flet_core/tooltip.py index efa64e81e..ec0c3f883 100644 --- a/sdk/python/packages/flet-core/src/flet_core/tooltip.py +++ b/sdk/python/packages/flet-core/src/flet_core/tooltip.py @@ -77,7 +77,7 @@ def __init__( shape: Optional[BoxShape] = None, message: Optional[str] = None, text_style: Optional[TextStyle] = None, - text_align: TextAlign = TextAlign.NONE, + text_align: Optional[TextAlign] = None, prefer_below: Optional[bool] = None, show_duration: Optional[int] = None, wait_duration: Optional[int] = None, @@ -240,11 +240,11 @@ def message(self, value: Optional[str]): # text_align @property - def text_align(self) -> TextAlign: + def text_align(self) -> Optional[TextAlign]: return self.__text_align @text_align.setter - def text_align(self, value: TextAlign): + def text_align(self, value: Optional[TextAlign]): self.__text_align = value self._set_attr( "textAlign", value.value if isinstance(value, TextAlign) else value diff --git a/sdk/python/packages/flet-core/src/flet_core/types.py b/sdk/python/packages/flet-core/src/flet_core/types.py index 101854174..6b1317687 100644 --- a/sdk/python/packages/flet-core/src/flet_core/types.py +++ b/sdk/python/packages/flet-core/src/flet_core/types.py @@ -103,7 +103,6 @@ class MainAxisAlignment(Enum): class CrossAxisAlignment(Enum): - NONE = None START = "start" END = "end" CENTER = "center" @@ -119,7 +118,6 @@ class VerticalAlignment(Enum): class TabAlignment(Enum): - NONE = None START = "start" START_OFFSET = "startOffset" FILL = "fill" @@ -127,13 +125,11 @@ class TabAlignment(Enum): class LabelPosition(Enum): - NONE = None RIGHT = "right" LEFT = "left" class BlendMode(Enum): - NONE = None CLEAR = "clear" COLOR = "color" COLOR_BURN = "colorBurn" @@ -167,7 +163,6 @@ class BlendMode(Enum): class TextAlign(Enum): - NONE = None LEFT = "left" RIGHT = "right" CENTER = "center" diff --git a/sdk/python/packages/flet-core/src/flet_core/view.py b/sdk/python/packages/flet-core/src/flet_core/view.py index 8cf528042..ab5c3288a 100644 --- a/sdk/python/packages/flet-core/src/flet_core/view.py +++ b/sdk/python/packages/flet-core/src/flet_core/view.py @@ -45,8 +45,8 @@ def __init__( navigation_bar: Union[NavigationBar, CupertinoNavigationBar, None] = None, drawer: Optional[NavigationDrawer] = None, end_drawer: Optional[NavigationDrawer] = None, - vertical_alignment: MainAxisAlignment = MainAxisAlignment.NONE, - horizontal_alignment: CrossAxisAlignment = CrossAxisAlignment.NONE, + vertical_alignment: Optional[MainAxisAlignment] = None, + horizontal_alignment: Optional[CrossAxisAlignment] = None, spacing: OptionalNumber = None, padding: PaddingValue = None, bgcolor: Optional[str] = None, diff --git a/sdk/python/packages/flet-core/tests/test_text.py b/sdk/python/packages/flet-core/tests/test_text.py index 112f9ed14..1574b8b59 100644 --- a/sdk/python/packages/flet-core/tests/test_text.py +++ b/sdk/python/packages/flet-core/tests/test_text.py @@ -1,5 +1,4 @@ import flet_core as ft -import pytest from flet_core.protocol import Command @@ -19,7 +18,7 @@ def test_instance_no_attrs_set(): def test_text_align_enum(): r = ft.Text() - assert r.text_align == ft.TextAlign.NONE + assert r.text_align is None assert r._get_attr("textAlign") is None r = ft.Text(text_align=ft.TextAlign.RIGHT) diff --git a/sdk/python/packages/flet-core/tests/test_tooltip.py b/sdk/python/packages/flet-core/tests/test_tooltip.py index 54001586b..917a55314 100644 --- a/sdk/python/packages/flet-core/tests/test_tooltip.py +++ b/sdk/python/packages/flet-core/tests/test_tooltip.py @@ -1,5 +1,4 @@ import flet_core as ft -import pytest from flet_core.protocol import Command @@ -19,7 +18,7 @@ def test_instance_no_attrs_set(): def test_text_align_enum(): r = ft.Tooltip() - assert r.text_align == ft.TextAlign.NONE + assert r.text_align is None assert r._get_attr("textAlign") is None r = ft.Tooltip(text_align=ft.TextAlign.RIGHT) From ae01358abbc8f46fa95bdf1b0392eefb89b52a15 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 1 Apr 2024 11:46:29 -0700 Subject: [PATCH 102/103] Updated rive package version --- packages/flet_rive/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/flet_rive/pubspec.yaml b/packages/flet_rive/pubspec.yaml index 44baaf5bc..02cb9da11 100644 --- a/packages/flet_rive/pubspec.yaml +++ b/packages/flet_rive/pubspec.yaml @@ -2,7 +2,7 @@ name: flet_rive description: Flet Rive control homepage: https://flet.dev repository: https://github.com/flet-dev/flet/packages/flet_rive -version: 0.21.1 +version: 0.21.2 environment: sdk: '>=3.2.3 <4.0.0' From 266cf63af7d9d6c3df0c3dd34a3b1240ef7a8af3 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 1 Apr 2024 11:56:24 -0700 Subject: [PATCH 103/103] Added Rive to CI --- .appveyor.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 1ede7183c..82c83daf1 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -122,6 +122,7 @@ for: python3 ci/patch_pubspec.py packages/flet_audio/pubspec.yaml $PKG_VER python3 ci/patch_pubspec.py packages/flet_audio_recorder/pubspec.yaml $PKG_VER python3 ci/patch_pubspec.py packages/flet_lottie/pubspec.yaml $PKG_VER + python3 ci/patch_pubspec.py packages/flet_rive/pubspec.yaml $PKG_VER python3 ci/patch_pubspec.py packages/flet_video/pubspec.yaml $PKG_VER python3 ci/patch_pubspec.py packages/flet_webview/pubspec.yaml $PKG_VER @@ -142,6 +143,10 @@ for: dart pub publish --force || exit 1 cd $APPVEYOR_BUILD_FOLDER + cd packages/flet_rive + dart pub publish --force || exit 1 + cd $APPVEYOR_BUILD_FOLDER + cd packages/flet_video dart pub publish --force || exit 1 cd $APPVEYOR_BUILD_FOLDER @@ -169,6 +174,10 @@ for: dart pub publish --dry-run cd $APPVEYOR_BUILD_FOLDER + cd packages/flet_rive + dart pub publish --dry-run + cd $APPVEYOR_BUILD_FOLDER + cd packages/flet_video dart pub publish --dry-run cd $APPVEYOR_BUILD_FOLDER