dex-framework 0.0.50__tar.gz
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.
- dex_framework-0.0.50/LICENSE +21 -0
- dex_framework-0.0.50/MANIFEST.in +5 -0
- dex_framework-0.0.50/PKG-INFO +217 -0
- dex_framework-0.0.50/README.md +189 -0
- dex_framework-0.0.50/dex_framework/__init__.py +22 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_ActionButtons.py +212 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_CupertinoButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_CupertinoFilledButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_ElevatedButton.py +57 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_FilledButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_FilledTonalButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_FloatingActionButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_IconButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_MenuItemButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_OutlinedButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_PopupMenuButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_SubmenuButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/DEx_TextButton.py +52 -0
- dex_framework-0.0.50/dex_framework/buttons/__init__.py +30 -0
- dex_framework-0.0.50/dex_framework/canvas/DEx_Canvas.py +50 -0
- dex_framework-0.0.50/dex_framework/canvas/__init__.py +3 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_BarChart.py +82 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_CandlestickChart.py +288 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_DonutChart.py +334 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_GeoHeatmap.py +305 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_HeatmapChart.py +363 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_LineChart.py +85 -0
- dex_framework-0.0.50/dex_framework/charts/DEx_PieChart.py +79 -0
- dex_framework-0.0.50/dex_framework/charts/__init__.py +15 -0
- dex_framework-0.0.50/dex_framework/charts/_brazil_states.py +295 -0
- dex_framework-0.0.50/dex_framework/core/DEx_Compat.py +45 -0
- dex_framework-0.0.50/dex_framework/core/DEx_Config.py +26 -0
- dex_framework-0.0.50/dex_framework/core/DEx_Protocol.py +30 -0
- dex_framework-0.0.50/dex_framework/core/__init__.py +13 -0
- dex_framework-0.0.50/dex_framework/display/DEx_Card.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_CircleAvatar.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_DataTable.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_ExpansionPanel.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_ExpansionTile.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_GridView.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_Icon.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_Image.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_KpiCard.py +205 -0
- dex_framework-0.0.50/dex_framework/display/DEx_ListTile.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_ListView.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_Markdown.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_Text.py +50 -0
- dex_framework-0.0.50/dex_framework/display/DEx_VersionBar.py +80 -0
- dex_framework-0.0.50/dex_framework/display/__init__.py +21 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_AlertDialog.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_Badge.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_Banner.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_Chip.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_CupertinoActivityIndicator.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_CupertinoAlertDialog.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_ProgressBar.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_ProgressRing.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_SnackBar.py +50 -0
- dex_framework-0.0.50/dex_framework/feedback/DEx_Tooltip.py +53 -0
- dex_framework-0.0.50/dex_framework/feedback/__init__.py +17 -0
- dex_framework-0.0.50/dex_framework/input/DEx_Checkbox.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_CupertinoCheckbox.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_CupertinoSlider.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_CupertinoSwitch.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_CupertinoTextField.py +56 -0
- dex_framework-0.0.50/dex_framework/input/DEx_DatePicker.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_Dropdown.py +57 -0
- dex_framework-0.0.50/dex_framework/input/DEx_Radio.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_RadioGroup.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_RangeSlider.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_Slider.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_Switch.py +50 -0
- dex_framework-0.0.50/dex_framework/input/DEx_TextField.py +57 -0
- dex_framework-0.0.50/dex_framework/input/DEx_TimePicker.py +50 -0
- dex_framework-0.0.50/dex_framework/input/__init__.py +22 -0
- dex_framework-0.0.50/dex_framework/interaction/DEx_Dismissible.py +50 -0
- dex_framework-0.0.50/dex_framework/interaction/DEx_Draggable.py +50 -0
- dex_framework-0.0.50/dex_framework/interaction/DEx_GestureDetector.py +50 -0
- dex_framework-0.0.50/dex_framework/interaction/DEx_SelectionArea.py +50 -0
- dex_framework-0.0.50/dex_framework/interaction/DEx_TransparentPointer.py +50 -0
- dex_framework-0.0.50/dex_framework/interaction/__init__.py +10 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_AppShell.py +394 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_Column.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_Container.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_Header.py +171 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_ResponsiveRow.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_Row.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_SafeArea.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/DEx_Stack.py +50 -0
- dex_framework-0.0.50/dex_framework/layout/__init__.py +15 -0
- dex_framework-0.0.50/dex_framework/maps/DEx_GeoHeatmap.py +703 -0
- dex_framework-0.0.50/dex_framework/maps/DEx_Map.py +79 -0
- dex_framework-0.0.50/dex_framework/maps/__init__.py +4 -0
- dex_framework-0.0.50/dex_framework/media/DEx_Audio.py +80 -0
- dex_framework-0.0.50/dex_framework/media/DEx_Lottie.py +82 -0
- dex_framework-0.0.50/dex_framework/media/DEx_Video.py +75 -0
- dex_framework-0.0.50/dex_framework/media/__init__.py +5 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_AppBar.py +50 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_CupertinoNavigationBar.py +50 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_NavBar.py +531 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_NavigationBar.py +50 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_NavigationDrawer.py +50 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_NavigationRail.py +50 -0
- dex_framework-0.0.50/dex_framework/navigation/DEx_Tabs.py +158 -0
- dex_framework-0.0.50/dex_framework/navigation/__init__.py +13 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_BottomSheet.py +50 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_CupertinoBottomSheet.py +50 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_Drawer.py +51 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_MenuBar.py +50 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_Pagelet.py +50 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_SearchAnchor.py +67 -0
- dex_framework-0.0.50/dex_framework/overlay/DEx_SearchBar.py +50 -0
- dex_framework-0.0.50/dex_framework/overlay/__init__.py +12 -0
- dex_framework-0.0.50/dex_framework/py.typed +0 -0
- dex_framework-0.0.50/dex_framework/scrolling/DEx_DragTarget.py +50 -0
- dex_framework-0.0.50/dex_framework/scrolling/DEx_ScrollableControl.py +56 -0
- dex_framework-0.0.50/dex_framework/scrolling/__init__.py +4 -0
- dex_framework-0.0.50/dex_framework/theming/DEx_BrandThemes.py +1006 -0
- dex_framework-0.0.50/dex_framework/theming/DEx_ColorScheme.py +37 -0
- dex_framework-0.0.50/dex_framework/theming/DEx_Theme.py +37 -0
- dex_framework-0.0.50/dex_framework/theming/__init__.py +5 -0
- dex_framework-0.0.50/dex_framework.egg-info/PKG-INFO +217 -0
- dex_framework-0.0.50/dex_framework.egg-info/SOURCES.txt +126 -0
- dex_framework-0.0.50/dex_framework.egg-info/dependency_links.txt +1 -0
- dex_framework-0.0.50/dex_framework.egg-info/requires.txt +5 -0
- dex_framework-0.0.50/dex_framework.egg-info/top_level.txt +1 -0
- dex_framework-0.0.50/pyproject.toml +47 -0
- dex_framework-0.0.50/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Almir
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dex-framework
|
|
3
|
+
Version: 0.0.50
|
|
4
|
+
Summary: Biblioteca reutilizável que encapsula todos os componentes do Flet v0.84.0, organizada em grupos temáticos.
|
|
5
|
+
Author-email: Almir <almir.jg@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/almirjg/DEx-Framework_3
|
|
8
|
+
Project-URL: Repository, https://github.com/almirjg/DEx-Framework_3
|
|
9
|
+
Keywords: flet,ui,framework,components,saas,design-system
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: flet==0.84.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: build>=1.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# DEx-Framework v0.0.49
|
|
30
|
+
|
|
31
|
+
Biblioteca reutilizável que encapsula **todos os componentes do Flet v0.84.0**, organizada em grupos temáticos, com UseCases demonstrativos para cada grupo.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Instalação
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install flet==0.84.0
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Clone o repositório e adicione ao `PYTHONPATH` ou instale em modo editável:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone <repo-url>
|
|
45
|
+
cd DEx-Framework_3
|
|
46
|
+
pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Uso básico
|
|
52
|
+
|
|
53
|
+
### Exemplo 1 — Botão com dex_id e callback de montagem
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
import flet as ft
|
|
57
|
+
from dex_framework import DEx_ElevatedButton
|
|
58
|
+
|
|
59
|
+
def main(page: ft.Page) -> None:
|
|
60
|
+
btn = DEx_ElevatedButton(
|
|
61
|
+
text="Salvar",
|
|
62
|
+
dex_id="btn_salvar",
|
|
63
|
+
on_click=lambda e: print("clicou"),
|
|
64
|
+
on_dex_ready=lambda c: print(f"{c.dex_id} montado"),
|
|
65
|
+
)
|
|
66
|
+
page.add(btn)
|
|
67
|
+
|
|
68
|
+
ft.app(target=main)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Exemplo 2 — Layout responsivo
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import flet as ft
|
|
75
|
+
from dex_framework import DEx_ResponsiveRow, DEx_Container, DEx_Text
|
|
76
|
+
|
|
77
|
+
def main(page: ft.Page) -> None:
|
|
78
|
+
row = DEx_ResponsiveRow(
|
|
79
|
+
dex_id="row_principal",
|
|
80
|
+
controls=[
|
|
81
|
+
DEx_Container(
|
|
82
|
+
col={"sm": 12, "md": 6},
|
|
83
|
+
content=DEx_Text("Coluna esquerda", dex_id="txt_esq"),
|
|
84
|
+
bgcolor=ft.Colors.BLUE_50,
|
|
85
|
+
padding=16,
|
|
86
|
+
),
|
|
87
|
+
DEx_Container(
|
|
88
|
+
col={"sm": 12, "md": 6},
|
|
89
|
+
content=DEx_Text("Coluna direita", dex_id="txt_dir"),
|
|
90
|
+
bgcolor=ft.Colors.GREEN_50,
|
|
91
|
+
padding=16,
|
|
92
|
+
),
|
|
93
|
+
],
|
|
94
|
+
)
|
|
95
|
+
page.add(row)
|
|
96
|
+
|
|
97
|
+
ft.app(target=main)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Exemplo 3 — Tema customizado
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
import flet as ft
|
|
104
|
+
from dex_framework import DEx_Theme, DEx_ColorScheme
|
|
105
|
+
|
|
106
|
+
def main(page: ft.Page) -> None:
|
|
107
|
+
page.theme = DEx_Theme(
|
|
108
|
+
color_scheme_seed=ft.Colors.INDIGO,
|
|
109
|
+
color_scheme=DEx_ColorScheme(
|
|
110
|
+
primary=ft.Colors.INDIGO,
|
|
111
|
+
secondary=ft.Colors.TEAL,
|
|
112
|
+
dex_id="esquema_app",
|
|
113
|
+
),
|
|
114
|
+
dex_id="tema_app",
|
|
115
|
+
)
|
|
116
|
+
page.add(ft.Text("App com tema DEx!", size=24))
|
|
117
|
+
|
|
118
|
+
ft.app(target=main)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Estrutura de grupos
|
|
124
|
+
|
|
125
|
+
| Grupo | Componentes | Quantidade |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `layout` | DEx_Row, DEx_Column, DEx_Stack, DEx_Container, DEx_ResponsiveRow, DEx_SafeArea | 6 |
|
|
128
|
+
| `navigation` | DEx_AppBar, DEx_NavigationBar, DEx_NavigationRail, DEx_NavigationDrawer, DEx_Tabs, DEx_CupertinoNavigationBar | 6 |
|
|
129
|
+
| `input` | DEx_TextField, DEx_Dropdown, DEx_Checkbox, DEx_Radio, DEx_RadioGroup, DEx_Switch, DEx_Slider, DEx_RangeSlider, DEx_DatePicker, DEx_TimePicker, DEx_CupertinoTextField, DEx_CupertinoCheckbox, DEx_CupertinoSlider, DEx_CupertinoSwitch | 14 |
|
|
130
|
+
| `buttons` | DEx_ElevatedButton, DEx_FilledButton, DEx_FilledTonalButton, DEx_OutlinedButton, DEx_TextButton, DEx_IconButton, DEx_FloatingActionButton, DEx_PopupMenuButton, DEx_MenuItemButton, DEx_SubmenuButton, DEx_CupertinoButton, DEx_CupertinoFilledButton | 12 |
|
|
131
|
+
| `display` | DEx_Text, DEx_Icon, DEx_Image, DEx_CircleAvatar, DEx_Card, DEx_DataTable, DEx_ListView, DEx_GridView, DEx_ListTile, DEx_ExpansionTile, DEx_ExpansionPanel, DEx_Markdown | 12 |
|
|
132
|
+
| `feedback` | DEx_ProgressBar, DEx_ProgressRing, DEx_SnackBar, DEx_AlertDialog, DEx_Banner, DEx_Tooltip, DEx_Badge, DEx_Chip, DEx_CupertinoAlertDialog, DEx_CupertinoActivityIndicator | 10 |
|
|
133
|
+
| `overlay` | DEx_BottomSheet, DEx_CupertinoBottomSheet, DEx_Drawer, DEx_SearchBar, DEx_SearchAnchor, DEx_MenuBar, DEx_Pagelet | 7 |
|
|
134
|
+
| `media` | DEx_Audio, DEx_Video, DEx_Lottie | 3 |
|
|
135
|
+
| `canvas` | DEx_Canvas | 1 |
|
|
136
|
+
| `maps` | DEx_Map | 1 |
|
|
137
|
+
| `charts` | DEx_BarChart, DEx_LineChart, DEx_PieChart | 3 |
|
|
138
|
+
| `scrolling` | DEx_ScrollableControl, DEx_DragTarget | 2 |
|
|
139
|
+
| `interaction` | DEx_GestureDetector, DEx_Draggable, DEx_Dismissible, DEx_SelectionArea, DEx_TransparentPointer | 5 |
|
|
140
|
+
| `theming` | DEx_Theme, DEx_ColorScheme | 2 |
|
|
141
|
+
| **Total** | | **84** |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Como rodar os UseCases
|
|
146
|
+
|
|
147
|
+
Os UseCases ficam na pasta `usecases/` na raiz do projeto.
|
|
148
|
+
Execute a partir da raiz do projeto (`DEx-Framework_3/`):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Grupo buttons
|
|
152
|
+
python -m usecases.buttons.UC_buttons
|
|
153
|
+
|
|
154
|
+
# Grupo layout
|
|
155
|
+
python -m usecases.layout.UC_layout
|
|
156
|
+
|
|
157
|
+
# Grupo navigation
|
|
158
|
+
python -m usecases.navigation.UC_navigation
|
|
159
|
+
|
|
160
|
+
# Grupo input
|
|
161
|
+
python -m usecases.input.UC_input
|
|
162
|
+
|
|
163
|
+
# Grupo display
|
|
164
|
+
python -m usecases.display.UC_display
|
|
165
|
+
|
|
166
|
+
# Grupo feedback
|
|
167
|
+
python -m usecases.feedback.UC_feedback
|
|
168
|
+
|
|
169
|
+
# Grupo overlay
|
|
170
|
+
python -m usecases.overlay.UC_overlay
|
|
171
|
+
|
|
172
|
+
# Grupo media
|
|
173
|
+
python -m usecases.media.UC_media
|
|
174
|
+
|
|
175
|
+
# Grupo canvas
|
|
176
|
+
python -m usecases.canvas.UC_canvas
|
|
177
|
+
|
|
178
|
+
# Grupo maps
|
|
179
|
+
python -m usecases.maps.UC_maps
|
|
180
|
+
|
|
181
|
+
# Grupo charts
|
|
182
|
+
python -m usecases.charts.UC_charts
|
|
183
|
+
|
|
184
|
+
# Grupo scrolling
|
|
185
|
+
python -m usecases.scrolling.UC_scrolling
|
|
186
|
+
|
|
187
|
+
# Grupo interaction
|
|
188
|
+
python -m usecases.interaction.UC_interaction
|
|
189
|
+
|
|
190
|
+
# Grupo theming
|
|
191
|
+
python -m usecases.theming.UC_theming
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Convenções DEx
|
|
197
|
+
|
|
198
|
+
Todos os componentes DEx seguem estas regras:
|
|
199
|
+
|
|
200
|
+
- **Herança direta** de `ft.<NomeOriginal>` — 100% da API Flet preservada
|
|
201
|
+
- **`dex_id: str`** — identificador keyword-only para rastreamento
|
|
202
|
+
- **`on_dex_ready`** — callback disparado após montagem na árvore (`did_mount`)
|
|
203
|
+
- **Type hints** em todas as assinaturas (PEP 484)
|
|
204
|
+
- **Docstrings Google Style** em toda classe e método público
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
# Todos os componentes aceitam:
|
|
208
|
+
componente = DEx_<Nome>(
|
|
209
|
+
# ... parâmetros nativos do Flet ...
|
|
210
|
+
dex_id="meu_id", # identificador único
|
|
211
|
+
on_dex_ready=lambda c: print(c.dex_id), # callback de montagem
|
|
212
|
+
)
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
*DEx-Framework v3.0.0 — gerado via Claude Code*
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# DEx-Framework v0.0.49
|
|
2
|
+
|
|
3
|
+
Biblioteca reutilizável que encapsula **todos os componentes do Flet v0.84.0**, organizada em grupos temáticos, com UseCases demonstrativos para cada grupo.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Instalação
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install flet==0.84.0
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Clone o repositório e adicione ao `PYTHONPATH` ou instale em modo editável:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
git clone <repo-url>
|
|
17
|
+
cd DEx-Framework_3
|
|
18
|
+
pip install -e .
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Uso básico
|
|
24
|
+
|
|
25
|
+
### Exemplo 1 — Botão com dex_id e callback de montagem
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
import flet as ft
|
|
29
|
+
from dex_framework import DEx_ElevatedButton
|
|
30
|
+
|
|
31
|
+
def main(page: ft.Page) -> None:
|
|
32
|
+
btn = DEx_ElevatedButton(
|
|
33
|
+
text="Salvar",
|
|
34
|
+
dex_id="btn_salvar",
|
|
35
|
+
on_click=lambda e: print("clicou"),
|
|
36
|
+
on_dex_ready=lambda c: print(f"{c.dex_id} montado"),
|
|
37
|
+
)
|
|
38
|
+
page.add(btn)
|
|
39
|
+
|
|
40
|
+
ft.app(target=main)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Exemplo 2 — Layout responsivo
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
import flet as ft
|
|
47
|
+
from dex_framework import DEx_ResponsiveRow, DEx_Container, DEx_Text
|
|
48
|
+
|
|
49
|
+
def main(page: ft.Page) -> None:
|
|
50
|
+
row = DEx_ResponsiveRow(
|
|
51
|
+
dex_id="row_principal",
|
|
52
|
+
controls=[
|
|
53
|
+
DEx_Container(
|
|
54
|
+
col={"sm": 12, "md": 6},
|
|
55
|
+
content=DEx_Text("Coluna esquerda", dex_id="txt_esq"),
|
|
56
|
+
bgcolor=ft.Colors.BLUE_50,
|
|
57
|
+
padding=16,
|
|
58
|
+
),
|
|
59
|
+
DEx_Container(
|
|
60
|
+
col={"sm": 12, "md": 6},
|
|
61
|
+
content=DEx_Text("Coluna direita", dex_id="txt_dir"),
|
|
62
|
+
bgcolor=ft.Colors.GREEN_50,
|
|
63
|
+
padding=16,
|
|
64
|
+
),
|
|
65
|
+
],
|
|
66
|
+
)
|
|
67
|
+
page.add(row)
|
|
68
|
+
|
|
69
|
+
ft.app(target=main)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Exemplo 3 — Tema customizado
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import flet as ft
|
|
76
|
+
from dex_framework import DEx_Theme, DEx_ColorScheme
|
|
77
|
+
|
|
78
|
+
def main(page: ft.Page) -> None:
|
|
79
|
+
page.theme = DEx_Theme(
|
|
80
|
+
color_scheme_seed=ft.Colors.INDIGO,
|
|
81
|
+
color_scheme=DEx_ColorScheme(
|
|
82
|
+
primary=ft.Colors.INDIGO,
|
|
83
|
+
secondary=ft.Colors.TEAL,
|
|
84
|
+
dex_id="esquema_app",
|
|
85
|
+
),
|
|
86
|
+
dex_id="tema_app",
|
|
87
|
+
)
|
|
88
|
+
page.add(ft.Text("App com tema DEx!", size=24))
|
|
89
|
+
|
|
90
|
+
ft.app(target=main)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Estrutura de grupos
|
|
96
|
+
|
|
97
|
+
| Grupo | Componentes | Quantidade |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `layout` | DEx_Row, DEx_Column, DEx_Stack, DEx_Container, DEx_ResponsiveRow, DEx_SafeArea | 6 |
|
|
100
|
+
| `navigation` | DEx_AppBar, DEx_NavigationBar, DEx_NavigationRail, DEx_NavigationDrawer, DEx_Tabs, DEx_CupertinoNavigationBar | 6 |
|
|
101
|
+
| `input` | DEx_TextField, DEx_Dropdown, DEx_Checkbox, DEx_Radio, DEx_RadioGroup, DEx_Switch, DEx_Slider, DEx_RangeSlider, DEx_DatePicker, DEx_TimePicker, DEx_CupertinoTextField, DEx_CupertinoCheckbox, DEx_CupertinoSlider, DEx_CupertinoSwitch | 14 |
|
|
102
|
+
| `buttons` | DEx_ElevatedButton, DEx_FilledButton, DEx_FilledTonalButton, DEx_OutlinedButton, DEx_TextButton, DEx_IconButton, DEx_FloatingActionButton, DEx_PopupMenuButton, DEx_MenuItemButton, DEx_SubmenuButton, DEx_CupertinoButton, DEx_CupertinoFilledButton | 12 |
|
|
103
|
+
| `display` | DEx_Text, DEx_Icon, DEx_Image, DEx_CircleAvatar, DEx_Card, DEx_DataTable, DEx_ListView, DEx_GridView, DEx_ListTile, DEx_ExpansionTile, DEx_ExpansionPanel, DEx_Markdown | 12 |
|
|
104
|
+
| `feedback` | DEx_ProgressBar, DEx_ProgressRing, DEx_SnackBar, DEx_AlertDialog, DEx_Banner, DEx_Tooltip, DEx_Badge, DEx_Chip, DEx_CupertinoAlertDialog, DEx_CupertinoActivityIndicator | 10 |
|
|
105
|
+
| `overlay` | DEx_BottomSheet, DEx_CupertinoBottomSheet, DEx_Drawer, DEx_SearchBar, DEx_SearchAnchor, DEx_MenuBar, DEx_Pagelet | 7 |
|
|
106
|
+
| `media` | DEx_Audio, DEx_Video, DEx_Lottie | 3 |
|
|
107
|
+
| `canvas` | DEx_Canvas | 1 |
|
|
108
|
+
| `maps` | DEx_Map | 1 |
|
|
109
|
+
| `charts` | DEx_BarChart, DEx_LineChart, DEx_PieChart | 3 |
|
|
110
|
+
| `scrolling` | DEx_ScrollableControl, DEx_DragTarget | 2 |
|
|
111
|
+
| `interaction` | DEx_GestureDetector, DEx_Draggable, DEx_Dismissible, DEx_SelectionArea, DEx_TransparentPointer | 5 |
|
|
112
|
+
| `theming` | DEx_Theme, DEx_ColorScheme | 2 |
|
|
113
|
+
| **Total** | | **84** |
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Como rodar os UseCases
|
|
118
|
+
|
|
119
|
+
Os UseCases ficam na pasta `usecases/` na raiz do projeto.
|
|
120
|
+
Execute a partir da raiz do projeto (`DEx-Framework_3/`):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Grupo buttons
|
|
124
|
+
python -m usecases.buttons.UC_buttons
|
|
125
|
+
|
|
126
|
+
# Grupo layout
|
|
127
|
+
python -m usecases.layout.UC_layout
|
|
128
|
+
|
|
129
|
+
# Grupo navigation
|
|
130
|
+
python -m usecases.navigation.UC_navigation
|
|
131
|
+
|
|
132
|
+
# Grupo input
|
|
133
|
+
python -m usecases.input.UC_input
|
|
134
|
+
|
|
135
|
+
# Grupo display
|
|
136
|
+
python -m usecases.display.UC_display
|
|
137
|
+
|
|
138
|
+
# Grupo feedback
|
|
139
|
+
python -m usecases.feedback.UC_feedback
|
|
140
|
+
|
|
141
|
+
# Grupo overlay
|
|
142
|
+
python -m usecases.overlay.UC_overlay
|
|
143
|
+
|
|
144
|
+
# Grupo media
|
|
145
|
+
python -m usecases.media.UC_media
|
|
146
|
+
|
|
147
|
+
# Grupo canvas
|
|
148
|
+
python -m usecases.canvas.UC_canvas
|
|
149
|
+
|
|
150
|
+
# Grupo maps
|
|
151
|
+
python -m usecases.maps.UC_maps
|
|
152
|
+
|
|
153
|
+
# Grupo charts
|
|
154
|
+
python -m usecases.charts.UC_charts
|
|
155
|
+
|
|
156
|
+
# Grupo scrolling
|
|
157
|
+
python -m usecases.scrolling.UC_scrolling
|
|
158
|
+
|
|
159
|
+
# Grupo interaction
|
|
160
|
+
python -m usecases.interaction.UC_interaction
|
|
161
|
+
|
|
162
|
+
# Grupo theming
|
|
163
|
+
python -m usecases.theming.UC_theming
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Convenções DEx
|
|
169
|
+
|
|
170
|
+
Todos os componentes DEx seguem estas regras:
|
|
171
|
+
|
|
172
|
+
- **Herança direta** de `ft.<NomeOriginal>` — 100% da API Flet preservada
|
|
173
|
+
- **`dex_id: str`** — identificador keyword-only para rastreamento
|
|
174
|
+
- **`on_dex_ready`** — callback disparado após montagem na árvore (`did_mount`)
|
|
175
|
+
- **Type hints** em todas as assinaturas (PEP 484)
|
|
176
|
+
- **Docstrings Google Style** em toda classe e método público
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
# Todos os componentes aceitam:
|
|
180
|
+
componente = DEx_<Nome>(
|
|
181
|
+
# ... parâmetros nativos do Flet ...
|
|
182
|
+
dex_id="meu_id", # identificador único
|
|
183
|
+
on_dex_ready=lambda c: print(c.dex_id), # callback de montagem
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
*DEx-Framework v3.0.0 — gerado via Claude Code*
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DEx-Framework v3.0.0
|
|
3
|
+
Biblioteca reutilizável que encapsula todos os componentes do Flet v0.84.0.
|
|
4
|
+
|
|
5
|
+
Uso básico:
|
|
6
|
+
from dex_framework import DEx_ElevatedButton, DEx_TextField, DEx_Column
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .layout import *
|
|
10
|
+
from .navigation import *
|
|
11
|
+
from .input import *
|
|
12
|
+
from .buttons import *
|
|
13
|
+
from .display import *
|
|
14
|
+
from .feedback import *
|
|
15
|
+
from .overlay import *
|
|
16
|
+
from .media import *
|
|
17
|
+
from .canvas import *
|
|
18
|
+
from .maps import *
|
|
19
|
+
from .charts import *
|
|
20
|
+
from .scrolling import *
|
|
21
|
+
from .interaction import *
|
|
22
|
+
from .theming import *
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"""DEx_ActionButtons — barra de botões de ação direita-para-esquerda."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
from typing import Callable
|
|
5
|
+
import flet as ft
|
|
6
|
+
from dex_framework.theming.DEx_BrandThemes import DEx_BrandTheme
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DEx_ActionButton:
|
|
10
|
+
"""
|
|
11
|
+
Define um botão individual para uso em DEx_ActionButtons.
|
|
12
|
+
|
|
13
|
+
Params
|
|
14
|
+
------
|
|
15
|
+
icon : ícone do botão (opcional se text fornecido; obrigatório se sem text)
|
|
16
|
+
text : rótulo do botão (opcional)
|
|
17
|
+
tooltip : dica de contexto
|
|
18
|
+
on_click : callback de clique
|
|
19
|
+
disabled : botão desabilitado
|
|
20
|
+
button_type : tipo pré-definido — "exit" | "theme" | "brightness" | "user"
|
|
21
|
+
define ícone padrão e comportamento embutido quando page é fornecido
|
|
22
|
+
|
|
23
|
+
Ícones e comportamentos padrão por tipo
|
|
24
|
+
----------------------------------------
|
|
25
|
+
exit → ft.Icons.LOGOUT — fecha a janela
|
|
26
|
+
theme → ft.Icons.PALETTE — cicla entre temas por nome de marca
|
|
27
|
+
brightness → ft.Icons.BRIGHTNESS_6 — alterna entre modo claro e escuro
|
|
28
|
+
user → ft.Icons.ACCOUNT_CIRCLE — nasce como readonly (disabled=True)
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
_DEFAULT_ICONS: dict = {
|
|
32
|
+
"exit": ft.Icons.LOGOUT,
|
|
33
|
+
"theme": ft.Icons.PALETTE,
|
|
34
|
+
"brightness": ft.Icons.BRIGHTNESS_6,
|
|
35
|
+
"user": ft.Icons.ACCOUNT_CIRCLE,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
icon: ft.IconData | None = None,
|
|
41
|
+
text: str | None = None,
|
|
42
|
+
tooltip: str | None = None,
|
|
43
|
+
on_click: Callable | None = None,
|
|
44
|
+
disabled: bool = False,
|
|
45
|
+
visible: bool = True,
|
|
46
|
+
button_type: str | None = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
self.button_type = button_type
|
|
49
|
+
self.text = text
|
|
50
|
+
self.icon = icon if icon is not None else self._DEFAULT_ICONS.get(button_type)
|
|
51
|
+
self.tooltip = tooltip
|
|
52
|
+
self.on_click = on_click
|
|
53
|
+
self.visible = visible
|
|
54
|
+
# "user" nasce como readonly salvo on_click explícito
|
|
55
|
+
self.disabled = disabled or (button_type == "user" and on_click is None)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class DEx_ActionButtons(ft.Container):
|
|
59
|
+
"""
|
|
60
|
+
Barra de botões de ação alinhada à direita, com quebra automática de linha.
|
|
61
|
+
|
|
62
|
+
Os botões são apresentados da direita para a esquerda conforme a ordem de
|
|
63
|
+
criação: o primeiro botão da lista aparece mais à direita. Quando o total
|
|
64
|
+
de botões ultrapassa a largura disponível, uma segunda linha é criada com
|
|
65
|
+
o mesmo alinhamento.
|
|
66
|
+
|
|
67
|
+
O container_main (exposto publicamente) não é expansível — seu tamanho é
|
|
68
|
+
determinado pelo conteúdo.
|
|
69
|
+
|
|
70
|
+
Params
|
|
71
|
+
------
|
|
72
|
+
buttons : lista de DEx_ActionButton
|
|
73
|
+
page : referência à ft.Page (necessário para ações embutidas exit/theme)
|
|
74
|
+
dex_id, dex_theme, on_dex_ready : padrão DEx
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# Ordem canônica de todas as marcas para o ciclo de temas
|
|
78
|
+
_ALL_BRANDS: list[str] = [
|
|
79
|
+
brand
|
|
80
|
+
for brands in DEx_BrandTheme.BRAND_GROUPS.values()
|
|
81
|
+
for brand in brands
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
buttons: list[DEx_ActionButton] | None = None,
|
|
87
|
+
page: ft.Page | None = None,
|
|
88
|
+
dex_id: str = "",
|
|
89
|
+
dex_theme: str = "dell",
|
|
90
|
+
on_dex_ready: Callable | None = None,
|
|
91
|
+
**kwargs,
|
|
92
|
+
) -> None:
|
|
93
|
+
self.dex_id: str = dex_id
|
|
94
|
+
self.dex_theme: str = dex_theme
|
|
95
|
+
# Desembrulha _UCProxy (hub) para sempre guardar a ft.Page real.
|
|
96
|
+
# getattr(proxy, "_real", proxy) funciona porque _UCProxy armazena
|
|
97
|
+
# "_real" via super().__setattr__, logo __getattr__ não é chamado.
|
|
98
|
+
self._page = getattr(page, "_real", page) if page is not None else None
|
|
99
|
+
# -1 → primeira clicada vai sempre para índice 0 (bradesco, vermelho),
|
|
100
|
+
# garantindo contraste visual imediato independente do dex_theme inicial.
|
|
101
|
+
self._theme_idx: int = -1
|
|
102
|
+
self._theme_widget: ft.IconButton | None = None
|
|
103
|
+
self._brightness_widget: ft.IconButton | None = None
|
|
104
|
+
|
|
105
|
+
# Inverte a lista para que o 1º definido fique mais à direita
|
|
106
|
+
btn_list = list(buttons or [])
|
|
107
|
+
widgets = [self._build_widget(btn) for btn in reversed(btn_list)]
|
|
108
|
+
|
|
109
|
+
self.container_main = ft.Container(
|
|
110
|
+
content=ft.Row(
|
|
111
|
+
controls=widgets,
|
|
112
|
+
wrap=True,
|
|
113
|
+
alignment=ft.MainAxisAlignment.END,
|
|
114
|
+
tight=True,
|
|
115
|
+
spacing=4,
|
|
116
|
+
run_spacing=4,
|
|
117
|
+
),
|
|
118
|
+
padding=ft.Padding.symmetric(horizontal=4, vertical=4),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
super().__init__(content=self.container_main, **kwargs)
|
|
122
|
+
|
|
123
|
+
if on_dex_ready:
|
|
124
|
+
on_dex_ready(self)
|
|
125
|
+
|
|
126
|
+
# ── Resolução de clique ────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
def _resolve_click(self, btn: DEx_ActionButton) -> Callable | None:
|
|
129
|
+
if btn.on_click:
|
|
130
|
+
return btn.on_click
|
|
131
|
+
if self._page is None:
|
|
132
|
+
return None
|
|
133
|
+
if btn.button_type == "exit":
|
|
134
|
+
return self._do_exit
|
|
135
|
+
if btn.button_type == "theme":
|
|
136
|
+
return self._next_theme
|
|
137
|
+
if btn.button_type == "brightness":
|
|
138
|
+
return self._toggle_brightness
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
async def _do_exit(self, e) -> None:
|
|
142
|
+
if self._page:
|
|
143
|
+
await self._page.window.close()
|
|
144
|
+
|
|
145
|
+
def _toggle_brightness(self, e) -> None:
|
|
146
|
+
if self._page is None:
|
|
147
|
+
return
|
|
148
|
+
is_dark = self._page.theme_mode == ft.ThemeMode.DARK
|
|
149
|
+
self._page.theme_mode = ft.ThemeMode.LIGHT if is_dark else ft.ThemeMode.DARK
|
|
150
|
+
# Atualiza ícone e tooltip para refletir o novo estado
|
|
151
|
+
if self._brightness_widget is not None:
|
|
152
|
+
if self._page.theme_mode == ft.ThemeMode.DARK:
|
|
153
|
+
self._brightness_widget.icon = ft.Icons.BRIGHTNESS_2
|
|
154
|
+
self._brightness_widget.tooltip = "Modo escuro (clique para claro)"
|
|
155
|
+
else:
|
|
156
|
+
self._brightness_widget.icon = ft.Icons.BRIGHTNESS_HIGH
|
|
157
|
+
self._brightness_widget.tooltip = "Modo claro (clique para escuro)"
|
|
158
|
+
self._brightness_widget.update()
|
|
159
|
+
self._page.update()
|
|
160
|
+
|
|
161
|
+
def _next_theme(self, e) -> None:
|
|
162
|
+
self._theme_idx = (self._theme_idx + 1) % len(self._ALL_BRANDS)
|
|
163
|
+
brand = self._ALL_BRANDS[self._theme_idx]
|
|
164
|
+
|
|
165
|
+
# Atualiza tooltip com grupo e nome da marca
|
|
166
|
+
if self._theme_widget is not None:
|
|
167
|
+
group = next(
|
|
168
|
+
(g for g, brands in DEx_BrandTheme.BRAND_GROUPS.items() if brand in brands),
|
|
169
|
+
"",
|
|
170
|
+
)
|
|
171
|
+
group_label = DEx_BrandTheme.GROUP_META.get(group, {}).get("label", group)
|
|
172
|
+
brand_display = brand.replace("_", " ").title()
|
|
173
|
+
self._theme_widget.tooltip = f"{group_label} · {brand_display}"
|
|
174
|
+
self._theme_widget.update()
|
|
175
|
+
|
|
176
|
+
if self._page:
|
|
177
|
+
DEx_BrandTheme.apply(self._page, brand)
|
|
178
|
+
|
|
179
|
+
# ── Construção de widget por botão ─────────────────────────────────
|
|
180
|
+
|
|
181
|
+
def _build_widget(self, btn: DEx_ActionButton) -> ft.Control:
|
|
182
|
+
on_click = self._resolve_click(btn)
|
|
183
|
+
|
|
184
|
+
if btn.text:
|
|
185
|
+
if btn.icon:
|
|
186
|
+
content = ft.Row(
|
|
187
|
+
[ft.Icon(btn.icon, size=16), ft.Text(btn.text, size=12)],
|
|
188
|
+
spacing=4,
|
|
189
|
+
tight=True,
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
content = ft.Text(btn.text, size=12)
|
|
193
|
+
return ft.Button(
|
|
194
|
+
content=content,
|
|
195
|
+
tooltip=btn.tooltip,
|
|
196
|
+
on_click=on_click,
|
|
197
|
+
disabled=btn.disabled,
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
widget = ft.IconButton(
|
|
201
|
+
icon=btn.icon or ft.Icons.RADIO_BUTTON_UNCHECKED,
|
|
202
|
+
tooltip=btn.tooltip,
|
|
203
|
+
on_click=on_click,
|
|
204
|
+
disabled=btn.disabled,
|
|
205
|
+
visible=btn.visible,
|
|
206
|
+
icon_size=20,
|
|
207
|
+
)
|
|
208
|
+
if btn.button_type == "theme":
|
|
209
|
+
self._theme_widget = widget
|
|
210
|
+
if btn.button_type == "brightness":
|
|
211
|
+
self._brightness_widget = widget
|
|
212
|
+
return widget
|