flet 0.70.0.dev5776__py3-none-any.whl → 0.70.0.dev6145__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flet might be problematic. Click here for more details.
- flet/__init__.py +32 -4
- flet/components/__init__.py +0 -0
- flet/components/component.py +346 -0
- flet/components/component_decorator.py +24 -0
- flet/components/component_owned.py +22 -0
- flet/components/hooks/__init__.py +0 -0
- flet/components/hooks/hook.py +12 -0
- flet/components/hooks/use_callback.py +28 -0
- flet/components/hooks/use_context.py +91 -0
- flet/components/hooks/use_effect.py +104 -0
- flet/components/hooks/use_memo.py +52 -0
- flet/components/hooks/use_state.py +58 -0
- flet/components/memo.py +34 -0
- flet/components/observable.py +269 -0
- flet/components/public_utils.py +10 -0
- flet/components/utils.py +85 -0
- flet/controls/base_control.py +34 -10
- flet/controls/base_page.py +44 -40
- flet/controls/context.py +22 -1
- flet/controls/control_event.py +19 -2
- flet/controls/core/column.py +5 -0
- flet/controls/core/drag_target.py +17 -8
- flet/controls/core/row.py +5 -0
- flet/controls/core/view.py +6 -6
- flet/controls/cupertino/cupertino_icons.py +1 -1
- flet/controls/id_counter.py +24 -0
- flet/controls/material/divider.py +6 -0
- flet/controls/material/icons.py +1 -1
- flet/controls/material/textfield.py +10 -1
- flet/controls/material/vertical_divider.py +6 -0
- flet/controls/object_patch.py +434 -197
- flet/controls/page.py +203 -84
- flet/controls/services/haptic_feedback.py +0 -3
- flet/controls/services/shake_detector.py +0 -3
- flet/messaging/flet_socket_server.py +13 -6
- flet/messaging/session.py +103 -10
- flet/{controls/session_storage.py → messaging/session_store.py} +2 -2
- flet/version.py +1 -1
- {flet-0.70.0.dev5776.dist-info → flet-0.70.0.dev6145.dist-info}/METADATA +4 -5
- {flet-0.70.0.dev5776.dist-info → flet-0.70.0.dev6145.dist-info}/RECORD +43 -30
- flet/controls/cache.py +0 -87
- flet/controls/control_id.py +0 -22
- flet/controls/core/state_view.py +0 -60
- {flet-0.70.0.dev5776.dist-info → flet-0.70.0.dev6145.dist-info}/WHEEL +0 -0
- {flet-0.70.0.dev5776.dist-info → flet-0.70.0.dev6145.dist-info}/entry_points.txt +0 -0
- {flet-0.70.0.dev5776.dist-info → flet-0.70.0.dev6145.dist-info}/top_level.txt +0 -0
flet/controls/base_control.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, Union
|
|
|
7
7
|
|
|
8
8
|
from flet.controls.context import _context_page, context
|
|
9
9
|
from flet.controls.control_event import ControlEvent, get_event_field_type
|
|
10
|
-
from flet.controls.
|
|
10
|
+
from flet.controls.id_counter import ControlId
|
|
11
11
|
from flet.controls.keys import KeyValue
|
|
12
12
|
from flet.controls.ref import Ref
|
|
13
13
|
from flet.utils.from_dict import from_dict
|
|
@@ -119,7 +119,6 @@ class BaseControl:
|
|
|
119
119
|
"""
|
|
120
120
|
Arbitrary data of any type.
|
|
121
121
|
"""
|
|
122
|
-
|
|
123
122
|
key: Optional[KeyValue] = None
|
|
124
123
|
|
|
125
124
|
ref: InitVar[Optional[Ref["BaseControl"]]] = None
|
|
@@ -173,18 +172,21 @@ class BaseControl:
|
|
|
173
172
|
return parent_ref() if parent_ref else None
|
|
174
173
|
|
|
175
174
|
@property
|
|
176
|
-
def page(self) ->
|
|
175
|
+
def page(self) -> Union["Page", "BasePage"]:
|
|
177
176
|
"""
|
|
178
177
|
The page to which this control belongs to.
|
|
179
178
|
"""
|
|
180
|
-
from .page import
|
|
179
|
+
from .page import Page
|
|
181
180
|
|
|
182
181
|
parent = self
|
|
183
182
|
while parent:
|
|
184
|
-
if isinstance(parent, (Page
|
|
183
|
+
if isinstance(parent, (Page)):
|
|
185
184
|
return parent
|
|
186
185
|
parent = parent.parent
|
|
187
|
-
|
|
186
|
+
raise RuntimeError(
|
|
187
|
+
f"{self.__class__.__qualname__}({self._i}) "
|
|
188
|
+
"Control must be added to the page first"
|
|
189
|
+
)
|
|
188
190
|
|
|
189
191
|
def is_isolated(self):
|
|
190
192
|
return hasattr(self, "_isolated") and self._isolated
|
|
@@ -209,15 +211,25 @@ class BaseControl:
|
|
|
209
211
|
"""
|
|
210
212
|
pass
|
|
211
213
|
|
|
214
|
+
def _before_update_safe(self):
|
|
215
|
+
frozen = getattr(self, "_frozen", None)
|
|
216
|
+
if frozen is not None:
|
|
217
|
+
del self._frozen
|
|
218
|
+
|
|
219
|
+
self.before_update()
|
|
220
|
+
|
|
221
|
+
if frozen is not None:
|
|
222
|
+
self._frozen = frozen
|
|
223
|
+
|
|
212
224
|
def before_event(self, e: ControlEvent):
|
|
213
225
|
return True
|
|
214
226
|
|
|
215
227
|
def did_mount(self):
|
|
216
|
-
controls_log.debug(f"{self.
|
|
228
|
+
controls_log.debug(f"{self}.did_mount()")
|
|
217
229
|
pass
|
|
218
230
|
|
|
219
231
|
def will_unmount(self):
|
|
220
|
-
controls_log.debug(f"{self.
|
|
232
|
+
controls_log.debug(f"{self}.will_unmount()")
|
|
221
233
|
pass
|
|
222
234
|
|
|
223
235
|
# public methods
|
|
@@ -239,7 +251,7 @@ class BaseControl:
|
|
|
239
251
|
f"{self.__class__.__qualname__} Control must be added to the page first"
|
|
240
252
|
)
|
|
241
253
|
|
|
242
|
-
return await self.page.
|
|
254
|
+
return await self.page.session.invoke_method(
|
|
243
255
|
self._i, method_name, arguments, timeout
|
|
244
256
|
)
|
|
245
257
|
|
|
@@ -271,11 +283,13 @@ class BaseControl:
|
|
|
271
283
|
_context_page.set(self.page)
|
|
272
284
|
context.reset_auto_update()
|
|
273
285
|
|
|
286
|
+
controls_log.debug(f"Trigger event {self}.{field_name} {e}")
|
|
287
|
+
|
|
274
288
|
assert self.page, (
|
|
275
289
|
"Control must be added to a page before triggering events. "
|
|
276
290
|
"Use page.add(control) or add it to a parent control that's on a page."
|
|
277
291
|
)
|
|
278
|
-
session = self.page.
|
|
292
|
+
session = self.page.session
|
|
279
293
|
|
|
280
294
|
# Handle async and sync event handlers accordingly
|
|
281
295
|
event_handler = getattr(self, field_name)
|
|
@@ -310,3 +324,13 @@ class BaseControl:
|
|
|
310
324
|
event_handler(e)
|
|
311
325
|
|
|
312
326
|
await session.after_event(session.index.get(self._i))
|
|
327
|
+
|
|
328
|
+
def _migrate_state(self, other: "BaseControl"):
|
|
329
|
+
if not isinstance(other, BaseControl):
|
|
330
|
+
return
|
|
331
|
+
self._i = other._i
|
|
332
|
+
if self.data is None:
|
|
333
|
+
self.data = other.data
|
|
334
|
+
|
|
335
|
+
def __str__(self):
|
|
336
|
+
return f"{self._c}({self._i} - {id(self)})"
|
flet/controls/base_page.py
CHANGED
|
@@ -159,33 +159,32 @@ class BasePage(AdaptiveControl):
|
|
|
159
159
|
reported by the framework.
|
|
160
160
|
"""
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
title: Optional[str] = None
|
|
163
|
+
"""
|
|
164
|
+
Page or window title.
|
|
163
165
|
"""
|
|
164
|
-
Page width in logical pixels.
|
|
165
166
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
title bar and borders) when running a Flet app on desktop,
|
|
170
|
-
use the [`width`][flet.Window.] property of
|
|
171
|
-
[`Page.window`][flet.] instead.
|
|
167
|
+
enable_screenshots: bool = False
|
|
168
|
+
"""
|
|
169
|
+
Enable taking screenshots of the entire page with `take_screenshot` method.
|
|
172
170
|
"""
|
|
173
171
|
|
|
174
|
-
|
|
172
|
+
on_resize: Optional[EventHandler["PageResizeEvent"]] = None
|
|
175
173
|
"""
|
|
176
|
-
|
|
174
|
+
Called when a user resizes a browser or native OS window containing Flet app, for
|
|
175
|
+
example:
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
```python
|
|
178
|
+
def page_resize(e):
|
|
179
|
+
print("New page size:", page.window.width, page.window_height)
|
|
180
|
+
|
|
181
|
+
page.on_resize = page_resize
|
|
182
|
+
```
|
|
184
183
|
"""
|
|
185
184
|
|
|
186
|
-
|
|
185
|
+
on_media_change: Optional[EventHandler[PageMediaData]] = None
|
|
187
186
|
"""
|
|
188
|
-
|
|
187
|
+
Called when `media` has changed.
|
|
189
188
|
"""
|
|
190
189
|
|
|
191
190
|
media: PageMediaData = field(
|
|
@@ -197,30 +196,35 @@ class BasePage(AdaptiveControl):
|
|
|
197
196
|
)
|
|
198
197
|
)
|
|
199
198
|
"""
|
|
200
|
-
|
|
201
|
-
"""
|
|
199
|
+
The current environmental metrics of the page or window.
|
|
202
200
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
201
|
+
This data is updated whenever the platform window or layout changes,
|
|
202
|
+
such as when rotating a device, resizing a browser window, or adjusting
|
|
203
|
+
system UI elements like the keyboard or safe areas.
|
|
206
204
|
"""
|
|
207
205
|
|
|
208
|
-
|
|
206
|
+
width: Optional[Number] = None
|
|
209
207
|
"""
|
|
210
|
-
|
|
211
|
-
example:
|
|
212
|
-
|
|
213
|
-
```python
|
|
214
|
-
def page_resize(e):
|
|
215
|
-
print("New page size:", page.window.width, page.window_height)
|
|
208
|
+
Page width in logical pixels.
|
|
216
209
|
|
|
217
|
-
|
|
218
|
-
|
|
210
|
+
Note:
|
|
211
|
+
- This property is read-only.
|
|
212
|
+
- To get or set the full window height including window chrome (e.g.,
|
|
213
|
+
title bar and borders) when running a Flet app on desktop,
|
|
214
|
+
use the [`width`][flet.Window.width] property of
|
|
215
|
+
[`Page.window`][flet.Page.window] instead.
|
|
219
216
|
"""
|
|
220
217
|
|
|
221
|
-
|
|
218
|
+
height: Optional[Number] = None
|
|
222
219
|
"""
|
|
223
|
-
|
|
220
|
+
Page height in logical pixels.
|
|
221
|
+
|
|
222
|
+
Note:
|
|
223
|
+
- This property is read-only.
|
|
224
|
+
- To get or set the full window height including window chrome (e.g.,
|
|
225
|
+
title bar and borders) when running a Flet app on desktop,
|
|
226
|
+
use the [`height`][flet.Window.height] property of
|
|
227
|
+
[`Page.window`][flet.Page.window] instead.
|
|
224
228
|
"""
|
|
225
229
|
|
|
226
230
|
_overlay: "Overlay" = field(default_factory=lambda: Overlay())
|
|
@@ -492,29 +496,29 @@ class BasePage(AdaptiveControl):
|
|
|
492
496
|
|
|
493
497
|
# horizontal_alignment
|
|
494
498
|
@property
|
|
495
|
-
def horizontal_alignment(self) ->
|
|
499
|
+
def horizontal_alignment(self) -> CrossAxisAlignment:
|
|
496
500
|
return self.__default_view().horizontal_alignment
|
|
497
501
|
|
|
498
502
|
@horizontal_alignment.setter
|
|
499
|
-
def horizontal_alignment(self, value:
|
|
503
|
+
def horizontal_alignment(self, value: CrossAxisAlignment):
|
|
500
504
|
self.__default_view().horizontal_alignment = value
|
|
501
505
|
|
|
502
506
|
# vertical_alignment
|
|
503
507
|
@property
|
|
504
|
-
def vertical_alignment(self) ->
|
|
508
|
+
def vertical_alignment(self) -> MainAxisAlignment:
|
|
505
509
|
return self.__default_view().vertical_alignment
|
|
506
510
|
|
|
507
511
|
@vertical_alignment.setter
|
|
508
|
-
def vertical_alignment(self, value:
|
|
512
|
+
def vertical_alignment(self, value: MainAxisAlignment):
|
|
509
513
|
self.__default_view().vertical_alignment = value
|
|
510
514
|
|
|
511
515
|
# spacing
|
|
512
516
|
@property
|
|
513
|
-
def spacing(self) ->
|
|
517
|
+
def spacing(self) -> Number:
|
|
514
518
|
return self.__default_view().spacing
|
|
515
519
|
|
|
516
520
|
@spacing.setter
|
|
517
|
-
def spacing(self, value:
|
|
521
|
+
def spacing(self, value: Number):
|
|
518
522
|
self.__default_view().spacing = value
|
|
519
523
|
|
|
520
524
|
# padding
|
flet/controls/context.py
CHANGED
|
@@ -13,6 +13,9 @@ class Context:
|
|
|
13
13
|
Context instance is accessed via [`flet.context`][flet.context].
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
+
def __init__(self) -> None:
|
|
17
|
+
self.__components_mode = False
|
|
18
|
+
|
|
16
19
|
@property
|
|
17
20
|
def page(self) -> "Page":
|
|
18
21
|
"""
|
|
@@ -95,6 +98,21 @@ class Context:
|
|
|
95
98
|
"""
|
|
96
99
|
_update_behavior_context_var.get()._auto_update_enabled = False
|
|
97
100
|
|
|
101
|
+
def enable_components_mode(self):
|
|
102
|
+
"""
|
|
103
|
+
Enables components mode in the current context.
|
|
104
|
+
"""
|
|
105
|
+
self.__components_mode = True
|
|
106
|
+
|
|
107
|
+
def is_components_mode(self) -> bool:
|
|
108
|
+
"""
|
|
109
|
+
Returns whether the current context is in components mode.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
`True` if in components mode, `False` otherwise.
|
|
113
|
+
"""
|
|
114
|
+
return self.__components_mode
|
|
115
|
+
|
|
98
116
|
def auto_update_enabled(self) -> bool:
|
|
99
117
|
"""
|
|
100
118
|
Returns whether auto-update is enabled in the current context.
|
|
@@ -102,7 +120,10 @@ class Context:
|
|
|
102
120
|
Returns:
|
|
103
121
|
`True` if auto-update is enabled, `False` otherwise.
|
|
104
122
|
"""
|
|
105
|
-
return
|
|
123
|
+
return (
|
|
124
|
+
not self.__components_mode
|
|
125
|
+
and _update_behavior_context_var.get()._auto_update_enabled
|
|
126
|
+
)
|
|
106
127
|
|
|
107
128
|
def reset_auto_update(self):
|
|
108
129
|
"""
|
flet/controls/control_event.py
CHANGED
|
@@ -32,14 +32,17 @@ __all__ = [
|
|
|
32
32
|
|
|
33
33
|
def get_event_field_type(control: Any, field_name: str):
|
|
34
34
|
frame = inspect.currentframe().f_back
|
|
35
|
-
globalns = sys.modules[control.__class__.__module__].__dict__
|
|
36
35
|
localns = frame.f_globals.copy()
|
|
37
36
|
localns.update(frame.f_locals)
|
|
38
37
|
|
|
39
38
|
merged_annotations = {}
|
|
39
|
+
annotation_modules = {}
|
|
40
40
|
|
|
41
41
|
for cls in control.__class__.__mro__:
|
|
42
42
|
annotations = getattr(cls, "__annotations__", {})
|
|
43
|
+
module = sys.modules.get(cls.__module__)
|
|
44
|
+
module_dict = module.__dict__ if module else {}
|
|
45
|
+
|
|
43
46
|
for name, annotation in annotations.items():
|
|
44
47
|
if get_origin(annotation) is InitVar or str(annotation).startswith(
|
|
45
48
|
"dataclasses.InitVar"
|
|
@@ -47,12 +50,25 @@ def get_event_field_type(control: Any, field_name: str):
|
|
|
47
50
|
continue # Skip InitVar
|
|
48
51
|
if name not in merged_annotations:
|
|
49
52
|
merged_annotations[name] = annotation
|
|
53
|
+
annotation_modules[name] = module_dict
|
|
50
54
|
|
|
51
55
|
if field_name not in merged_annotations:
|
|
52
56
|
return None
|
|
53
57
|
|
|
54
58
|
annotation = merged_annotations[field_name]
|
|
55
59
|
|
|
60
|
+
globalns = {}
|
|
61
|
+
current_module = sys.modules.get(control.__class__.__module__)
|
|
62
|
+
if current_module:
|
|
63
|
+
globalns.update(current_module.__dict__)
|
|
64
|
+
|
|
65
|
+
owner_module_dict = annotation_modules.get(field_name)
|
|
66
|
+
if owner_module_dict:
|
|
67
|
+
for key, value in owner_module_dict.items():
|
|
68
|
+
globalns.setdefault(key, value)
|
|
69
|
+
|
|
70
|
+
globalns.setdefault("__builtins__", __builtins__)
|
|
71
|
+
|
|
56
72
|
try:
|
|
57
73
|
# Resolve forward refs manually
|
|
58
74
|
if isinstance(annotation, ForwardRef):
|
|
@@ -80,7 +96,8 @@ class Event(Generic[EventControlType]):
|
|
|
80
96
|
control: EventControlType = field(repr=False)
|
|
81
97
|
|
|
82
98
|
@property
|
|
83
|
-
def page(self) ->
|
|
99
|
+
def page(self) -> Union["Page", "BasePage"]:
|
|
100
|
+
assert self.control.page
|
|
84
101
|
return self.control.page
|
|
85
102
|
|
|
86
103
|
@property
|
flet/controls/core/column.py
CHANGED
|
@@ -65,6 +65,11 @@ class Column(LayoutControl, ScrollableControl, AdaptiveControl):
|
|
|
65
65
|
is `True`.
|
|
66
66
|
"""
|
|
67
67
|
|
|
68
|
+
intrinsic_width: bool = False
|
|
69
|
+
"""
|
|
70
|
+
If `True`, the Column will be as wide as the widest child control.
|
|
71
|
+
"""
|
|
72
|
+
|
|
68
73
|
def init(self):
|
|
69
74
|
super().init()
|
|
70
75
|
self._internals["host_expanded"] = True
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Optional, cast
|
|
3
3
|
|
|
4
4
|
from flet.controls.base_control import control
|
|
5
5
|
from flet.controls.control import Control
|
|
6
6
|
from flet.controls.control_event import Event, EventHandler
|
|
7
|
+
from flet.controls.core.draggable import Draggable
|
|
7
8
|
from flet.controls.transform import Offset
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
@@ -15,14 +16,22 @@ __all__ = [
|
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
@dataclass
|
|
18
|
-
class
|
|
19
|
+
class DragEventBase(Event["DragTarget"]):
|
|
20
|
+
src_id: Optional[int]
|
|
21
|
+
src: Draggable = field(init=False)
|
|
22
|
+
|
|
23
|
+
def __post_init__(self):
|
|
24
|
+
if self.src_id is not None:
|
|
25
|
+
self.src = cast(Draggable, self.page.get_control(self.src_id))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass
|
|
29
|
+
class DragWillAcceptEvent(DragEventBase):
|
|
19
30
|
accept: bool
|
|
20
|
-
src_id: int
|
|
21
31
|
|
|
22
32
|
|
|
23
33
|
@dataclass
|
|
24
|
-
class DragTargetEvent(
|
|
25
|
-
src_id: int
|
|
34
|
+
class DragTargetEvent(DragEventBase):
|
|
26
35
|
x: float
|
|
27
36
|
y: float
|
|
28
37
|
|
|
@@ -32,8 +41,8 @@ class DragTargetEvent(Event["DragTarget"]):
|
|
|
32
41
|
|
|
33
42
|
|
|
34
43
|
@dataclass
|
|
35
|
-
class DragTargetLeaveEvent(
|
|
36
|
-
|
|
44
|
+
class DragTargetLeaveEvent(DragEventBase):
|
|
45
|
+
pass
|
|
37
46
|
|
|
38
47
|
|
|
39
48
|
@control("DragTarget")
|
flet/controls/core/row.py
CHANGED
|
@@ -68,6 +68,11 @@ class Row(LayoutControl, ScrollableControl, AdaptiveControl):
|
|
|
68
68
|
How the runs should be placed in the cross-axis when `wrap=True`.
|
|
69
69
|
"""
|
|
70
70
|
|
|
71
|
+
intrinsic_height: bool = False
|
|
72
|
+
"""
|
|
73
|
+
If `True`, the Row will be as tall as the tallest child control.
|
|
74
|
+
"""
|
|
75
|
+
|
|
71
76
|
def init(self):
|
|
72
77
|
super().init()
|
|
73
78
|
self._internals["host_expanded"] = True
|
flet/controls/core/view.py
CHANGED
|
@@ -37,12 +37,6 @@ class View(ScrollableControl, LayoutControl):
|
|
|
37
37
|
control, so it has a similar behavior and shares same properties.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
-
route: Optional[str] = None
|
|
41
|
-
"""
|
|
42
|
-
View's route - not currently used by Flet framework, but can be used in a user
|
|
43
|
-
program to update [`Page.route`][flet.] when a view popped.
|
|
44
|
-
"""
|
|
45
|
-
|
|
46
40
|
controls: list[BaseControl] = field(default_factory=list)
|
|
47
41
|
"""
|
|
48
42
|
A list of controls to display.
|
|
@@ -71,6 +65,12 @@ class View(ScrollableControl, LayoutControl):
|
|
|
71
65
|
///
|
|
72
66
|
"""
|
|
73
67
|
|
|
68
|
+
route: Optional[str] = field(default_factory=lambda: "/")
|
|
69
|
+
"""
|
|
70
|
+
View's route - not currently used by Flet framework, but can be used in a user
|
|
71
|
+
program to update [`Page.route`][flet.Page.route] when a view popped.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
74
|
appbar: Optional[Union[AppBar, CupertinoAppBar]] = None
|
|
75
75
|
"""
|
|
76
76
|
An [`AppBar`][flet.] control to display at the top of
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import itertools
|
|
2
|
+
import threading
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from flet.utils.locks import NopeLock
|
|
6
|
+
from flet.utils.platform_utils import is_pyodide
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class IdCounter:
|
|
10
|
+
def __init__(
|
|
11
|
+
self, start: int = 1, step: int = 1, lock: Optional[threading.Lock] = None
|
|
12
|
+
):
|
|
13
|
+
self._counter = itertools.count(start, step)
|
|
14
|
+
self._lock = lock or (NopeLock() if is_pyodide() else threading.Lock())
|
|
15
|
+
|
|
16
|
+
def next(self) -> int:
|
|
17
|
+
with self._lock:
|
|
18
|
+
return next(self._counter)
|
|
19
|
+
|
|
20
|
+
def __call__(self) -> int: # for dataclass default_factory
|
|
21
|
+
return self.next()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
ControlId = IdCounter(start=3)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from flet.controls.base_control import control
|
|
4
|
+
from flet.controls.border_radius import BorderRadiusValue
|
|
4
5
|
from flet.controls.control import Control
|
|
5
6
|
from flet.controls.types import ColorValue, Number
|
|
6
7
|
|
|
@@ -62,6 +63,11 @@ class Divider(Control):
|
|
|
62
63
|
If that is also `None`, defaults to `0.0`.
|
|
63
64
|
"""
|
|
64
65
|
|
|
66
|
+
radius: Optional[BorderRadiusValue] = None
|
|
67
|
+
"""
|
|
68
|
+
The border radius of the divider.
|
|
69
|
+
"""
|
|
70
|
+
|
|
65
71
|
def before_update(self):
|
|
66
72
|
super().before_update()
|
|
67
73
|
if self.height is not None and self.height < 0:
|
flet/controls/material/icons.py
CHANGED
|
@@ -3,7 +3,7 @@ from enum import Enum
|
|
|
3
3
|
from typing import Optional, Union
|
|
4
4
|
|
|
5
5
|
from flet.controls.adaptive_control import AdaptiveControl
|
|
6
|
-
from flet.controls.base_control import control
|
|
6
|
+
from flet.controls.base_control import BaseControl, control
|
|
7
7
|
from flet.controls.control_event import ControlEventHandler
|
|
8
8
|
from flet.controls.core.autofill_group import AutofillHint
|
|
9
9
|
from flet.controls.material.form_field_control import FormFieldControl
|
|
@@ -424,6 +424,15 @@ class TextField(FormFieldControl, AdaptiveControl):
|
|
|
424
424
|
TBD
|
|
425
425
|
"""
|
|
426
426
|
|
|
427
|
+
def _migrate_state(self, other: BaseControl):
|
|
428
|
+
super()._migrate_state(other)
|
|
429
|
+
if (
|
|
430
|
+
isinstance(other, TextField)
|
|
431
|
+
and self.value is None
|
|
432
|
+
and self.value != other.value
|
|
433
|
+
):
|
|
434
|
+
self.value = other.value
|
|
435
|
+
|
|
427
436
|
def before_update(self):
|
|
428
437
|
super().before_update()
|
|
429
438
|
if self.min_lines is not None and self.min_lines <= 0:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
from flet.controls.base_control import control
|
|
4
|
+
from flet.controls.border_radius import BorderRadiusValue
|
|
4
5
|
from flet.controls.control import Control
|
|
5
6
|
from flet.controls.types import ColorValue, Number
|
|
6
7
|
|
|
@@ -67,6 +68,11 @@ class VerticalDivider(Control):
|
|
|
67
68
|
If that's is also `None`, defaults to `0.0`.
|
|
68
69
|
"""
|
|
69
70
|
|
|
71
|
+
radius: Optional[BorderRadiusValue] = None
|
|
72
|
+
"""
|
|
73
|
+
The border radius of the divider.
|
|
74
|
+
"""
|
|
75
|
+
|
|
70
76
|
def before_update(self):
|
|
71
77
|
super().before_update()
|
|
72
78
|
if self.width is not None and self.width < 0:
|