From 102529b95129f34e836239147b9fe87aebb4d1bd Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 21 Jan 2025 22:14:36 -0800 Subject: [PATCH 01/81] snackbar --- python/controls/snack-bar/simple-snack.py | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/python/controls/snack-bar/simple-snack.py b/python/controls/snack-bar/simple-snack.py index 7b8656be..064c28e3 100644 --- a/python/controls/snack-bar/simple-snack.py +++ b/python/controls/snack-bar/simple-snack.py @@ -1,7 +1,6 @@ import logging +import flet as ft -import flet -from flet import ElevatedButton, SnackBar, Text logging.basicConfig(level=logging.DEBUG) @@ -10,26 +9,30 @@ class Data: def __init__(self) -> None: self.counter = 0 + def increment(self): + self.counter += 1 + + def decrement(self): + self.counter -= 1 + d = Data() def main(page): - - page.snack_bar = SnackBar( - content=Text("Hello, world!"), - # remove_current_snackbar=True, - action="Alright!", + page.snack_bar = ft.SnackBar( + content=ft.Text(f"You did it!"), + action="Undo it!", + on_action=lambda e: d.decrement(), ) def on_click(e): - # page.snack_bar.content.value = f"Hello, world: {d.counter}" - page.snack_bar = SnackBar(Text(f"Hello {d.counter}")) + d.increment() + page.snack_bar.content.value = f"You did it x {d.counter}" page.snack_bar.open = True - d.counter += 1 page.update() - page.add(ElevatedButton("Open SnackBar", on_click=on_click)) + page.add(ft.ElevatedButton("Open SnackBar", on_click=on_click)) -flet.app(target=main) +ft.app(main) From bc5a0d82802d446c08d25e98184c81b18613115e Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 08:04:40 -0800 Subject: [PATCH 02/81] alert-dialog --- python/controls/alert-dialog/dialogs.py | 32 ++++++++++++++----------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/python/controls/alert-dialog/dialogs.py b/python/controls/alert-dialog/dialogs.py index ba64b045..68995549 100644 --- a/python/controls/alert-dialog/dialogs.py +++ b/python/controls/alert-dialog/dialogs.py @@ -4,14 +4,28 @@ def main(page: ft.Page): page.title = "AlertDialog examples" - dlg = ft.AlertDialog( - title=ft.Text("Hello, you!"), on_dismiss=lambda e: print("Dialog dismissed!") - ) + def open_dlg(e): + page.overlay.append(dlg) + dlg.open = True + page.update() + + def open_dlg_modal(e): + page.overlay.append(dlg_modal) + dlg_modal.open = True + page.update() def close_dlg(e): dlg_modal.open = False page.update() + dlg = ft.AlertDialog( + title=ft.Text("Hello"), + content=ft.Text("You are notified!"), + alignment=ft.alignment.center, + on_dismiss=lambda e: print("Dialog dismissed!"), + title_padding=ft.padding.all(25), + ) + dlg_modal = ft.AlertDialog( modal=True, title=ft.Text("Please confirm"), @@ -24,20 +38,10 @@ def close_dlg(e): on_dismiss=lambda e: print("Modal dialog dismissed!"), ) - def open_dlg(e): - page.dialog = dlg - dlg.open = True - page.update() - - def open_dlg_modal(e): - page.dialog = dlg_modal - dlg_modal.open = True - page.update() - page.add( ft.ElevatedButton("Open dialog", on_click=open_dlg), ft.ElevatedButton("Open modal dialog", on_click=open_dlg_modal), ) -ft.app(target=main) +ft.app(main) From c9a005e921842d719123905b5f56ad2ef39f29a2 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 08:38:02 -0800 Subject: [PATCH 03/81] animated switcher --- .../controls/animation/animated-switcher.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/python/controls/animation/animated-switcher.py b/python/controls/animation/animated-switcher.py index 0c770d02..286e8459 100644 --- a/python/controls/animation/animated-switcher.py +++ b/python/controls/animation/animated-switcher.py @@ -4,18 +4,18 @@ def main(page: ft.Page): c1 = ft.Container( - ft.Text("Hello!", style=ft.TextThemeStyle.HEADLINE_MEDIUM), + ft.Text("Hello!", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM), alignment=ft.alignment.center, width=200, height=200, - bgcolor=ft.colors.GREEN, + bgcolor=ft.Colors.GREEN, ) c2 = ft.Container( ft.Text("Bye!", size=50), alignment=ft.alignment.center, width=200, height=200, - bgcolor=ft.colors.YELLOW, + bgcolor=ft.Colors.YELLOW, ) c = ft.AnimatedSwitcher( c1, @@ -26,14 +26,27 @@ def main(page: ft.Page): switch_out_curve=ft.AnimationCurve.BOUNCE_IN, ) - def animate(e): + def scale(e): c.content = c2 if c.content == c1 else c1 + c.transition = ft.AnimatedSwitcherTransition.SCALE + c.update() + + def fade(e): + c.content = c2 if c.content == c1 else c1 + c.transition = ft.AnimatedSwitcherTransition.FADE + c.update() + + def rotate(e): + c.content = c2 if c.content == c1 else c1 + c.transition = ft.AnimatedSwitcherTransition.ROTATION c.update() page.add( c, - ft.ElevatedButton("Animate!", on_click=animate), + ft.ElevatedButton("Scale", on_click=scale), + ft.ElevatedButton("Fade", on_click=fade), + ft.ElevatedButton("Rotate", on_click=rotate), ) -ft.app(target=main) +ft.app(main) From 34fec8c7ff2668410f3e1f5a2f7e7dd4c9649863 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 10:35:38 -0800 Subject: [PATCH 04/81] update snackbar --- python/controls/snack-bar/simple-snack.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/controls/snack-bar/simple-snack.py b/python/controls/snack-bar/simple-snack.py index 064c28e3..c9648c31 100644 --- a/python/controls/snack-bar/simple-snack.py +++ b/python/controls/snack-bar/simple-snack.py @@ -20,7 +20,7 @@ def decrement(self): def main(page): - page.snack_bar = ft.SnackBar( + sb = ft.SnackBar( content=ft.Text(f"You did it!"), action="Undo it!", on_action=lambda e: d.decrement(), @@ -28,8 +28,8 @@ def main(page): def on_click(e): d.increment() - page.snack_bar.content.value = f"You did it x {d.counter}" - page.snack_bar.open = True + sb.content.value = f"You did it x {d.counter}" + page.open(sb) page.update() page.add(ft.ElevatedButton("Open SnackBar", on_click=on_click)) From 0cd4844e954dc15e8fdedff2779365d7c9e25db6 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 10:54:58 -0800 Subject: [PATCH 05/81] update dialogs, add titles --- python/controls/alert-dialog/dialogs.py | 22 ++++--------------- .../controls/animation/animated-switcher.py | 1 + python/controls/snack-bar/simple-snack.py | 2 ++ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/python/controls/alert-dialog/dialogs.py b/python/controls/alert-dialog/dialogs.py index 68995549..56851a06 100644 --- a/python/controls/alert-dialog/dialogs.py +++ b/python/controls/alert-dialog/dialogs.py @@ -4,20 +4,6 @@ def main(page: ft.Page): page.title = "AlertDialog examples" - def open_dlg(e): - page.overlay.append(dlg) - dlg.open = True - page.update() - - def open_dlg_modal(e): - page.overlay.append(dlg_modal) - dlg_modal.open = True - page.update() - - def close_dlg(e): - dlg_modal.open = False - page.update() - dlg = ft.AlertDialog( title=ft.Text("Hello"), content=ft.Text("You are notified!"), @@ -31,16 +17,16 @@ def close_dlg(e): title=ft.Text("Please confirm"), content=ft.Text("Do you really want to delete all those files?"), actions=[ - ft.TextButton("Yes", on_click=close_dlg), - ft.TextButton("No", on_click=close_dlg), + ft.TextButton("Yes", on_click=lambda e: page.close(dlg_modal)), + ft.TextButton("No", on_click=lambda e: page.close(dlg_modal)), ], actions_alignment=ft.MainAxisAlignment.END, on_dismiss=lambda e: print("Modal dialog dismissed!"), ) page.add( - ft.ElevatedButton("Open dialog", on_click=open_dlg), - ft.ElevatedButton("Open modal dialog", on_click=open_dlg_modal), + ft.ElevatedButton("Open dialog", on_click=lambda e: page.open(dlg)), + ft.ElevatedButton("Open modal dialog", on_click=lambda e: page.open(dlg_modal)), ) diff --git a/python/controls/animation/animated-switcher.py b/python/controls/animation/animated-switcher.py index 286e8459..e1d22d9c 100644 --- a/python/controls/animation/animated-switcher.py +++ b/python/controls/animation/animated-switcher.py @@ -2,6 +2,7 @@ def main(page: ft.Page): + page.title = "AnimatedSwitcher examples" c1 = ft.Container( ft.Text("Hello!", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM), diff --git a/python/controls/snack-bar/simple-snack.py b/python/controls/snack-bar/simple-snack.py index c9648c31..f77d02ca 100644 --- a/python/controls/snack-bar/simple-snack.py +++ b/python/controls/snack-bar/simple-snack.py @@ -20,6 +20,8 @@ def decrement(self): def main(page): + page.title = "SnackBar examples" + sb = ft.SnackBar( content=ft.Text(f"You did it!"), action="Undo it!", From c81e18e4d86d9b322b49aafd0877ffb8813b10a9 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 14:14:35 -0800 Subject: [PATCH 06/81] appbar --- python/controls/appbar/appbar-simple.py | 42 ++++++++++--------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/python/controls/appbar/appbar-simple.py b/python/controls/appbar/appbar-simple.py index 43275541..31cc28b6 100644 --- a/python/controls/appbar/appbar-simple.py +++ b/python/controls/appbar/appbar-simple.py @@ -1,44 +1,34 @@ -import flet -from flet import ( - AppBar, - Icon, - IconButton, - Page, - PopupMenuButton, - PopupMenuItem, - Text, - colors, - icons, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): + page.title = "AppBar Example" + def check_item_clicked(e): e.control.checked = not e.control.checked page.update() - page.title = "AppBar Example" - page.appbar = AppBar( - leading=Icon(icons.PALETTE), + page.appbar = ft.AppBar( + leading=ft.Icon(ft.Icons.PALETTE), leading_width=40, - title=Text("AppBar Example"), + title=ft.Text("AppBar Example"), center_title=False, - bgcolor=colors.SURFACE_VARIANT, + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, actions=[ - IconButton(icons.WB_SUNNY_OUTLINED), - IconButton(icons.FILTER_3), - PopupMenuButton( + ft.IconButton(ft.Icons.WB_SUNNY_OUTLINED), + ft.IconButton(ft.Icons.FILTER_3), + ft.PopupMenuButton( items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(), # divider - PopupMenuItem( + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(), # divider + ft.PopupMenuItem( text="Checked item", checked=False, on_click=check_item_clicked ), ] ), ], ) - page.add(Text("Body!")) + page.add(ft.Text("Body!")) -flet.app(target=main) +ft.app(target=main) From 90b21a7a06349eaaa9ec3683f9dba29e95e5e7d6 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 22 Jan 2025 23:09:47 -0800 Subject: [PATCH 07/81] update appbar-theme-material --- .../controls/appbar/appbar-theme-material.py | 91 +++++++++---------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/python/controls/appbar/appbar-theme-material.py b/python/controls/appbar/appbar-theme-material.py index baf51869..72f9ecbe 100644 --- a/python/controls/appbar/appbar-theme-material.py +++ b/python/controls/appbar/appbar-theme-material.py @@ -1,101 +1,100 @@ from time import sleep -import flet -from flet import ( - AppBar, - ElevatedButton, - Icon, - IconButton, - Page, - PopupMenuButton, - PopupMenuItem, - Row, - Text, - colors, - icons, - theme, -) +import flet as ft -LIGHT_SEED_COLOR = colors.DEEP_ORANGE -DARK_SEED_COLOR = colors.INDIGO +LIGHT_SEED_COLOR = ft.Colors.DEEP_ORANGE +DARK_SEED_COLOR = ft.Colors.DEEP_PURPLE -def main(page: Page): +def main(page: ft.Page): + page.title = "AppBar Example" + def check_item_clicked(e): e.control.checked = not e.control.checked page.update() - page.title = "AppBar Example" - page.theme_mode = "light" - page.theme = theme.Theme(color_scheme_seed=LIGHT_SEED_COLOR, use_material3=True) - page.dark_theme = theme.Theme(color_scheme_seed=DARK_SEED_COLOR, use_material3=True) + page.theme_mode = ft.ThemeMode.LIGHT + page.theme = ft.Theme(color_scheme_seed=LIGHT_SEED_COLOR, use_material3=True) + page.dark_theme = ft.Theme(color_scheme_seed=DARK_SEED_COLOR, use_material3=True) page.update() def toggle_theme_mode(e): - page.theme_mode = "dark" if page.theme_mode == "light" else "light" + page.theme_mode = ( + ft.ThemeMode.DARK + if page.theme_mode == ft.ThemeMode.LIGHT + else ft.ThemeMode.LIGHT + ) lightMode.icon = ( - icons.WB_SUNNY_OUTLINED if page.theme_mode == "light" else icons.WB_SUNNY + ft.Icons.WB_SUNNY_OUTLINED + if page.theme_mode == "light" + else ft.Icons.WB_SUNNY ) page.update() - lightMode = IconButton( - icons.WB_SUNNY_OUTLINED if page.theme_mode == "light" else icons.WB_SUNNY, + lightMode = ft.IconButton( + ft.Icons.WB_SUNNY_OUTLINED if page.theme_mode == "light" else ft.Icons.WB_SUNNY, on_click=toggle_theme_mode, ) def toggle_material(e): use_material3 = not page.theme.use_material3 - page.theme = theme.Theme( + page.theme = ft.Theme( color_scheme_seed=LIGHT_SEED_COLOR, use_material3=use_material3 ) - page.dark_theme = theme.Theme( + page.dark_theme = ft.Theme( color_scheme_seed=DARK_SEED_COLOR, use_material3=use_material3 ) materialMode.icon = ( - icons.FILTER_3 if page.theme.use_material3 else icons.FILTER_2 + ft.Icons.FILTER_3 if page.theme.use_material3 else ft.Icons.FILTER_2 ) page.update() - materialMode = IconButton( - icons.FILTER_3 if page.theme.use_material3 else icons.FILTER_2, + materialMode = ft.IconButton( + ft.Icons.FILTER_3 if page.theme.use_material3 else ft.Icons.FILTER_2, on_click=toggle_material, ) page.padding = 50 - page.appbar = AppBar( + page.appbar = ft.AppBar( # toolbar_height=100, - # bgcolor=colors.SECONDARY_CONTAINER, - leading=Icon(icons.PALETTE), + bgcolor=ft.Colors.SECONDARY_CONTAINER, + leading=ft.Icon(ft.Icons.PALETTE), leading_width=40, - title=Text("AppBar Example"), + title=ft.Text("AppBar Example"), center_title=False, actions=[ lightMode, materialMode, - PopupMenuButton( + ft.PopupMenuButton( items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(icon=icons.POWER_INPUT, text="Check power"), - PopupMenuItem( - content=Row( + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(icon=ft.Icons.POWER_INPUT, text="Check power"), + ft.PopupMenuItem( + content=ft.Row( [ - Icon(icons.HOURGLASS_TOP_OUTLINED), - Text("Item with a custom content"), + ft.Icon(ft.Icons.HOURGLASS_TOP_OUTLINED), + ft.Text("Item with a custom content"), ] ), on_click=lambda _: print( "Button with a custom content clicked!" ), ), - PopupMenuItem(), # divider - PopupMenuItem( + ft.PopupMenuItem(), # divider + ft.PopupMenuItem( text="Checked item", checked=False, on_click=check_item_clicked ), ] ), ], ) - page.add(Text("Body!"), ElevatedButton("Click me!")) + page.add( + ft.Text( + "Flet is a framework that allows building web, desktop and mobile applications in Python without prior experience in frontend development.You can build a UI for your program with Flet controls which are based on Flutter by Google. Flet goes beyond merely wrapping Flutter widgets. It adds its own touch by combining smaller widgets, simplifying complexities, implementing UI best practices, and applying sensible defaults. This ensures that your applications look stylish and polished without requiring additional design efforts on your part.", + text_align=ft.TextAlign.END, + ), + ft.ElevatedButton("Click me!"), + ) -flet.app(target=main) +ft.app(main) From 3948bf5fa727a5c24708400ba22e6557a890e4a7 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 23 Jan 2025 13:43:02 -0800 Subject: [PATCH 08/81] audio examples update --- python/controls/audio/audio-autoplay.py | 33 ++++++++++++++------- python/controls/audio/audio-player-async.py | 29 ++++++++++-------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/python/controls/audio/audio-autoplay.py b/python/controls/audio/audio-autoplay.py index be9405a1..091072ef 100644 --- a/python/controls/audio/audio-autoplay.py +++ b/python/controls/audio/audio-autoplay.py @@ -1,16 +1,29 @@ -import flet -from flet import Audio, ElevatedButton, Page, Text +import flet as ft -def main(page: Page): - audio1 = Audio( - src="https://luan.xyz/files/audio/ambient_c_motion.mp3", autoplay=True +def main(page: ft.Page): + page.title = "Audio Example" + + def change_button(e): + if e.state == ft.AudioState.PAUSED: + b.text = "Resume playing" + b.on_click = lambda e: audio1.resume() + + elif e.state == ft.AudioState.PLAYING: + b.text = "Pause playing" + b.on_click = lambda e: audio1.pause() + + b.update() + + audio1 = ft.Audio( + src="https://luan.xyz/files/audio/ambient_c_motion.mp3", + autoplay=True, + on_state_changed=change_button, ) + b = ft.ElevatedButton("Pause playing", on_click=lambda _: audio1.pause()) + page.overlay.append(audio1) - page.add( - Text("This is an app with background audio."), - ElevatedButton("Stop playing", on_click=lambda _: audio1.pause()), - ) + page.add(ft.Text("This is an app with background audio."), b) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/audio/audio-player-async.py b/python/controls/audio/audio-player-async.py index cf9fbecb..d1b82e24 100644 --- a/python/controls/audio/audio-player-async.py +++ b/python/controls/audio/audio-player-async.py @@ -7,37 +7,40 @@ async def main(page: ft.Page): async def volume_down(_): audio1.volume -= 0.1 - await audio1.update_async() + audio1.update() async def volume_up(_): audio1.volume += 0.1 - await audio1.update_async() + audio1.update() async def balance_left(_): audio1.balance -= 0.1 - await audio1.update_async() + audio1.update() async def balance_right(_): audio1.balance += 0.1 - await audio1.update_async() + audio1.update() async def play(_): - await audio1.play_async() + audio1.play() async def pause(_): - await audio1.pause_async() + audio1.pause() async def resume(_): - await audio1.resume_async() + audio1.resume() async def release(_): - await audio1.release_async() + audio1.release() async def seek(_): - await audio1.seek_async(2000) + audio1.seek(3000) async def get_duration(_): - print("Current position:", await audio1.get_duration_async()) + print("Current duration:", await audio1.get_duration_async()) + + async def get_position(_): + print("Current position:", await audio1.get_current_position_async()) audio1 = ft.Audio( src=url, @@ -51,12 +54,12 @@ async def get_duration(_): on_seek_complete=lambda _: print("Seek complete"), ) page.overlay.append(audio1) - await page.add_async( + page.add( ft.ElevatedButton("Play", on_click=play), ft.ElevatedButton("Pause", on_click=pause), ft.ElevatedButton("Resume", on_click=resume), ft.ElevatedButton("Release", on_click=release), - ft.ElevatedButton("Seek 2s", on_click=seek), + ft.ElevatedButton("Seek 3s", on_click=seek), ft.Row( [ ft.ElevatedButton("Volume down", on_click=volume_down), @@ -72,7 +75,7 @@ async def get_duration(_): ft.ElevatedButton("Get duration", on_click=get_duration), ft.ElevatedButton( "Get current position", - on_click=get_duration, + on_click=get_position, ), ) From f0e01b33fad56d8cb417b94b349295e2cc9c0fb6 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 23 Jan 2025 23:40:34 -0800 Subject: [PATCH 09/81] random slider example --- python/controls/audio/audio-player-slider.py | 97 +++++++++++++++++++ python/controls/audio/audio-player.py | 68 +++++++------ python/controls/forms/slider-basic.py | 13 ++- python/controls/forms/slider-random-change.py | 29 ++++++ python/controls/forms/slider-values.py | 13 ++- python/controls/forms/slider-with-change.py | 11 +-- 6 files changed, 183 insertions(+), 48 deletions(-) create mode 100644 python/controls/audio/audio-player-slider.py create mode 100644 python/controls/forms/slider-random-change.py diff --git a/python/controls/audio/audio-player-slider.py b/python/controls/audio/audio-player-slider.py new file mode 100644 index 00000000..81662b07 --- /dev/null +++ b/python/controls/audio/audio-player-slider.py @@ -0,0 +1,97 @@ +import flet as ft + + +url = "https://github.com/mdn/webaudio-examples/blob/main/audio-basics/outfoxing.mp3?raw=true" +# url = "https://github.com/mdn/webaudio-examples/blob/main/audio-analyser/viper.mp3?raw=true" +# url = "https://luan.xyz/files/audio/ambient_c_motion.mp3" +# url = "https://luan.xyz/files/audio/coins.wav" +# url = "https://luan.xyz/files/audio/laser.wav" + + +def main(page: ft.Page): + def volume_down(_): + audio1.volume -= 0.1 + audio1.update() + + def volume_up(_): + audio1.volume += 0.1 + audio1.update() + + def balance_left(_): + audio1.balance -= 0.1 + audio1.update() + + def balance_right(_): + audio1.balance += 0.1 + audio1.update() + + def play(_): + audio1.play() + + def pause(_): + audio1.pause() + + def resume(_): + audio1.resume() + + def release(_): + audio1.release() + + def seek(_): + audio1.seek(3000) + + def get_duration(_): + print("Current duration:", audio1.get_duration()) + + def get_position(_): + print("Current position:", audio1.get_current_position()) + + def position_changed(e): + s.value=??? + + audio1 = ft.Audio( + src=url, + autoplay=False, + volume=1, + balance=0, + on_loaded=lambda _: print("Loaded"), + on_duration_changed=lambda e: print("Duration changed:", e.data), + on_position_changed=lambda e: print("Position changed:", e.data), + on_state_changed=lambda e: print("State changed:", e.data), + on_seek_complete=lambda _: print("Seek complete"), + ) + page.overlay.append(audio1) + s = ft.Slider(value=0.3) + page.add( + s, + ft.Row( + [ + ft.ElevatedButton("Play", on_click=play), + ft.ElevatedButton("Pause", on_click=pause), + ft.ElevatedButton("Resume", on_click=resume), + ] + ), + ft.ElevatedButton("Release", on_click=release), + ft.ElevatedButton("Seek 3s", on_click=seek), + ft.Row( + [ + ft.ElevatedButton("Volume down", on_click=volume_down), + ft.ElevatedButton("Volume up", on_click=volume_up), + ] + ), + ft.Row( + [ + ft.ElevatedButton("Balance left", on_click=balance_left), + ft.ElevatedButton("Balance right", on_click=balance_right), + ] + ), + ft.Row( + [ + ft.ElevatedButton("Get duration", on_click=get_duration), + ft.ElevatedButton("Get current position", on_click=get_position), + ] + ), + ) + + +ft.app(main) diff --git a/python/controls/audio/audio-player.py b/python/controls/audio/audio-player.py index 1e6d0063..a5c5642e 100644 --- a/python/controls/audio/audio-player.py +++ b/python/controls/audio/audio-player.py @@ -1,18 +1,14 @@ -import logging +import flet as ft -import flet -from flet import Audio, ElevatedButton, Page, Row, Text -# logging.basicConfig(level=logging.DEBUG) - -# url = "https://github.com/mdn/webaudio-examples/blob/main/audio-basics/outfoxing.mp3?raw=true" -url = "https://github.com/mdn/webaudio-examples/blob/main/audio-analyser/viper.mp3?raw=true" +url = "https://github.com/mdn/webaudio-examples/blob/main/audio-basics/outfoxing.mp3?raw=true" +# url = "https://github.com/mdn/webaudio-examples/blob/main/audio-analyser/viper.mp3?raw=true" # url = "https://luan.xyz/files/audio/ambient_c_motion.mp3" # url = "https://luan.xyz/files/audio/coins.wav" # url = "https://luan.xyz/files/audio/laser.wav" -def main(page: Page): +def main(page: ft.Page): def volume_down(_): audio1.volume -= 0.1 audio1.update() @@ -29,7 +25,28 @@ def balance_right(_): audio1.balance += 0.1 audio1.update() - audio1 = Audio( + def play(_): + audio1.play() + + def pause(_): + audio1.pause() + + def resume(_): + audio1.resume() + + def release(_): + audio1.release() + + def seek(_): + audio1.seek(3000) + + def get_duration(_): + print("Current duration:", audio1.get_duration()) + + def get_position(_): + print("Current position:", audio1.get_current_position()) + + audio1 = ft.Audio( src=url, autoplay=False, volume=1, @@ -42,31 +59,26 @@ def balance_right(_): ) page.overlay.append(audio1) page.add( - ElevatedButton("Play", on_click=lambda _: audio1.play()), - ElevatedButton("Pause", on_click=lambda _: audio1.pause()), - ElevatedButton("Resume", on_click=lambda _: audio1.resume()), - ElevatedButton("Release", on_click=lambda _: audio1.release()), - ElevatedButton("Seek 2s", on_click=lambda _: audio1.seek(2000)), - Row( + ft.ElevatedButton("Play", on_click=play), + ft.ElevatedButton("Pause", on_click=pause), + ft.ElevatedButton("Resume", on_click=resume), + ft.ElevatedButton("Release", on_click=release), + ft.ElevatedButton("Seek 3s", on_click=seek), + ft.Row( [ - ElevatedButton("Volume down", on_click=volume_down), - ElevatedButton("Volume up", on_click=volume_up), + ft.ElevatedButton("Volume down", on_click=volume_down), + ft.ElevatedButton("Volume up", on_click=volume_up), ] ), - Row( + ft.Row( [ - ElevatedButton("Balance left", on_click=balance_left), - ElevatedButton("Balance right", on_click=balance_right), + ft.ElevatedButton("Balance left", on_click=balance_left), + ft.ElevatedButton("Balance right", on_click=balance_right), ] ), - ElevatedButton( - "Get duration", on_click=lambda _: print("Duration:", audio1.get_duration()) - ), - ElevatedButton( - "Get current position", - on_click=lambda _: print("Current position:", audio1.get_duration()), - ), + ft.ElevatedButton("Get duration", on_click=get_duration), + ft.ElevatedButton("Get current position", on_click=get_position), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/forms/slider-basic.py b/python/controls/forms/slider-basic.py index c528a80a..023e508a 100644 --- a/python/controls/forms/slider-basic.py +++ b/python/controls/forms/slider-basic.py @@ -1,14 +1,13 @@ -import flet -from flet import Slider, Text +import flet as ft def main(page): page.add( - Text("Default slider:"), - Slider(), - Text("Default disabled slider:"), - Slider(disabled=True), + ft.Text("Default slider:"), + ft.Slider(), + ft.Text("Default disabled slider:"), + ft.Slider(disabled=True), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/forms/slider-random-change.py b/python/controls/forms/slider-random-change.py new file mode 100644 index 00000000..b904cd06 --- /dev/null +++ b/python/controls/forms/slider-random-change.py @@ -0,0 +1,29 @@ +import time +import random +import flet as ft + + +def main(page): + + def slider_changed(e): + t.value = f"Slider changed to {e.control.value}" + page.update() + + t = ft.Text() + s = ft.Slider(label="{value}", on_change=slider_changed) + + page.add( + ft.Text("Slider with 'on_change' event:"), + s, + t, + ) + + while True: + time.sleep(1) + val = s.value = random.random() + e = ft.ControlEvent("_", "_", "_", s, val) + slider_changed(e) + s.update() + + +ft.app(main) diff --git a/python/controls/forms/slider-values.py b/python/controls/forms/slider-values.py index 0b3f9670..f0d890b4 100644 --- a/python/controls/forms/slider-values.py +++ b/python/controls/forms/slider-values.py @@ -1,14 +1,13 @@ -import flet -from flet import Slider, Text +import flet as ft def main(page): page.add( - Text("Slider with value:"), - Slider(value=0.3), - Text("Slider with a custom range and label:"), - Slider(min=0, max=100, divisions=10, label="{value}%"), + ft.Text("Slider with value:"), + ft.Slider(value=0.3), + ft.Text("Slider with a custom range and label:"), + ft.Slider(min=0, max=100, divisions=10, label="{value}%"), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/forms/slider-with-change.py b/python/controls/forms/slider-with-change.py index c1c54dcc..5e8a95e0 100644 --- a/python/controls/forms/slider-with-change.py +++ b/python/controls/forms/slider-with-change.py @@ -1,5 +1,4 @@ -import flet -from flet import Slider, Text +import flet as ft def main(page): @@ -7,14 +6,14 @@ def slider_changed(e): t.value = f"Slider changed to {e.control.value}" page.update() - t = Text() + t = ft.Text() page.add( - Text("Slider with 'on_change' event:"), - Slider( + ft.Text("Slider with 'on_change' event:"), + ft.Slider( min=0, max=100, divisions=10, label="{value}%", on_change=slider_changed ), t, ) -flet.app(target=main) +ft.app(main) From 0d7e0da6acc361d2d42375528ef30245022bbae8 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 27 Jan 2025 10:39:25 -0800 Subject: [PATCH 10/81] update banner --- python/controls/banner/banner-test.py | 48 +++++++++++++-------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/python/controls/banner/banner-test.py b/python/controls/banner/banner-test.py index 547b134e..0e4d40e2 100644 --- a/python/controls/banner/banner-test.py +++ b/python/controls/banner/banner-test.py @@ -1,37 +1,35 @@ -import logging - -import flet -from flet import Banner, ElevatedButton, Icon, Text, TextButton, colors, icons - -logging.basicConfig(level=logging.DEBUG) +import flet as ft def main(page): - page.title = "Banner Example" - page.update() + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER def close_banner(e): - page.banner.open = False - page.update() - - page.banner = Banner( - bgcolor=colors.AMBER_100, - leading=Icon(icons.WARNING_AMBER_ROUNDED, color=colors.AMBER, size=40), - content=Text( - "Oops, there were some errors while trying to delete the file. What would you like me to do?" + page.close(banner) + page.add(ft.Text("Action clicked: " + e.control.text)) + + action_button_style = ft.ButtonStyle(color=ft.Colors.BLUE) + banner = ft.Banner( + bgcolor=ft.Colors.AMBER_100, + leading=ft.Icon(ft.Icons.WARNING_AMBER_ROUNDED, color=ft.Colors.AMBER, size=40), + content=ft.Text( + value="Oops, there were some errors while trying to delete the file. What would you like to do?", + color=ft.Colors.BLACK, ), actions=[ - TextButton("Retry", on_click=close_banner), - TextButton("Ignore", on_click=close_banner), - TextButton("Cancel", on_click=close_banner), + ft.TextButton( + text="Retry", style=action_button_style, on_click=close_banner + ), + ft.TextButton( + text="Ignore", style=action_button_style, on_click=close_banner + ), + ft.TextButton( + text="Cancel", style=action_button_style, on_click=close_banner + ), ], ) - def show_banner_click(e): - page.banner.open = True - page.update() - - page.add(ElevatedButton("Show Banner", on_click=show_banner_click)) + page.add(ft.ElevatedButton("Show Banner", on_click=lambda e: page.open(banner))) -flet.app(target=main) +ft.app(main) From 131caa522f791c2513aeabb28a260158bda7b87c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 27 Jan 2025 15:18:08 -0800 Subject: [PATCH 11/81] barchart update --- python/controls/charts/barchart_sample-1.py | 2 +- python/controls/charts/barchart_sample-2.py | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/python/controls/charts/barchart_sample-1.py b/python/controls/charts/barchart_sample-1.py index aeb004fd..700ebefe 100644 --- a/python/controls/charts/barchart_sample-1.py +++ b/python/controls/charts/barchart_sample-1.py @@ -11,7 +11,7 @@ def main(page: ft.Page): from_y=0, to_y=40, width=40, - color=ft.colors.AMBER, + color=ft.colors.GREEN, tooltip="Apple", border_radius=0, ), diff --git a/python/controls/charts/barchart_sample-2.py b/python/controls/charts/barchart_sample-2.py index 0413c589..60be40f6 100644 --- a/python/controls/charts/barchart_sample-2.py +++ b/python/controls/charts/barchart_sample-2.py @@ -7,17 +7,17 @@ def __init__(self, y: float, hovered: bool = False): self.hovered = hovered self.y = y - def _before_build_command(self): - self.to_y = self.y + 1 if self.hovered else self.y + def before_update(self): + self.to_y = self.y + 0.5 if self.hovered else self.y self.color = ft.colors.YELLOW if self.hovered else ft.colors.WHITE self.border_side = ( ft.BorderSide(width=1, color=ft.colors.GREEN_400) if self.hovered else ft.BorderSide(width=0, color=ft.colors.WHITE) ) - super()._before_build_command() + super().before_update() - def _build(self): + def build(self): self.tooltip = str(self.y) self.width = 22 self.color = ft.colors.WHITE @@ -44,7 +44,7 @@ def on_chart_event(e: ft.BarChartEvent): ), ft.BarChartGroup( x=2, - bar_rods=[SampleRod(5)], + bar_rods=[SampleRod(15)], ), ft.BarChartGroup( x=3, From bab4b0e0e1edf2c823d14756cfe7bb38c75b4e15 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 27 Jan 2025 15:20:08 -0800 Subject: [PATCH 12/81] barchart update --- python/controls/charts/barchart_sample-2.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/python/controls/charts/barchart_sample-2.py b/python/controls/charts/barchart_sample-2.py index 60be40f6..f919e19a 100644 --- a/python/controls/charts/barchart_sample-2.py +++ b/python/controls/charts/barchart_sample-2.py @@ -9,20 +9,20 @@ def __init__(self, y: float, hovered: bool = False): def before_update(self): self.to_y = self.y + 0.5 if self.hovered else self.y - self.color = ft.colors.YELLOW if self.hovered else ft.colors.WHITE + self.color = ft.Colors.YELLOW if self.hovered else ft.Colors.WHITE self.border_side = ( - ft.BorderSide(width=1, color=ft.colors.GREEN_400) + ft.BorderSide(width=1, color=ft.Colors.GREEN_400) if self.hovered - else ft.BorderSide(width=0, color=ft.colors.WHITE) + else ft.BorderSide(width=0, color=ft.Colors.WHITE) ) super().before_update() def build(self): self.tooltip = str(self.y) self.width = 22 - self.color = ft.colors.WHITE + self.color = ft.Colors.WHITE self.bg_to_y = 20 - self.bg_color = ft.colors.GREEN_300 + self.bg_color = ft.Colors.GREEN_300 def main(page: ft.Page): @@ -80,7 +80,7 @@ def on_chart_event(e: ft.BarChartEvent): page.add( ft.Container( - chart, bgcolor=ft.colors.GREEN_200, padding=10, border_radius=5, expand=True + chart, bgcolor=ft.Colors.GREEN_200, padding=10, border_radius=5, expand=True ) ) From 6437c632911ca32d7929c54df45f551f41eac493 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 27 Jan 2025 23:02:39 -0800 Subject: [PATCH 13/81] update BottomSheet --- .../bottom-sheet/modal-bottom-sheet.py | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/python/controls/bottom-sheet/modal-bottom-sheet.py b/python/controls/bottom-sheet/modal-bottom-sheet.py index a0122a2d..67ae7807 100644 --- a/python/controls/bottom-sheet/modal-bottom-sheet.py +++ b/python/controls/bottom-sheet/modal-bottom-sheet.py @@ -2,33 +2,31 @@ def main(page: ft.Page): - def bs_dismissed(e): - print("Dismissed!") - - def show_bs(e): - bs.open = True - bs.update() + page.title = "BottomSheet example" + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER - def close_bs(e): - bs.open = False - bs.update() + def bs_dismissed(e): + page.add(ft.Text("Bottom sheet dismissed")) bs = ft.BottomSheet( ft.Container( ft.Column( [ - ft.Text("This is sheet's content!"), - ft.ElevatedButton("Close bottom sheet", on_click=close_bs), + ft.Text("Here is a bottom sheet!"), + ft.ElevatedButton("Dismiss", on_click=lambda _: page.close(bs)), ], + horizontal_alignment=ft.CrossAxisAlignment.CENTER, tight=True, ), - padding=10, + padding=50, ), - open=True, + open=False, on_dismiss=bs_dismissed, ) page.overlay.append(bs) - page.add(ft.ElevatedButton("Display bottom sheet", on_click=show_bs)) + page.add( + ft.ElevatedButton("Display bottom sheet", on_click=lambda e: page.open(bs)) + ) ft.app(target=main) From 20bc743c2d12705b9ad4db1423fb4cdf82b3d67f Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 30 Jan 2025 15:10:21 -0800 Subject: [PATCH 14/81] update animation examples, add buffered image switcher --- .../animation/animate-button-on-hover.py | 13 ++-- .../controls/animation/animate-container.py | 28 ++++---- .../animate-image-switch-buffered.py | 70 +++++++++++++++++++ .../animation/animate-image-switch.py | 2 +- python/controls/animation/animate-offset.py | 2 +- python/controls/animation/animate-opacity.py | 2 +- python/controls/animation/animate-rotation.py | 4 +- .../controls/animation/animate-scale-docs.py | 5 +- python/controls/animation/animate-scale.py | 6 +- .../animation/animate-single-container.py | 2 +- .../controls/animation/animated-left-menu.py | 6 +- python/controls/animation/image-slideshow.py | 7 +- python/controls/animation/rocket.py | 4 +- .../basic-elevated-buttons.py | 12 ++-- .../elevated-button-with-click-event.py | 11 ++- .../elevated-buttons-with-icons.py | 12 ++-- 16 files changed, 128 insertions(+), 58 deletions(-) create mode 100644 python/controls/animation/animate-image-switch-buffered.py diff --git a/python/controls/animation/animate-button-on-hover.py b/python/controls/animation/animate-button-on-hover.py index 1bfb3308..30802d72 100644 --- a/python/controls/animation/animate-button-on-hover.py +++ b/python/controls/animation/animate-button-on-hover.py @@ -3,19 +3,20 @@ def main(page: ft.Page): def animate(e): - b1.rotate = 0.1 if e.data == "true" else 0 + b.rotate = 0.1 if e.data == "true" else 0 page.update() - b1 = ft.ElevatedButton( - "Hover me, I'm animated!", + t = ft.Text() + b = ft.ElevatedButton( + "Hover over me, I'm animated!", rotate=0, animate_rotation=100, on_hover=animate, - on_click=lambda e: print("Clicked!"), - on_long_press=lambda e: print("Long pressed!"), + on_click=lambda e: page.add(ft.Text("Clicked! Try a long press!")), + on_long_press=lambda e: page.add(ft.Text("I knew you could do it!")), ) - page.add(b1) + page.add(b) ft.app(target=main) diff --git a/python/controls/animation/animate-container.py b/python/controls/animation/animate-container.py index 6d98a964..f8772bde 100644 --- a/python/controls/animation/animate-container.py +++ b/python/controls/animation/animate-container.py @@ -6,44 +6,44 @@ def main(page: ft.Page): g1 = ft.LinearGradient( begin=ft.alignment.top_center, end=ft.alignment.bottom_center, - colors=[ft.colors.GREEN, ft.colors.TRANSPARENT], + colors=[ft.Colors.GREEN, ft.Colors.BLUE], stops=[0.5, 1.0], ) g2 = ft.RadialGradient( center=ft.alignment.top_left, radius=1.0, - colors=[ft.colors.YELLOW, ft.colors.DEEP_ORANGE_900], + colors=[ft.Colors.YELLOW, ft.Colors.DEEP_ORANGE_900], tile_mode=ft.GradientTileMode.CLAMP, ) - + t = ft.Text("Animate me!") c = ft.Container( - ft.Text("Animate me!"), - width=200, - height=200, - bgcolor="red", + t, + width=250, + height=250, gradient=g1, alignment=ft.alignment.top_left, animate=ft.animation.Animation(1000, ft.AnimationCurve.BOUNCE_OUT), border=ft.border.all(2, "blue"), border_radius=10, padding=10, - margin=10, ) def animate_container(e): - c.width = 100 if c.width == 200 else 200 - c.height = 100 if c.height == 200 else 200 - c.bgcolor = "blue" if c.bgcolor == "red" else "red" + t.value = "Animate me back!" if t.value == "Animate me!" else "Animate me!" + c.width = 150 if c.width == 250 else 250 + c.height = 150 if c.height == 250 else 250 c.gradient = g2 if c.gradient == g1 else g1 if c.alignment == ft.alignment.top_left: c.alignment = ft.alignment.bottom_right else: c.alignment = ft.alignment.top_left c.border_radius = 30 if c.border_radius == 10 else 10 - c.border = ft.border.all(4, "black") - c.padding = 50 - c.margin = 50 + c.border = ( + ft.border.all(2, "black") + if c.border == ft.border.all(2, "blue") + else ft.border.all(2, "blue") + ) c.update() page.add(c, ft.ElevatedButton("Animate container", on_click=animate_container)) diff --git a/python/controls/animation/animate-image-switch-buffered.py b/python/controls/animation/animate-image-switch-buffered.py new file mode 100644 index 00000000..464d6760 --- /dev/null +++ b/python/controls/animation/animate-image-switch-buffered.py @@ -0,0 +1,70 @@ +import time +import httpx +import base64 + +import flet as ft + + +class BufferingSwitcher(ft.AnimatedSwitcher): + image_queue = [] + + def __init__(self, image: ft.Image, page: ft.Page): + super().__init__(image) + self.transition = ft.AnimatedSwitcherTransition.SCALE + self.duration = 500 + self.reverse_duration = 100 + self.switch_in_curve = ft.AnimationCurve.EASE_IN + self.switch_out_curve = ft.AnimationCurve.EASE_OUT + self.image_queue.append(image) + self.page = page + + def animate(self, e): + self.content = ft.Image( + src_base64=self.image_queue.pop(), + width=200, + height=300, + gapless_playback=True, + ) + self.update() + + async def fill_queue(self): + while len(self.image_queue) < 10: + + self.image_queue.append( + await self.image_to_base64( + f"https://picsum.photos/200/300?{time.time()}" + ) + ) + + async def image_to_base64(self, url): + print("image_to_base64 called") + response = await httpx.AsyncClient(follow_redirects=True).get(url) + if response.status_code == 200: + base64_str = ( + base64.standard_b64encode(response.content).decode("utf-8").strip() + ) + return base64_str + else: + print(f"Image request failed with {response.status_code}") + + def before_update(self): + + self.page.run_task(self.fill_queue) + print(len(self.image_queue)) + + +def main(page: ft.Page): + + i = ft.Image( + src=f"https://picsum.photos/200/300?{time.time()}", width=200, height=300 + ) + + sw = BufferingSwitcher(i, page) + + page.add( + sw, + ft.ElevatedButton("Animate!", on_click=sw.animate), + ) + + +ft.app(target=main) diff --git a/python/controls/animation/animate-image-switch.py b/python/controls/animation/animate-image-switch.py index 81f6e22e..95d18516 100644 --- a/python/controls/animation/animate-image-switch.py +++ b/python/controls/animation/animate-image-switch.py @@ -28,4 +28,4 @@ def animate(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/animate-offset.py b/python/controls/animation/animate-offset.py index 2673607b..586838be 100644 --- a/python/controls/animation/animate-offset.py +++ b/python/controls/animation/animate-offset.py @@ -21,4 +21,4 @@ def animate(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/animate-opacity.py b/python/controls/animation/animate-opacity.py index 6667e210..91c592cf 100644 --- a/python/controls/animation/animate-opacity.py +++ b/python/controls/animation/animate-opacity.py @@ -18,4 +18,4 @@ def animate_opacity(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/animate-rotation.py b/python/controls/animation/animate-rotation.py index 645253f3..231b2a7b 100644 --- a/python/controls/animation/animate-rotation.py +++ b/python/controls/animation/animate-rotation.py @@ -29,9 +29,9 @@ def animate(e): page.update() page.add( - ft.Stack([c1, c2], width=600, height=600), + ft.Stack([c1, c2], width=500, height=300), ft.ElevatedButton("Animate!", on_click=animate), ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/animate-scale-docs.py b/python/controls/animation/animate-scale-docs.py index b9ea3e66..9fa8d297 100644 --- a/python/controls/animation/animate-scale-docs.py +++ b/python/controls/animation/animate-scale-docs.py @@ -8,13 +8,12 @@ def main(page: ft.Page): height=100, bgcolor="blue", border_radius=5, - scale=ft.transform.Scale(scale=1), + scale=1, animate_scale=ft.animation.Animation(600, ft.AnimationCurve.BOUNCE_OUT), ) def animate(e): - # c1.rotate = 1 - c.scale = 2 + c.scale = 2 if c.scale == 1 else 1 page.update() page.vertical_alignment = ft.MainAxisAlignment.CENTER diff --git a/python/controls/animation/animate-scale.py b/python/controls/animation/animate-scale.py index 24056569..02b14101 100644 --- a/python/controls/animation/animate-scale.py +++ b/python/controls/animation/animate-scale.py @@ -4,7 +4,7 @@ def main(page: ft.Page): c1 = ft.ShaderMask( - ft.Image( + content=ft.Image( src="https://picsum.photos/140/100?1", width=140, height=100, @@ -14,7 +14,7 @@ def main(page: ft.Page): shader=ft.RadialGradient( center=ft.alignment.top_left, radius=1.0, - colors=[ft.colors.YELLOW, ft.colors.DEEP_ORANGE_900], + colors=[ft.Colors.YELLOW, ft.Colors.DEEP_ORANGE_900], tile_mode=ft.GradientTileMode.CLAMP, ), border_radius=5, @@ -28,7 +28,7 @@ def animate(e): page.update() page.add( - ft.Stack([c1], width=600, height=600), + ft.Stack([c1], width=500, height=300), ft.ElevatedButton("Animate!", on_click=animate), ) diff --git a/python/controls/animation/animate-single-container.py b/python/controls/animation/animate-single-container.py index fab80563..7dc4fa8d 100644 --- a/python/controls/animation/animate-single-container.py +++ b/python/controls/animation/animate-single-container.py @@ -19,4 +19,4 @@ def animate_container(e): page.add(c, ft.ElevatedButton("Animate container", on_click=animate_container)) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/animated-left-menu.py b/python/controls/animation/animated-left-menu.py index 8cd532cd..d5347ca3 100644 --- a/python/controls/animation/animated-left-menu.py +++ b/python/controls/animation/animated-left-menu.py @@ -14,7 +14,7 @@ def hide_menu(e): content=ft.Column( [ ft.Row( - [ft.IconButton(icon=ft.icons.CLOSE, on_click=hide_menu)], + [ft.IconButton(icon=ft.Icons.CLOSE, on_click=hide_menu)], alignment=ft.MainAxisAlignment.END, ), ft.ListTile( @@ -31,7 +31,7 @@ def hide_menu(e): top=10, width=200, height=300, - bgcolor=ft.colors.SURFACE_VARIANT, + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, border_radius=5, offset=ft.transform.Offset(-2, 0), animate_offset=ft.animation.Animation(300, ft.AnimationCurve.EASE_IN), @@ -43,4 +43,4 @@ def hide_menu(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/image-slideshow.py b/python/controls/animation/image-slideshow.py index 078fb56e..8b6531ef 100644 --- a/python/controls/animation/image-slideshow.py +++ b/python/controls/animation/image-slideshow.py @@ -6,6 +6,7 @@ def main(page: ft.Page): i1 = ft.Image( src="https://picsum.photos/200/300?1", animate_position=ft.animation.Animation(300, ft.AnimationCurve.BOUNCE_OUT), + left=0, ) i2 = ft.Image( src="https://picsum.photos/200/300?2", @@ -14,8 +15,8 @@ def main(page: ft.Page): ) def animate(e): - i1.left = 400 - i2.left = 0 + i1.left = 400 if i1.left == 0 else 0 + i2.left = 0 if i2.left == -400 else -400 page.update() page.add( @@ -31,4 +32,4 @@ def animate(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/animation/rocket.py b/python/controls/animation/rocket.py index 5c001709..bf72e682 100644 --- a/python/controls/animation/rocket.py +++ b/python/controls/animation/rocket.py @@ -7,7 +7,7 @@ def main(page: ft.Page): c2 = ft.Container( content=ft.Container( - ft.Icon(ft.icons.ROCKET, size=40, color="black"), + ft.Icon(ft.Icons.ROCKET, size=40, color="black"), scale=1.0, animate_scale=1000, opacity=1.0, @@ -41,4 +41,4 @@ def animate(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/elevated-buttons/basic-elevated-buttons.py b/python/controls/elevated-buttons/basic-elevated-buttons.py index c8e9dde4..78c405c4 100644 --- a/python/controls/elevated-buttons/basic-elevated-buttons.py +++ b/python/controls/elevated-buttons/basic-elevated-buttons.py @@ -1,13 +1,13 @@ -import flet -from flet import ElevatedButton, Page +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Basic elevated buttons" + page.add( - ElevatedButton(text="Elevated button"), - ElevatedButton("Disabled button", disabled=True), + ft.ElevatedButton(text="Elevated button"), + ft.Button("Disabled button", disabled=True), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/elevated-buttons/elevated-button-with-click-event.py b/python/controls/elevated-buttons/elevated-button-with-click-event.py index d7fd5f17..982f5c7b 100644 --- a/python/controls/elevated-buttons/elevated-button-with-click-event.py +++ b/python/controls/elevated-buttons/elevated-button-with-click-event.py @@ -1,8 +1,7 @@ -import flet -from flet import ElevatedButton, Page, Text +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Elevated button with 'click' event" def button_clicked(e): @@ -10,10 +9,10 @@ def button_clicked(e): t.value = f"Button clicked {b.data} time(s)" page.update() - b = ElevatedButton("Button with 'click' event", on_click=button_clicked, data=0) - t = Text() + b = ft.ElevatedButton("Button with 'click' event", on_click=button_clicked, data=0) + t = ft.Text() page.add(b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/elevated-buttons/elevated-buttons-with-icons.py b/python/controls/elevated-buttons/elevated-buttons-with-icons.py index bc11f77c..680c18c9 100644 --- a/python/controls/elevated-buttons/elevated-buttons-with-icons.py +++ b/python/controls/elevated-buttons/elevated-buttons-with-icons.py @@ -1,12 +1,12 @@ -import flet -from flet import ElevatedButton, Page +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Elevated buttons with icons" + page.add( - ElevatedButton("Button with icon", icon="chair_outlined"), - ElevatedButton( + ft.ElevatedButton("Button with icon", icon="chair_outlined"), + ft.ElevatedButton( "Button with colorful icon", icon="park_rounded", icon_color="green400", @@ -14,4 +14,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) From dbc7ce684b3fd201ce385bae398b37c20a0b6085 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 31 Jan 2025 10:50:28 -0800 Subject: [PATCH 15/81] add rive and lottie examples --- python/controls/animation/lottie-basic.py | 14 ++++++++++++++ python/controls/animation/rive-basic.py | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 python/controls/animation/lottie-basic.py create mode 100644 python/controls/animation/rive-basic.py diff --git a/python/controls/animation/lottie-basic.py b/python/controls/animation/lottie-basic.py new file mode 100644 index 00000000..5f0716a0 --- /dev/null +++ b/python/controls/animation/lottie-basic.py @@ -0,0 +1,14 @@ +import flet as ft + + +def main(page: ft.Page): + l = ft.Lottie( + src="https://raw.githubusercontent.com/xvrh/lottie-flutter/refs/heads/master/example/assets/Logo/LogoSmall.json", + reverse=False, + animate=True, + ) + c1 = ft.Container(content=l, bgcolor=ft.Colors.AMBER_ACCENT, padding=50) + page.add(c1) + + +ft.app(main) diff --git a/python/controls/animation/rive-basic.py b/python/controls/animation/rive-basic.py new file mode 100644 index 00000000..336b8228 --- /dev/null +++ b/python/controls/animation/rive-basic.py @@ -0,0 +1,15 @@ +import flet as ft + + +def main(page): + page.add( + ft.Rive( + "https://cdn.rive.app/animations/vehicles.riv", + placeholder=ft.ProgressBar(), + width=300, + height=200, + ) + ) + + +ft.app(main) From 2f590e47e8aded8e63441f4952c5c032ba8229c6 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 31 Jan 2025 21:39:21 -0800 Subject: [PATCH 16/81] add bottom-appbar example --- python/controls/appbar/bottom-appbar.py | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 python/controls/appbar/bottom-appbar.py diff --git a/python/controls/appbar/bottom-appbar.py b/python/controls/appbar/bottom-appbar.py new file mode 100644 index 00000000..d6d8d2cc --- /dev/null +++ b/python/controls/appbar/bottom-appbar.py @@ -0,0 +1,34 @@ +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = page.vertical_alignment = "center" + + page.floating_action_button = ft.FloatingActionButton( + icon=ft.Icons.ADD, shape=ft.CircleBorder() + ) + page.floating_action_button_location = ft.FloatingActionButtonLocation.CENTER_DOCKED + + page.appbar = ft.AppBar( + title=ft.Text("Bottom AppBar Demo"), + center_title=True, + bgcolor=ft.Colors.GREEN_300, + automatically_imply_leading=False, + ) + page.bottom_appbar = ft.BottomAppBar( + bgcolor=ft.Colors.BLUE, + shape=ft.NotchShape.CIRCULAR, + content=ft.Row( + controls=[ + ft.IconButton(icon=ft.Icons.MENU, icon_color=ft.Colors.WHITE), + ft.Container(expand=True), + ft.IconButton(icon=ft.Icons.SEARCH, icon_color=ft.Colors.WHITE), + ft.IconButton(icon=ft.Icons.FAVORITE, icon_color=ft.Colors.WHITE), + ] + ), + ) + + page.add(ft.Text("Body!")) + + +ft.app(main) From c2ca94b64ca96800b6726b856dc1c99f1a4b200b Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 31 Jan 2025 22:42:11 -0800 Subject: [PATCH 17/81] add cupertino-button.py --- .../cupertino-buttons/cupertino-button.py | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 python/controls/cupertino-buttons/cupertino-button.py diff --git a/python/controls/cupertino-buttons/cupertino-button.py b/python/controls/cupertino-buttons/cupertino-button.py new file mode 100644 index 00000000..c19fe4cc --- /dev/null +++ b/python/controls/cupertino-buttons/cupertino-button.py @@ -0,0 +1,44 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.CupertinoButton( + content=ft.Text( + "Normal CupertinoButton", + color=ft.CupertinoColors.DESTRUCTIVE_RED, + ), + bgcolor=ft.CupertinoColors.LIGHT_BACKGROUND_GRAY, + opacity_on_click=0.3, + on_click=lambda e: print("Normal CupertinoButton clicked!"), + ), + ft.CupertinoButton( + content=ft.Text("Filled CupertinoButton", color=ft.Colors.YELLOW), + bgcolor=ft.Colors.PRIMARY, + alignment=ft.alignment.top_left, + border_radius=ft.border_radius.all(15), + opacity_on_click=0.5, + on_click=lambda e: print("Filled CupertinoButton clicked!"), + ), + ft.CupertinoButton( + content=ft.Text("Disabled CupertinoButton"), + bgcolor=ft.Colors.PRIMARY, + disabled=True, + alignment=ft.alignment.top_left, + opacity_on_click=0.5, + ), + ft.ElevatedButton( + adaptive=True, # a CupertinoButton will be rendered when running on apple-platform + bgcolor=ft.CupertinoColors.SYSTEM_TEAL, + content=ft.Row( + [ + ft.Icon(name=ft.Icons.FAVORITE, color="pink"), + ft.Text("ElevatedButton+adaptive"), + ], + tight=True, + ), + ), + ) + + +ft.app(main) From c567b43e8c7c1aff93b74b81f989d2b8d32cec3c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 3 Feb 2025 23:41:23 -0800 Subject: [PATCH 18/81] add cupertino-segmented-button examples --- .../cupertino-segmented-button-padding.py | 69 +++++++++++++++++++ .../cupertino-segmented-button.py | 27 ++++++++ .../cupertino-sliding-segmented-button.py | 28 ++++++++ 3 files changed, 124 insertions(+) create mode 100644 python/controls/cupertino-buttons/cupertino-segmented-button-padding.py create mode 100644 python/controls/cupertino-buttons/cupertino-segmented-button.py create mode 100644 python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py diff --git a/python/controls/cupertino-buttons/cupertino-segmented-button-padding.py b/python/controls/cupertino-buttons/cupertino-segmented-button-padding.py new file mode 100644 index 00000000..0655f5c7 --- /dev/null +++ b/python/controls/cupertino-buttons/cupertino-segmented-button-padding.py @@ -0,0 +1,69 @@ +import flet as ft + + +def main(page): + page.theme_mode = ft.ThemeMode.LIGHT + + def handle_vertical_change(e): + csb.controls[1].padding = ft.padding.only( + top=e.control.value, bottom=e.control.value + ) + page.update() + + def handle_horizontal_change(e): + csb.controls[2].padding = ft.padding.only( + left=e.control.value, right=e.control.value + ) + page.update() + + csb = ft.CupertinoSegmentedButton( + selected_index=1, + selected_color=ft.Colors.RED_400, + unselected_color=ft.Colors.GREY_400, + on_change=lambda e: print(f"selected_index: {e.data}"), + controls=[ + ft.Text("All"), + ft.Container( + padding=ft.padding.symmetric(30, 0), + content=ft.Text("None"), + # alignment=ft.alignment.top_left, + ), + ft.Container( + padding=ft.padding.symmetric(0, 30), + content=ft.Text("Some"), + # alignment=ft.alignment.bottom_right, + ), + ], + ) + + vs = ft.Slider( + label="{value}", + min=0, + max=50, + divisions=50, + value=30, + on_change=handle_vertical_change, + ) + hs = ft.Slider( + label="{value}", + min=0, + max=50, + divisions=50, + value=30, + on_change=handle_horizontal_change, + ) + page.add( + csb, + ft.Text("Vertical padding button 1: "), + vs, + ft.Text("Horizontal padding button 2:"), + hs, + ft.Text( + "*note that padding changes to one segment can effect padding on other segments*", + style=ft.TextThemeStyle.LABEL_MEDIUM, + color=ft.Colors.ORANGE_ACCENT, + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino-buttons/cupertino-segmented-button.py b/python/controls/cupertino-buttons/cupertino-segmented-button.py new file mode 100644 index 00000000..6fbad250 --- /dev/null +++ b/python/controls/cupertino-buttons/cupertino-segmented-button.py @@ -0,0 +1,27 @@ +import flet as ft + + +def main(page): + page.theme_mode = ft.ThemeMode.LIGHT + + page.add( + ft.CupertinoSegmentedButton( + selected_index=1, + selected_color=ft.Colors.RED_400, + on_change=lambda e: print(f"selected_index: {e.data}"), + controls=[ + ft.Text("One"), + ft.Container( + padding=ft.padding.symmetric(0, 30), + content=ft.Text("Two"), + ), + ft.Container( + padding=ft.padding.symmetric(0, 10), + content=ft.Text("Three"), + ), + ], + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py b/python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py new file mode 100644 index 00000000..c9143186 --- /dev/null +++ b/python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py @@ -0,0 +1,28 @@ +import flet as ft + + +def main(page): + page.title = "CupertinoSlidingSegmentedButton example" + page.theme_mode = ft.ThemeMode.LIGHT + + def handle_change(e): + print(f"selected_index: {e.data}") + page.add(ft.Text(f"segment {int(e.data) + 1} chosen")) + page.update() + + page.add( + ft.CupertinoSlidingSegmentedButton( + selected_index=1, + thumb_color=ft.Colors.BLUE_400, + on_change=handle_change, + padding=ft.padding.symmetric(0, 10), + controls=[ + ft.Text("One"), + ft.Text("Two"), + ft.Text("Three"), + ], + ), + ) + + +ft.app(main) From d394f970e1346862d25b1ed713e946cdbaf07632 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 4 Feb 2025 11:31:47 -0800 Subject: [PATCH 19/81] update remaining buttons --- .../elevated-buttons-with-custom-content.py | 8 ++++---- .../elevated-buttons/elevated-buttons-with-icons.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/controls/elevated-buttons/elevated-buttons-with-custom-content.py b/python/controls/elevated-buttons/elevated-buttons-with-custom-content.py index d6299919..64200d60 100644 --- a/python/controls/elevated-buttons/elevated-buttons-with-custom-content.py +++ b/python/controls/elevated-buttons/elevated-buttons-with-custom-content.py @@ -8,9 +8,9 @@ def main(page: ft.Page): width=150, content=ft.Row( [ - ft.Icon(name=ft.icons.FAVORITE, color="pink"), - ft.Icon(name=ft.icons.AUDIOTRACK, color="green"), - ft.Icon(name=ft.icons.BEACH_ACCESS, color="blue"), + ft.Icon(name=ft.Icons.FAVORITE, color="pink"), + ft.Icon(name=ft.Icons.AUDIOTRACK, color="green"), + ft.Icon(name=ft.Icons.BEACH_ACCESS, color="blue"), ], alignment=ft.MainAxisAlignment.SPACE_AROUND, ), @@ -31,4 +31,4 @@ def main(page: ft.Page): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/elevated-buttons/elevated-buttons-with-icons.py b/python/controls/elevated-buttons/elevated-buttons-with-icons.py index 680c18c9..c81f6437 100644 --- a/python/controls/elevated-buttons/elevated-buttons-with-icons.py +++ b/python/controls/elevated-buttons/elevated-buttons-with-icons.py @@ -9,7 +9,7 @@ def main(page: ft.Page): ft.ElevatedButton( "Button with colorful icon", icon="park_rounded", - icon_color="green400", + icon_color=ft.Colors.GREEN_400, ), ) From a2015d43c2cc0d35f5c63a0381102b45b2dc050a Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Feb 2025 13:19:16 -0800 Subject: [PATCH 20/81] add canvas-flet-logo example --- python/controls/canvas/canvas-flet-logo.py | 45 ++++++++++++++++++++++ python/controls/card/card-with-buttons.py | 32 +++++++-------- 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 python/controls/canvas/canvas-flet-logo.py diff --git a/python/controls/canvas/canvas-flet-logo.py b/python/controls/canvas/canvas-flet-logo.py new file mode 100644 index 00000000..b538ee04 --- /dev/null +++ b/python/controls/canvas/canvas-flet-logo.py @@ -0,0 +1,45 @@ +import math + +import flet as ft +import flet.canvas as cv + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + cp = cv.Canvas( + [ + cv.Path( + [ + cv.Path.MoveTo(25, 125), + cv.Path.QuadraticTo(50, 25, 135, 35, 0.35), + cv.Path.QuadraticTo(75, 115, 135, 215, 0.6), + cv.Path.QuadraticTo(50, 225, 25, 125, 0.35), + ], + paint=ft.Paint( + stroke_width=2, + style=ft.PaintingStyle.FILL, + color=ft.Colors.PINK_400, + ), + ), + cv.Path( + [ + cv.Path.MoveTo(85, 125), + cv.Path.QuadraticTo(120, 85, 165, 75, 0.5), + cv.Path.QuadraticTo(120, 115, 165, 175, 0.3), + cv.Path.QuadraticTo(120, 165, 85, 125, 0.5), + ], + paint=ft.Paint( + stroke_width=2, + style=ft.PaintingStyle.FILL, + color=ft.Colors.with_opacity(0.5, ft.Colors.BLUE_400), + ), + ), + ], + width=float("inf"), + expand=True, + ) + + page.add(cp) + + +ft.app(main) diff --git a/python/controls/card/card-with-buttons.py b/python/controls/card/card-with-buttons.py index 4f718a2d..da07f30c 100644 --- a/python/controls/card/card-with-buttons.py +++ b/python/controls/card/card-with-buttons.py @@ -1,32 +1,34 @@ -import flet -from flet import Card, Column, Container, Icon, ListTile, Row, Text, TextButton, icons +import flet as ft -def main(page): +def main(page: ft.Page): page.title = "Card Example" + page.theme_mode = ft.ThemeMode.LIGHT page.add( - Card( - content=Container( - content=Column( + ft.Card( + content=ft.Container( + content=ft.Column( [ - ListTile( - leading=Icon(icons.ALBUM), - title=Text("The Enchanted Nightingale"), - subtitle=Text( + ft.ListTile( + leading=ft.Icon(ft.Icons.ALBUM), + title=ft.Text("The Enchanted Nightingale"), + subtitle=ft.Text( "Music by Julie Gable. Lyrics by Sidney Stein." ), + bgcolor=ft.Colors.GREY_400, ), - Row( - [TextButton("Buy tickets"), TextButton("Listen")], - alignment="end", + ft.Row( + [ft.TextButton("Buy tickets"), ft.TextButton("Listen")], + alignment=ft.MainAxisAlignment.END, ), ] ), width=400, padding=10, - ) + ), + shadow_color=ft.Colors.ON_SURFACE_VARIANT, ) ) -flet.app(target=main) +ft.app(main) From e1693388fd3c0d47f9da08aac45749f8676ab629 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Feb 2025 15:59:24 -0800 Subject: [PATCH 21/81] canvas examples --- python/controls/canvas/canvas-gradients.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/controls/canvas/canvas-gradients.py b/python/controls/canvas/canvas-gradients.py index cdf8d9a4..039d771b 100644 --- a/python/controls/canvas/canvas-gradients.py +++ b/python/controls/canvas/canvas-gradients.py @@ -18,7 +18,6 @@ def main(page: ft.Page): (0, 10), (100, 50), colors=[ft.colors.BLUE, ft.colors.YELLOW], - # rotation=math.pi / 2, ), style=ft.PaintingStyle.FILL, ), From 4a05ad66dd86db6bee2de1e5113a4df90612a594 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 10 Feb 2025 10:48:57 -0800 Subject: [PATCH 22/81] finish canvas update --- python/controls/canvas/canvas-gradients.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/controls/canvas/canvas-gradients.py b/python/controls/canvas/canvas-gradients.py index 039d771b..517d260b 100644 --- a/python/controls/canvas/canvas-gradients.py +++ b/python/controls/canvas/canvas-gradients.py @@ -17,7 +17,7 @@ def main(page: ft.Page): gradient=ft.PaintLinearGradient( (0, 10), (100, 50), - colors=[ft.colors.BLUE, ft.colors.YELLOW], + colors=[ft.Colors.BLUE, ft.Colors.YELLOW], ), style=ft.PaintingStyle.FILL, ), From 80b4c02f5b1bdb12b16aa8e58021304f73a9cc1c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 13 Feb 2025 11:31:30 -0800 Subject: [PATCH 23/81] add dropdown and checkbox examples --- python/controls/forms/checkbox-basic.py | 4 +-- python/controls/forms/checkbox-with-event.py | 18 +++++----- python/controls/forms/dropdown-add-items.py | 20 +++++++++++ python/controls/forms/dropdown-random-icon.py | 34 +++++++++++++++++++ python/controls/forms/dropdown.py | 23 ++++++------- 5 files changed, 74 insertions(+), 25 deletions(-) create mode 100644 python/controls/forms/dropdown-add-items.py create mode 100644 python/controls/forms/dropdown-random-icon.py diff --git a/python/controls/forms/checkbox-basic.py b/python/controls/forms/checkbox-basic.py index e20b41e3..c2061afc 100644 --- a/python/controls/forms/checkbox-basic.py +++ b/python/controls/forms/checkbox-basic.py @@ -1,7 +1,7 @@ import flet as ft -def main(page): +def main(page: ft.Page): def button_clicked(e): t.value = f"Checkboxes values are: {c1.value}, {c2.value}, {c3.value}, {c4.value}, {c5.value}." page.update() @@ -19,4 +19,4 @@ def button_clicked(e): page.add(c1, c2, c3, c4, c5, b, t) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/forms/checkbox-with-event.py b/python/controls/forms/checkbox-with-event.py index edf864d4..4a9737a1 100644 --- a/python/controls/forms/checkbox-with-event.py +++ b/python/controls/forms/checkbox-with-event.py @@ -1,16 +1,14 @@ -import flet -from flet import Checkbox, ElevatedButton, Text +import flet as ft -def main(page): - def checkbox_changed(e): - t.value = f"Checkbox value changed to {c.value}" - t.update() +def main(page: ft.Page): + def checkbox_changed(e): + page.add(ft.Text(f"Checkbox value changed to {c.value}")) + page.update() - c = Checkbox(label="Checkbox with 'change' event", on_change=checkbox_changed) - t = Text() + c = ft.Checkbox(label="Checkbox with 'change' event", on_change=checkbox_changed) - page.add(c, t) + page.add(c) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/forms/dropdown-add-items.py b/python/controls/forms/dropdown-add-items.py new file mode 100644 index 00000000..8214be78 --- /dev/null +++ b/python/controls/forms/dropdown-add-items.py @@ -0,0 +1,20 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "Add items to dropdown options" + + def add_clicked(e): + d.options.append(ft.dropdown.Option(option_textbox.value)) + d.value = option_textbox.value + option_textbox.value = "" + page.update() + + d = ft.Dropdown() + option_textbox = ft.TextField(hint_text="Enter item name") + add = ft.ElevatedButton("Add", on_click=add_clicked) + + page.add(ft.Column(controls=[d, ft.Row(controls=[option_textbox, add])])) + + +ft.app(main) diff --git a/python/controls/forms/dropdown-random-icon.py b/python/controls/forms/dropdown-random-icon.py new file mode 100644 index 00000000..0f65ab7c --- /dev/null +++ b/python/controls/forms/dropdown-random-icon.py @@ -0,0 +1,34 @@ +import logging +import random +import flet as ft + +logging.basicConfig(level=logging.INFO) + + +def main(page: ft.Page): + dd_options = [] + + def dd_choice(e): + t.value = f"{dd.value} chosen" + page.update() + + def btn1_click(e): + icon = ft.Icon(ft.Icons.random()) + dd.options.append( + ft.dropdown.Option(text=f"{str(icon.name)[6:]}", content=icon) + ) + page.update() + + def btn2_click(e): + random.shuffle(dd_options) + page.update() + + btn1 = ft.ElevatedButton("Add random item to dropdown!", on_click=btn1_click) + btn2 = ft.ElevatedButton("Shuffle Dropdown items", on_click=btn2_click) + dd = ft.Dropdown(options=dd_options, on_change=dd_choice) + t = ft.Text() + + page.add(dd, btn1, btn2, t) + + +ft.app(main) diff --git a/python/controls/forms/dropdown.py b/python/controls/forms/dropdown.py index 463439c1..f85f9fcc 100644 --- a/python/controls/forms/dropdown.py +++ b/python/controls/forms/dropdown.py @@ -1,33 +1,30 @@ import logging -import os - -import flet -from flet import Dropdown, ElevatedButton, dropdown +import flet as ft logging.basicConfig(level=logging.INFO) -def main(page): - dd = Dropdown( +def main(page: ft.Page): + dd = ft.Dropdown( options=[ - dropdown.Option("a", "Item A"), - dropdown.Option("b", "Item B"), - dropdown.Option("c", "Item C"), + ft.dropdown.Option("a", "Item A"), + ft.dropdown.Option("b", "Item B"), + ft.dropdown.Option("c", "Item C"), ] ) def btn2_click(e): - dd.options.append(dropdown.Option("d", "Item D")) + dd.options.append(ft.dropdown.Option("d", "Item D")) page.update() def btn3_click(e): dd.options[1].text = "Item Blah Blah Blah" page.update() - btn2 = ElevatedButton("Add new item!", on_click=btn2_click) - btn3 = ElevatedButton("Change second item", on_click=btn3_click) + btn2 = ft.ElevatedButton("Add new item!", on_click=btn2_click) + btn3 = ft.ElevatedButton("Change second item", on_click=btn3_click) page.add(dd, btn2, btn3) -flet.app(target=main) +ft.app(main) From 3a528a64a273229f7fc663e70db4d75e1ffc4161 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 14 Feb 2025 17:13:55 -0800 Subject: [PATCH 24/81] synchronize examples folder with documentation --- .../controls/{animation => animations}/animate-button-on-hover.py | 0 python/controls/{animation => animations}/animate-container.py | 0 .../{animation => animations}/animate-image-switch-buffered.py | 0 python/controls/{animation => animations}/animate-image-switch.py | 0 python/controls/{animation => animations}/animate-offset.py | 0 python/controls/{animation => animations}/animate-opacity.py | 0 python/controls/{animation => animations}/animate-position.py | 0 python/controls/{animation => animations}/animate-rotation.py | 0 python/controls/{animation => animations}/animate-scale-docs.py | 0 python/controls/{animation => animations}/animate-scale.py | 0 .../{animation => animations}/animate-single-container.py | 0 python/controls/{animation => animations}/animated-left-menu.py | 0 python/controls/{animation => animations}/animated-switcher.py | 0 python/controls/{animation => animations}/bursting-flet.py | 0 python/controls/{animation => animations}/image-slideshow.py | 0 python/controls/{animation => animations}/lottie-basic.py | 0 python/controls/{animation => animations}/rive-basic.py | 0 python/controls/{animation => animations}/rocket.py | 0 .../elevated-button}/basic-elevated-buttons.py | 0 .../elevated-button}/button-shapes.py | 0 .../elevated-button}/elevated-button-with-click-event.py | 0 .../elevated-button}/elevated-buttons-with-custom-content.py | 0 .../elevated-button}/elevated-buttons-with-icons.py | 0 .../elevated-button}/styled-button.py | 0 python/controls/{ => buttons}/floating-action-button/fab.py | 0 .../icon-button}/icon-button-with-click-event.py | 0 .../{icon-buttons => buttons/icon-button}/icon-buttons.py | 0 .../{icon-buttons => buttons/icon-button}/toggle-icon-button.py | 0 .../outlined-button}/basic-outlined-buttons.py | 0 .../outlined-button}/outlined-button-with-click-event.py | 0 .../outlined-button}/outlined-buttons-with-custom-content.py | 0 .../outlined-button}/outlined-buttons-with-icons.py | 0 .../popup-menu-button}/popup-button.py | 0 .../{text-buttons => buttons/text-button}/basic-text-buttons.py | 0 .../text-button}/text-button-with-click-event.py | 0 .../text-button}/text-buttons-with-custom-content.py | 0 .../text-button}/text-buttons-with-icons.py | 0 .../matplotlib-chart}/mpl-barchart.py | 0 .../{charts-matplotlib => charts/matplotlib-chart}/mpl-contour.py | 0 .../{charts-matplotlib => charts/matplotlib-chart}/mpl-finance.py | 0 .../matplotlib-chart}/mpl-linechart.py | 0 .../{charts-matplotlib => charts/matplotlib-chart}/mpl-scatter.py | 0 .../{charts-plotly => charts/plotly-chart}/plotly-barchart.py | 0 .../{charts-plotly => charts/plotly-chart}/plotly-boxchart.py | 0 .../{charts-plotly => charts/plotly-chart}/plotly-linechart.py | 0 .../{charts-plotly => charts/plotly-chart}/plotly-piechart.py | 0 .../{ => cupertino}/cupertino-buttons/cupertino-button.py | 0 .../cupertino-buttons/cupertino-segmented-button-padding.py | 0 .../cupertino-buttons/cupertino-segmented-button.py | 0 .../cupertino-buttons/cupertino-sliding-segmented-button.py | 0 .../controls/{ => dialogs-alerts-panels}/alert-dialog/dialogs.py | 0 python/controls/{ => dialogs-alerts-panels}/banner/banner-test.py | 0 .../bottom-sheet/modal-bottom-sheet.py | 0 .../{ => dialogs-alerts-panels}/snack-bar/simple-snack.py | 0 python/controls/{ => information-displays}/canvas/canvas-face.py | 0 .../canvas/canvas-flet-brush-on-image.py | 0 .../{ => information-displays}/canvas/canvas-flet-brush.py | 0 .../{ => information-displays}/canvas/canvas-flet-logo.py | 0 .../{ => information-displays}/canvas/canvas-gradients.py | 0 .../{ => information-displays}/canvas/canvas-path-bezier.py | 0 .../{ => information-displays}/canvas/canvas-path-triangles.py | 0 .../controls/{ => information-displays}/canvas/canvas-resize.py | 0 python/controls/{ => information-displays}/canvas/canvas-text.py | 0 .../{ => information-displays}/circle-avatar/avatar-test.py | 0 python/controls/{ => information-displays}/icon/icons-test.py | 0 .../{ => information-displays}/image/custom-svg-animation.py | 0 python/controls/{ => information-displays}/image/image-base64.py | 0 python/controls/{ => information-displays}/image/images.py | 0 python/controls/{ => information-displays}/image/svg-image.py | 0 python/controls/{ => information-displays}/image/svg-lucide.py | 0 .../{ => information-displays}/markdown/markdown-basic.py | 0 .../markdown/markdown-code-highlight.py | 0 .../{ => information-displays}/markdown/markdown-custom-theme.py | 0 .../{ => information-displays}/markdown/markdown-listviews.py | 0 .../{ => information-displays}/progress-bar/progress-bar.py | 0 .../progress-ring/gauge-with-progress.py | 0 .../{ => information-displays}/progress-ring/progress-ring.py | 0 .../{ => information-displays}/text/richtext-borders-stroke.py | 0 .../controls/{ => information-displays}/text/richtext-gradient.py | 0 python/controls/{ => information-displays}/text/richtext.py | 0 .../{ => information-displays}/text/text-custom-styles.py | 0 .../controls/{ => information-displays}/text/text-theme-styles.py | 0 .../{ => information-displays}/text/variable-weight-font.py | 0 .../{forms => input-and-selections/checkbox}/checkbox-basic.py | 0 .../checkbox}/checkbox-with-event.py | 0 .../{forms => input-and-selections/checkbox}/styled-checkbox.py | 0 .../{ => input-and-selections}/dropdown/basic-dropdown.py | 0 .../controls/{ => input-and-selections}/dropdown/change-items.py | 0 .../dropdown}/dropdown-add-items.py | 0 .../dropdown}/dropdown-random-icon.py | 0 .../controls/{forms => input-and-selections/dropdown}/dropdown.py | 0 .../{ => input-and-selections}/dropdown/label-and-hint.py | 0 .../{ => input-and-selections}/dropdown/on-change-event.py | 0 .../{ => input-and-selections}/dropdown/styled-dropdown.py | 0 .../{forms => input-and-selections/dropdown}/styled-dropdowns.py | 0 .../{forms => input-and-selections}/form-controls-misc.py | 0 .../{forms => input-and-selections/radio}/radiogroup-basic.py | 0 .../radio}/radiogroup-with-event.py | 0 .../{forms => input-and-selections/radio}/styled-radio.py | 0 .../{forms => input-and-selections/slider}/slider-basic.py | 0 .../slider}/slider-random-change.py | 0 .../{forms => input-and-selections/slider}/slider-values.py | 0 .../{forms => input-and-selections/slider}/slider-with-change.py | 0 .../{forms => input-and-selections/switch}/switch-basic.py | 0 .../{forms => input-and-selections/switch}/switch-with-event.py | 0 .../text-field}/basic-textfields.py | 0 .../{textfield => input-and-selections/text-field}/multiline.py | 0 .../{textfield => input-and-selections/text-field}/on-change.py | 0 .../{textfield => input-and-selections/text-field}/password.py | 0 .../text-field}/prefix-suffix.py | 0 .../text-field}/styled-textfield.py | 0 .../text-field}/textfield-style.py | 0 .../{forms => input-and-selections/text-field}/textfields.py | 0 .../{textfield => input-and-selections/text-field}/underlined.py | 0 python/controls/{ => layout}/card/card-with-buttons.py | 0 python/controls/{ => layout}/column/column-alignment.py | 0 python/controls/{ => layout}/column/column-horiz-alignment.py | 0 python/controls/{ => layout}/column/column-infinite-list.py | 0 python/controls/{ => layout}/column/column-scroll-misc.py | 0 python/controls/{ => layout}/column/column-scroll-to-key.py | 0 python/controls/{ => layout}/column/column-scroll.py | 0 python/controls/{ => layout}/column/column-spacing.py | 0 python/controls/{ => layout}/column/column-wrap.py | 0 python/controls/{ => layout}/column/scroll-events.py | 0 python/controls/{ => layout}/container/clickable-container.py | 0 python/controls/{ => layout}/container/container-blur.py | 0 python/controls/{ => layout}/container/container-margin.py | 0 python/controls/{ => layout}/container/container-on-resize.py | 0 python/controls/{ => layout}/container/container-padding.py | 0 python/controls/{ => layout}/container/container-shadow.py | 0 python/controls/{ => layout}/container/containers-alignment.py | 0 .../{ => layout}/container/containers-background-color.py | 0 python/controls/{ => layout}/container/containers-borders.py | 0 python/controls/{ => layout}/container/gradients.py | 0 python/controls/{ => layout}/container/linear-gradient.py | 0 python/controls/{ => layout}/container/nested-themes-simple.py | 0 python/controls/{ => layout}/container/nested-themes.py | 0 python/controls/{ => layout}/container/radial-gradient.py | 0 python/controls/{ => layout}/container/sweep-gradient.py | 0 .../{datatable => layout/data-table}/datatable-no-source.py | 0 python/controls/{ => layout}/divider/divider-horiz.py | 0 python/controls/{gridview => layout/grid-view}/photo-gallery.py | 0 python/controls/{listtile => layout/list-tile}/listtiles.py | 0 python/controls/{listview => layout/list-view}/listview-scroll.py | 0 python/controls/{ => layout}/page/app-exit-confirm-dialog.py | 0 python/controls/{ => layout}/page/keyboard-events.py | 0 python/controls/{ => layout}/page/splash-test.py | 0 python/controls/{ => layout}/page/window-hidden-on-start.py | 0 python/controls/{ => layout}/responsive-row/responsive-layout.py | 0 python/controls/{ => layout}/row/row-alignment.py | 0 python/controls/{ => layout}/row/row-spacing.py | 0 python/controls/{ => layout}/row/row-vert-alignment.py | 0 python/controls/{ => layout}/row/row-wrap.py | 0 python/controls/{ => layout}/stack/absolute-positioned.py | 0 python/controls/{ => layout}/stack/avatar-with-status.py | 0 python/controls/{ => layout}/stack/image-title.py | 0 python/controls/{ => layout}/tabs/tabs-dynamic.py | 0 python/controls/{ => layout}/tabs/tabs-simple.py | 0 python/controls/{ => layout}/vertical-divider/divider-vert.py | 0 python/controls/{appbar => navigation/app-bar}/appbar-simple.py | 0 .../{appbar => navigation/app-bar}/appbar-theme-material.py | 0 python/controls/{appbar => navigation/app-bar}/bottom-appbar.py | 0 .../{ => navigation}/navigation-bar/navigation-bar-sample.py | 0 .../controls/{ => navigation}/navigation-rail/nav-rail-layout.py | 0 python/controls/{ => navigation}/navigation-rail/nav-rail-test.py | 0 python/controls/{ => utility}/audio/audio-autoplay.py | 0 python/controls/{ => utility}/audio/audio-player-async.py | 0 python/controls/{ => utility}/audio/audio-player-slider.py | 0 python/controls/{ => utility}/audio/audio-player.py | 0 .../{drag-and-drop => utility/drag-target}/drag-drop-colors.py | 0 .../{drag-and-drop => utility/drag-target}/drag-drop-nesting.py | 0 .../{drag-and-drop => utility/drag-target}/drag-drop-ordering.py | 0 .../controls/{ => utility}/file-picker/file-picker-all-modes.py | 0 .../{ => utility}/file-picker/file-picker-upload-progress.py | 0 .../gesture-detector/draggable-container_change_mouse_cursor.py | 0 .../{ => utility}/gesture-detector/draggable-containers.py | 0 python/controls/{ => utility}/gesture-detector/gestures-tester.py | 0 python/controls/{ => utility}/shader-mask/shader-mask-gradient.py | 0 python/controls/{ => utility}/shader-mask/shader-mask-image.py | 0 .../{ => utility}/shader-mask/shader-mask-single-image.py | 0 python/controls/{ => utility}/window-drag-area/no-frame-window.py | 0 181 files changed, 0 insertions(+), 0 deletions(-) rename python/controls/{animation => animations}/animate-button-on-hover.py (100%) rename python/controls/{animation => animations}/animate-container.py (100%) rename python/controls/{animation => animations}/animate-image-switch-buffered.py (100%) rename python/controls/{animation => animations}/animate-image-switch.py (100%) rename python/controls/{animation => animations}/animate-offset.py (100%) rename python/controls/{animation => animations}/animate-opacity.py (100%) rename python/controls/{animation => animations}/animate-position.py (100%) rename python/controls/{animation => animations}/animate-rotation.py (100%) rename python/controls/{animation => animations}/animate-scale-docs.py (100%) rename python/controls/{animation => animations}/animate-scale.py (100%) rename python/controls/{animation => animations}/animate-single-container.py (100%) rename python/controls/{animation => animations}/animated-left-menu.py (100%) rename python/controls/{animation => animations}/animated-switcher.py (100%) rename python/controls/{animation => animations}/bursting-flet.py (100%) rename python/controls/{animation => animations}/image-slideshow.py (100%) rename python/controls/{animation => animations}/lottie-basic.py (100%) rename python/controls/{animation => animations}/rive-basic.py (100%) rename python/controls/{animation => animations}/rocket.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/basic-elevated-buttons.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/button-shapes.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/elevated-button-with-click-event.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/elevated-buttons-with-custom-content.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/elevated-buttons-with-icons.py (100%) rename python/controls/{elevated-buttons => buttons/elevated-button}/styled-button.py (100%) rename python/controls/{ => buttons}/floating-action-button/fab.py (100%) rename python/controls/{icon-buttons => buttons/icon-button}/icon-button-with-click-event.py (100%) rename python/controls/{icon-buttons => buttons/icon-button}/icon-buttons.py (100%) rename python/controls/{icon-buttons => buttons/icon-button}/toggle-icon-button.py (100%) rename python/controls/{outlined-buttons => buttons/outlined-button}/basic-outlined-buttons.py (100%) rename python/controls/{outlined-buttons => buttons/outlined-button}/outlined-button-with-click-event.py (100%) rename python/controls/{outlined-buttons => buttons/outlined-button}/outlined-buttons-with-custom-content.py (100%) rename python/controls/{outlined-buttons => buttons/outlined-button}/outlined-buttons-with-icons.py (100%) rename python/controls/{popupmenu-button => buttons/popup-menu-button}/popup-button.py (100%) rename python/controls/{text-buttons => buttons/text-button}/basic-text-buttons.py (100%) rename python/controls/{text-buttons => buttons/text-button}/text-button-with-click-event.py (100%) rename python/controls/{text-buttons => buttons/text-button}/text-buttons-with-custom-content.py (100%) rename python/controls/{text-buttons => buttons/text-button}/text-buttons-with-icons.py (100%) rename python/controls/{charts-matplotlib => charts/matplotlib-chart}/mpl-barchart.py (100%) rename python/controls/{charts-matplotlib => charts/matplotlib-chart}/mpl-contour.py (100%) rename python/controls/{charts-matplotlib => charts/matplotlib-chart}/mpl-finance.py (100%) rename python/controls/{charts-matplotlib => charts/matplotlib-chart}/mpl-linechart.py (100%) rename python/controls/{charts-matplotlib => charts/matplotlib-chart}/mpl-scatter.py (100%) rename python/controls/{charts-plotly => charts/plotly-chart}/plotly-barchart.py (100%) rename python/controls/{charts-plotly => charts/plotly-chart}/plotly-boxchart.py (100%) rename python/controls/{charts-plotly => charts/plotly-chart}/plotly-linechart.py (100%) rename python/controls/{charts-plotly => charts/plotly-chart}/plotly-piechart.py (100%) rename python/controls/{ => cupertino}/cupertino-buttons/cupertino-button.py (100%) rename python/controls/{ => cupertino}/cupertino-buttons/cupertino-segmented-button-padding.py (100%) rename python/controls/{ => cupertino}/cupertino-buttons/cupertino-segmented-button.py (100%) rename python/controls/{ => cupertino}/cupertino-buttons/cupertino-sliding-segmented-button.py (100%) rename python/controls/{ => dialogs-alerts-panels}/alert-dialog/dialogs.py (100%) rename python/controls/{ => dialogs-alerts-panels}/banner/banner-test.py (100%) rename python/controls/{ => dialogs-alerts-panels}/bottom-sheet/modal-bottom-sheet.py (100%) rename python/controls/{ => dialogs-alerts-panels}/snack-bar/simple-snack.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-face.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-flet-brush-on-image.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-flet-brush.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-flet-logo.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-gradients.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-path-bezier.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-path-triangles.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-resize.py (100%) rename python/controls/{ => information-displays}/canvas/canvas-text.py (100%) rename python/controls/{ => information-displays}/circle-avatar/avatar-test.py (100%) rename python/controls/{ => information-displays}/icon/icons-test.py (100%) rename python/controls/{ => information-displays}/image/custom-svg-animation.py (100%) rename python/controls/{ => information-displays}/image/image-base64.py (100%) rename python/controls/{ => information-displays}/image/images.py (100%) rename python/controls/{ => information-displays}/image/svg-image.py (100%) rename python/controls/{ => information-displays}/image/svg-lucide.py (100%) rename python/controls/{ => information-displays}/markdown/markdown-basic.py (100%) rename python/controls/{ => information-displays}/markdown/markdown-code-highlight.py (100%) rename python/controls/{ => information-displays}/markdown/markdown-custom-theme.py (100%) rename python/controls/{ => information-displays}/markdown/markdown-listviews.py (100%) rename python/controls/{ => information-displays}/progress-bar/progress-bar.py (100%) rename python/controls/{ => information-displays}/progress-ring/gauge-with-progress.py (100%) rename python/controls/{ => information-displays}/progress-ring/progress-ring.py (100%) rename python/controls/{ => information-displays}/text/richtext-borders-stroke.py (100%) rename python/controls/{ => information-displays}/text/richtext-gradient.py (100%) rename python/controls/{ => information-displays}/text/richtext.py (100%) rename python/controls/{ => information-displays}/text/text-custom-styles.py (100%) rename python/controls/{ => information-displays}/text/text-theme-styles.py (100%) rename python/controls/{ => information-displays}/text/variable-weight-font.py (100%) rename python/controls/{forms => input-and-selections/checkbox}/checkbox-basic.py (100%) rename python/controls/{forms => input-and-selections/checkbox}/checkbox-with-event.py (100%) rename python/controls/{forms => input-and-selections/checkbox}/styled-checkbox.py (100%) rename python/controls/{ => input-and-selections}/dropdown/basic-dropdown.py (100%) rename python/controls/{ => input-and-selections}/dropdown/change-items.py (100%) rename python/controls/{forms => input-and-selections/dropdown}/dropdown-add-items.py (100%) rename python/controls/{forms => input-and-selections/dropdown}/dropdown-random-icon.py (100%) rename python/controls/{forms => input-and-selections/dropdown}/dropdown.py (100%) rename python/controls/{ => input-and-selections}/dropdown/label-and-hint.py (100%) rename python/controls/{ => input-and-selections}/dropdown/on-change-event.py (100%) rename python/controls/{ => input-and-selections}/dropdown/styled-dropdown.py (100%) rename python/controls/{forms => input-and-selections/dropdown}/styled-dropdowns.py (100%) rename python/controls/{forms => input-and-selections}/form-controls-misc.py (100%) rename python/controls/{forms => input-and-selections/radio}/radiogroup-basic.py (100%) rename python/controls/{forms => input-and-selections/radio}/radiogroup-with-event.py (100%) rename python/controls/{forms => input-and-selections/radio}/styled-radio.py (100%) rename python/controls/{forms => input-and-selections/slider}/slider-basic.py (100%) rename python/controls/{forms => input-and-selections/slider}/slider-random-change.py (100%) rename python/controls/{forms => input-and-selections/slider}/slider-values.py (100%) rename python/controls/{forms => input-and-selections/slider}/slider-with-change.py (100%) rename python/controls/{forms => input-and-selections/switch}/switch-basic.py (100%) rename python/controls/{forms => input-and-selections/switch}/switch-with-event.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/basic-textfields.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/multiline.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/on-change.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/password.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/prefix-suffix.py (100%) rename python/controls/{forms => input-and-selections/text-field}/styled-textfield.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/textfield-style.py (100%) rename python/controls/{forms => input-and-selections/text-field}/textfields.py (100%) rename python/controls/{textfield => input-and-selections/text-field}/underlined.py (100%) rename python/controls/{ => layout}/card/card-with-buttons.py (100%) rename python/controls/{ => layout}/column/column-alignment.py (100%) rename python/controls/{ => layout}/column/column-horiz-alignment.py (100%) rename python/controls/{ => layout}/column/column-infinite-list.py (100%) rename python/controls/{ => layout}/column/column-scroll-misc.py (100%) rename python/controls/{ => layout}/column/column-scroll-to-key.py (100%) rename python/controls/{ => layout}/column/column-scroll.py (100%) rename python/controls/{ => layout}/column/column-spacing.py (100%) rename python/controls/{ => layout}/column/column-wrap.py (100%) rename python/controls/{ => layout}/column/scroll-events.py (100%) rename python/controls/{ => layout}/container/clickable-container.py (100%) rename python/controls/{ => layout}/container/container-blur.py (100%) rename python/controls/{ => layout}/container/container-margin.py (100%) rename python/controls/{ => layout}/container/container-on-resize.py (100%) rename python/controls/{ => layout}/container/container-padding.py (100%) rename python/controls/{ => layout}/container/container-shadow.py (100%) rename python/controls/{ => layout}/container/containers-alignment.py (100%) rename python/controls/{ => layout}/container/containers-background-color.py (100%) rename python/controls/{ => layout}/container/containers-borders.py (100%) rename python/controls/{ => layout}/container/gradients.py (100%) rename python/controls/{ => layout}/container/linear-gradient.py (100%) rename python/controls/{ => layout}/container/nested-themes-simple.py (100%) rename python/controls/{ => layout}/container/nested-themes.py (100%) rename python/controls/{ => layout}/container/radial-gradient.py (100%) rename python/controls/{ => layout}/container/sweep-gradient.py (100%) rename python/controls/{datatable => layout/data-table}/datatable-no-source.py (100%) rename python/controls/{ => layout}/divider/divider-horiz.py (100%) rename python/controls/{gridview => layout/grid-view}/photo-gallery.py (100%) rename python/controls/{listtile => layout/list-tile}/listtiles.py (100%) rename python/controls/{listview => layout/list-view}/listview-scroll.py (100%) rename python/controls/{ => layout}/page/app-exit-confirm-dialog.py (100%) rename python/controls/{ => layout}/page/keyboard-events.py (100%) rename python/controls/{ => layout}/page/splash-test.py (100%) rename python/controls/{ => layout}/page/window-hidden-on-start.py (100%) rename python/controls/{ => layout}/responsive-row/responsive-layout.py (100%) rename python/controls/{ => layout}/row/row-alignment.py (100%) rename python/controls/{ => layout}/row/row-spacing.py (100%) rename python/controls/{ => layout}/row/row-vert-alignment.py (100%) rename python/controls/{ => layout}/row/row-wrap.py (100%) rename python/controls/{ => layout}/stack/absolute-positioned.py (100%) rename python/controls/{ => layout}/stack/avatar-with-status.py (100%) rename python/controls/{ => layout}/stack/image-title.py (100%) rename python/controls/{ => layout}/tabs/tabs-dynamic.py (100%) rename python/controls/{ => layout}/tabs/tabs-simple.py (100%) rename python/controls/{ => layout}/vertical-divider/divider-vert.py (100%) rename python/controls/{appbar => navigation/app-bar}/appbar-simple.py (100%) rename python/controls/{appbar => navigation/app-bar}/appbar-theme-material.py (100%) rename python/controls/{appbar => navigation/app-bar}/bottom-appbar.py (100%) rename python/controls/{ => navigation}/navigation-bar/navigation-bar-sample.py (100%) rename python/controls/{ => navigation}/navigation-rail/nav-rail-layout.py (100%) rename python/controls/{ => navigation}/navigation-rail/nav-rail-test.py (100%) rename python/controls/{ => utility}/audio/audio-autoplay.py (100%) rename python/controls/{ => utility}/audio/audio-player-async.py (100%) rename python/controls/{ => utility}/audio/audio-player-slider.py (100%) rename python/controls/{ => utility}/audio/audio-player.py (100%) rename python/controls/{drag-and-drop => utility/drag-target}/drag-drop-colors.py (100%) rename python/controls/{drag-and-drop => utility/drag-target}/drag-drop-nesting.py (100%) rename python/controls/{drag-and-drop => utility/drag-target}/drag-drop-ordering.py (100%) rename python/controls/{ => utility}/file-picker/file-picker-all-modes.py (100%) rename python/controls/{ => utility}/file-picker/file-picker-upload-progress.py (100%) rename python/controls/{ => utility}/gesture-detector/draggable-container_change_mouse_cursor.py (100%) rename python/controls/{ => utility}/gesture-detector/draggable-containers.py (100%) rename python/controls/{ => utility}/gesture-detector/gestures-tester.py (100%) rename python/controls/{ => utility}/shader-mask/shader-mask-gradient.py (100%) rename python/controls/{ => utility}/shader-mask/shader-mask-image.py (100%) rename python/controls/{ => utility}/shader-mask/shader-mask-single-image.py (100%) rename python/controls/{ => utility}/window-drag-area/no-frame-window.py (100%) diff --git a/python/controls/animation/animate-button-on-hover.py b/python/controls/animations/animate-button-on-hover.py similarity index 100% rename from python/controls/animation/animate-button-on-hover.py rename to python/controls/animations/animate-button-on-hover.py diff --git a/python/controls/animation/animate-container.py b/python/controls/animations/animate-container.py similarity index 100% rename from python/controls/animation/animate-container.py rename to python/controls/animations/animate-container.py diff --git a/python/controls/animation/animate-image-switch-buffered.py b/python/controls/animations/animate-image-switch-buffered.py similarity index 100% rename from python/controls/animation/animate-image-switch-buffered.py rename to python/controls/animations/animate-image-switch-buffered.py diff --git a/python/controls/animation/animate-image-switch.py b/python/controls/animations/animate-image-switch.py similarity index 100% rename from python/controls/animation/animate-image-switch.py rename to python/controls/animations/animate-image-switch.py diff --git a/python/controls/animation/animate-offset.py b/python/controls/animations/animate-offset.py similarity index 100% rename from python/controls/animation/animate-offset.py rename to python/controls/animations/animate-offset.py diff --git a/python/controls/animation/animate-opacity.py b/python/controls/animations/animate-opacity.py similarity index 100% rename from python/controls/animation/animate-opacity.py rename to python/controls/animations/animate-opacity.py diff --git a/python/controls/animation/animate-position.py b/python/controls/animations/animate-position.py similarity index 100% rename from python/controls/animation/animate-position.py rename to python/controls/animations/animate-position.py diff --git a/python/controls/animation/animate-rotation.py b/python/controls/animations/animate-rotation.py similarity index 100% rename from python/controls/animation/animate-rotation.py rename to python/controls/animations/animate-rotation.py diff --git a/python/controls/animation/animate-scale-docs.py b/python/controls/animations/animate-scale-docs.py similarity index 100% rename from python/controls/animation/animate-scale-docs.py rename to python/controls/animations/animate-scale-docs.py diff --git a/python/controls/animation/animate-scale.py b/python/controls/animations/animate-scale.py similarity index 100% rename from python/controls/animation/animate-scale.py rename to python/controls/animations/animate-scale.py diff --git a/python/controls/animation/animate-single-container.py b/python/controls/animations/animate-single-container.py similarity index 100% rename from python/controls/animation/animate-single-container.py rename to python/controls/animations/animate-single-container.py diff --git a/python/controls/animation/animated-left-menu.py b/python/controls/animations/animated-left-menu.py similarity index 100% rename from python/controls/animation/animated-left-menu.py rename to python/controls/animations/animated-left-menu.py diff --git a/python/controls/animation/animated-switcher.py b/python/controls/animations/animated-switcher.py similarity index 100% rename from python/controls/animation/animated-switcher.py rename to python/controls/animations/animated-switcher.py diff --git a/python/controls/animation/bursting-flet.py b/python/controls/animations/bursting-flet.py similarity index 100% rename from python/controls/animation/bursting-flet.py rename to python/controls/animations/bursting-flet.py diff --git a/python/controls/animation/image-slideshow.py b/python/controls/animations/image-slideshow.py similarity index 100% rename from python/controls/animation/image-slideshow.py rename to python/controls/animations/image-slideshow.py diff --git a/python/controls/animation/lottie-basic.py b/python/controls/animations/lottie-basic.py similarity index 100% rename from python/controls/animation/lottie-basic.py rename to python/controls/animations/lottie-basic.py diff --git a/python/controls/animation/rive-basic.py b/python/controls/animations/rive-basic.py similarity index 100% rename from python/controls/animation/rive-basic.py rename to python/controls/animations/rive-basic.py diff --git a/python/controls/animation/rocket.py b/python/controls/animations/rocket.py similarity index 100% rename from python/controls/animation/rocket.py rename to python/controls/animations/rocket.py diff --git a/python/controls/elevated-buttons/basic-elevated-buttons.py b/python/controls/buttons/elevated-button/basic-elevated-buttons.py similarity index 100% rename from python/controls/elevated-buttons/basic-elevated-buttons.py rename to python/controls/buttons/elevated-button/basic-elevated-buttons.py diff --git a/python/controls/elevated-buttons/button-shapes.py b/python/controls/buttons/elevated-button/button-shapes.py similarity index 100% rename from python/controls/elevated-buttons/button-shapes.py rename to python/controls/buttons/elevated-button/button-shapes.py diff --git a/python/controls/elevated-buttons/elevated-button-with-click-event.py b/python/controls/buttons/elevated-button/elevated-button-with-click-event.py similarity index 100% rename from python/controls/elevated-buttons/elevated-button-with-click-event.py rename to python/controls/buttons/elevated-button/elevated-button-with-click-event.py diff --git a/python/controls/elevated-buttons/elevated-buttons-with-custom-content.py b/python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py similarity index 100% rename from python/controls/elevated-buttons/elevated-buttons-with-custom-content.py rename to python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py diff --git a/python/controls/elevated-buttons/elevated-buttons-with-icons.py b/python/controls/buttons/elevated-button/elevated-buttons-with-icons.py similarity index 100% rename from python/controls/elevated-buttons/elevated-buttons-with-icons.py rename to python/controls/buttons/elevated-button/elevated-buttons-with-icons.py diff --git a/python/controls/elevated-buttons/styled-button.py b/python/controls/buttons/elevated-button/styled-button.py similarity index 100% rename from python/controls/elevated-buttons/styled-button.py rename to python/controls/buttons/elevated-button/styled-button.py diff --git a/python/controls/floating-action-button/fab.py b/python/controls/buttons/floating-action-button/fab.py similarity index 100% rename from python/controls/floating-action-button/fab.py rename to python/controls/buttons/floating-action-button/fab.py diff --git a/python/controls/icon-buttons/icon-button-with-click-event.py b/python/controls/buttons/icon-button/icon-button-with-click-event.py similarity index 100% rename from python/controls/icon-buttons/icon-button-with-click-event.py rename to python/controls/buttons/icon-button/icon-button-with-click-event.py diff --git a/python/controls/icon-buttons/icon-buttons.py b/python/controls/buttons/icon-button/icon-buttons.py similarity index 100% rename from python/controls/icon-buttons/icon-buttons.py rename to python/controls/buttons/icon-button/icon-buttons.py diff --git a/python/controls/icon-buttons/toggle-icon-button.py b/python/controls/buttons/icon-button/toggle-icon-button.py similarity index 100% rename from python/controls/icon-buttons/toggle-icon-button.py rename to python/controls/buttons/icon-button/toggle-icon-button.py diff --git a/python/controls/outlined-buttons/basic-outlined-buttons.py b/python/controls/buttons/outlined-button/basic-outlined-buttons.py similarity index 100% rename from python/controls/outlined-buttons/basic-outlined-buttons.py rename to python/controls/buttons/outlined-button/basic-outlined-buttons.py diff --git a/python/controls/outlined-buttons/outlined-button-with-click-event.py b/python/controls/buttons/outlined-button/outlined-button-with-click-event.py similarity index 100% rename from python/controls/outlined-buttons/outlined-button-with-click-event.py rename to python/controls/buttons/outlined-button/outlined-button-with-click-event.py diff --git a/python/controls/outlined-buttons/outlined-buttons-with-custom-content.py b/python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py similarity index 100% rename from python/controls/outlined-buttons/outlined-buttons-with-custom-content.py rename to python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py diff --git a/python/controls/outlined-buttons/outlined-buttons-with-icons.py b/python/controls/buttons/outlined-button/outlined-buttons-with-icons.py similarity index 100% rename from python/controls/outlined-buttons/outlined-buttons-with-icons.py rename to python/controls/buttons/outlined-button/outlined-buttons-with-icons.py diff --git a/python/controls/popupmenu-button/popup-button.py b/python/controls/buttons/popup-menu-button/popup-button.py similarity index 100% rename from python/controls/popupmenu-button/popup-button.py rename to python/controls/buttons/popup-menu-button/popup-button.py diff --git a/python/controls/text-buttons/basic-text-buttons.py b/python/controls/buttons/text-button/basic-text-buttons.py similarity index 100% rename from python/controls/text-buttons/basic-text-buttons.py rename to python/controls/buttons/text-button/basic-text-buttons.py diff --git a/python/controls/text-buttons/text-button-with-click-event.py b/python/controls/buttons/text-button/text-button-with-click-event.py similarity index 100% rename from python/controls/text-buttons/text-button-with-click-event.py rename to python/controls/buttons/text-button/text-button-with-click-event.py diff --git a/python/controls/text-buttons/text-buttons-with-custom-content.py b/python/controls/buttons/text-button/text-buttons-with-custom-content.py similarity index 100% rename from python/controls/text-buttons/text-buttons-with-custom-content.py rename to python/controls/buttons/text-button/text-buttons-with-custom-content.py diff --git a/python/controls/text-buttons/text-buttons-with-icons.py b/python/controls/buttons/text-button/text-buttons-with-icons.py similarity index 100% rename from python/controls/text-buttons/text-buttons-with-icons.py rename to python/controls/buttons/text-button/text-buttons-with-icons.py diff --git a/python/controls/charts-matplotlib/mpl-barchart.py b/python/controls/charts/matplotlib-chart/mpl-barchart.py similarity index 100% rename from python/controls/charts-matplotlib/mpl-barchart.py rename to python/controls/charts/matplotlib-chart/mpl-barchart.py diff --git a/python/controls/charts-matplotlib/mpl-contour.py b/python/controls/charts/matplotlib-chart/mpl-contour.py similarity index 100% rename from python/controls/charts-matplotlib/mpl-contour.py rename to python/controls/charts/matplotlib-chart/mpl-contour.py diff --git a/python/controls/charts-matplotlib/mpl-finance.py b/python/controls/charts/matplotlib-chart/mpl-finance.py similarity index 100% rename from python/controls/charts-matplotlib/mpl-finance.py rename to python/controls/charts/matplotlib-chart/mpl-finance.py diff --git a/python/controls/charts-matplotlib/mpl-linechart.py b/python/controls/charts/matplotlib-chart/mpl-linechart.py similarity index 100% rename from python/controls/charts-matplotlib/mpl-linechart.py rename to python/controls/charts/matplotlib-chart/mpl-linechart.py diff --git a/python/controls/charts-matplotlib/mpl-scatter.py b/python/controls/charts/matplotlib-chart/mpl-scatter.py similarity index 100% rename from python/controls/charts-matplotlib/mpl-scatter.py rename to python/controls/charts/matplotlib-chart/mpl-scatter.py diff --git a/python/controls/charts-plotly/plotly-barchart.py b/python/controls/charts/plotly-chart/plotly-barchart.py similarity index 100% rename from python/controls/charts-plotly/plotly-barchart.py rename to python/controls/charts/plotly-chart/plotly-barchart.py diff --git a/python/controls/charts-plotly/plotly-boxchart.py b/python/controls/charts/plotly-chart/plotly-boxchart.py similarity index 100% rename from python/controls/charts-plotly/plotly-boxchart.py rename to python/controls/charts/plotly-chart/plotly-boxchart.py diff --git a/python/controls/charts-plotly/plotly-linechart.py b/python/controls/charts/plotly-chart/plotly-linechart.py similarity index 100% rename from python/controls/charts-plotly/plotly-linechart.py rename to python/controls/charts/plotly-chart/plotly-linechart.py diff --git a/python/controls/charts-plotly/plotly-piechart.py b/python/controls/charts/plotly-chart/plotly-piechart.py similarity index 100% rename from python/controls/charts-plotly/plotly-piechart.py rename to python/controls/charts/plotly-chart/plotly-piechart.py diff --git a/python/controls/cupertino-buttons/cupertino-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-button.py similarity index 100% rename from python/controls/cupertino-buttons/cupertino-button.py rename to python/controls/cupertino/cupertino-buttons/cupertino-button.py diff --git a/python/controls/cupertino-buttons/cupertino-segmented-button-padding.py b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py similarity index 100% rename from python/controls/cupertino-buttons/cupertino-segmented-button-padding.py rename to python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py diff --git a/python/controls/cupertino-buttons/cupertino-segmented-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button.py similarity index 100% rename from python/controls/cupertino-buttons/cupertino-segmented-button.py rename to python/controls/cupertino/cupertino-buttons/cupertino-segmented-button.py diff --git a/python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py similarity index 100% rename from python/controls/cupertino-buttons/cupertino-sliding-segmented-button.py rename to python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py diff --git a/python/controls/alert-dialog/dialogs.py b/python/controls/dialogs-alerts-panels/alert-dialog/dialogs.py similarity index 100% rename from python/controls/alert-dialog/dialogs.py rename to python/controls/dialogs-alerts-panels/alert-dialog/dialogs.py diff --git a/python/controls/banner/banner-test.py b/python/controls/dialogs-alerts-panels/banner/banner-test.py similarity index 100% rename from python/controls/banner/banner-test.py rename to python/controls/dialogs-alerts-panels/banner/banner-test.py diff --git a/python/controls/bottom-sheet/modal-bottom-sheet.py b/python/controls/dialogs-alerts-panels/bottom-sheet/modal-bottom-sheet.py similarity index 100% rename from python/controls/bottom-sheet/modal-bottom-sheet.py rename to python/controls/dialogs-alerts-panels/bottom-sheet/modal-bottom-sheet.py diff --git a/python/controls/snack-bar/simple-snack.py b/python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py similarity index 100% rename from python/controls/snack-bar/simple-snack.py rename to python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py diff --git a/python/controls/canvas/canvas-face.py b/python/controls/information-displays/canvas/canvas-face.py similarity index 100% rename from python/controls/canvas/canvas-face.py rename to python/controls/information-displays/canvas/canvas-face.py diff --git a/python/controls/canvas/canvas-flet-brush-on-image.py b/python/controls/information-displays/canvas/canvas-flet-brush-on-image.py similarity index 100% rename from python/controls/canvas/canvas-flet-brush-on-image.py rename to python/controls/information-displays/canvas/canvas-flet-brush-on-image.py diff --git a/python/controls/canvas/canvas-flet-brush.py b/python/controls/information-displays/canvas/canvas-flet-brush.py similarity index 100% rename from python/controls/canvas/canvas-flet-brush.py rename to python/controls/information-displays/canvas/canvas-flet-brush.py diff --git a/python/controls/canvas/canvas-flet-logo.py b/python/controls/information-displays/canvas/canvas-flet-logo.py similarity index 100% rename from python/controls/canvas/canvas-flet-logo.py rename to python/controls/information-displays/canvas/canvas-flet-logo.py diff --git a/python/controls/canvas/canvas-gradients.py b/python/controls/information-displays/canvas/canvas-gradients.py similarity index 100% rename from python/controls/canvas/canvas-gradients.py rename to python/controls/information-displays/canvas/canvas-gradients.py diff --git a/python/controls/canvas/canvas-path-bezier.py b/python/controls/information-displays/canvas/canvas-path-bezier.py similarity index 100% rename from python/controls/canvas/canvas-path-bezier.py rename to python/controls/information-displays/canvas/canvas-path-bezier.py diff --git a/python/controls/canvas/canvas-path-triangles.py b/python/controls/information-displays/canvas/canvas-path-triangles.py similarity index 100% rename from python/controls/canvas/canvas-path-triangles.py rename to python/controls/information-displays/canvas/canvas-path-triangles.py diff --git a/python/controls/canvas/canvas-resize.py b/python/controls/information-displays/canvas/canvas-resize.py similarity index 100% rename from python/controls/canvas/canvas-resize.py rename to python/controls/information-displays/canvas/canvas-resize.py diff --git a/python/controls/canvas/canvas-text.py b/python/controls/information-displays/canvas/canvas-text.py similarity index 100% rename from python/controls/canvas/canvas-text.py rename to python/controls/information-displays/canvas/canvas-text.py diff --git a/python/controls/circle-avatar/avatar-test.py b/python/controls/information-displays/circle-avatar/avatar-test.py similarity index 100% rename from python/controls/circle-avatar/avatar-test.py rename to python/controls/information-displays/circle-avatar/avatar-test.py diff --git a/python/controls/icon/icons-test.py b/python/controls/information-displays/icon/icons-test.py similarity index 100% rename from python/controls/icon/icons-test.py rename to python/controls/information-displays/icon/icons-test.py diff --git a/python/controls/image/custom-svg-animation.py b/python/controls/information-displays/image/custom-svg-animation.py similarity index 100% rename from python/controls/image/custom-svg-animation.py rename to python/controls/information-displays/image/custom-svg-animation.py diff --git a/python/controls/image/image-base64.py b/python/controls/information-displays/image/image-base64.py similarity index 100% rename from python/controls/image/image-base64.py rename to python/controls/information-displays/image/image-base64.py diff --git a/python/controls/image/images.py b/python/controls/information-displays/image/images.py similarity index 100% rename from python/controls/image/images.py rename to python/controls/information-displays/image/images.py diff --git a/python/controls/image/svg-image.py b/python/controls/information-displays/image/svg-image.py similarity index 100% rename from python/controls/image/svg-image.py rename to python/controls/information-displays/image/svg-image.py diff --git a/python/controls/image/svg-lucide.py b/python/controls/information-displays/image/svg-lucide.py similarity index 100% rename from python/controls/image/svg-lucide.py rename to python/controls/information-displays/image/svg-lucide.py diff --git a/python/controls/markdown/markdown-basic.py b/python/controls/information-displays/markdown/markdown-basic.py similarity index 100% rename from python/controls/markdown/markdown-basic.py rename to python/controls/information-displays/markdown/markdown-basic.py diff --git a/python/controls/markdown/markdown-code-highlight.py b/python/controls/information-displays/markdown/markdown-code-highlight.py similarity index 100% rename from python/controls/markdown/markdown-code-highlight.py rename to python/controls/information-displays/markdown/markdown-code-highlight.py diff --git a/python/controls/markdown/markdown-custom-theme.py b/python/controls/information-displays/markdown/markdown-custom-theme.py similarity index 100% rename from python/controls/markdown/markdown-custom-theme.py rename to python/controls/information-displays/markdown/markdown-custom-theme.py diff --git a/python/controls/markdown/markdown-listviews.py b/python/controls/information-displays/markdown/markdown-listviews.py similarity index 100% rename from python/controls/markdown/markdown-listviews.py rename to python/controls/information-displays/markdown/markdown-listviews.py diff --git a/python/controls/progress-bar/progress-bar.py b/python/controls/information-displays/progress-bar/progress-bar.py similarity index 100% rename from python/controls/progress-bar/progress-bar.py rename to python/controls/information-displays/progress-bar/progress-bar.py diff --git a/python/controls/progress-ring/gauge-with-progress.py b/python/controls/information-displays/progress-ring/gauge-with-progress.py similarity index 100% rename from python/controls/progress-ring/gauge-with-progress.py rename to python/controls/information-displays/progress-ring/gauge-with-progress.py diff --git a/python/controls/progress-ring/progress-ring.py b/python/controls/information-displays/progress-ring/progress-ring.py similarity index 100% rename from python/controls/progress-ring/progress-ring.py rename to python/controls/information-displays/progress-ring/progress-ring.py diff --git a/python/controls/text/richtext-borders-stroke.py b/python/controls/information-displays/text/richtext-borders-stroke.py similarity index 100% rename from python/controls/text/richtext-borders-stroke.py rename to python/controls/information-displays/text/richtext-borders-stroke.py diff --git a/python/controls/text/richtext-gradient.py b/python/controls/information-displays/text/richtext-gradient.py similarity index 100% rename from python/controls/text/richtext-gradient.py rename to python/controls/information-displays/text/richtext-gradient.py diff --git a/python/controls/text/richtext.py b/python/controls/information-displays/text/richtext.py similarity index 100% rename from python/controls/text/richtext.py rename to python/controls/information-displays/text/richtext.py diff --git a/python/controls/text/text-custom-styles.py b/python/controls/information-displays/text/text-custom-styles.py similarity index 100% rename from python/controls/text/text-custom-styles.py rename to python/controls/information-displays/text/text-custom-styles.py diff --git a/python/controls/text/text-theme-styles.py b/python/controls/information-displays/text/text-theme-styles.py similarity index 100% rename from python/controls/text/text-theme-styles.py rename to python/controls/information-displays/text/text-theme-styles.py diff --git a/python/controls/text/variable-weight-font.py b/python/controls/information-displays/text/variable-weight-font.py similarity index 100% rename from python/controls/text/variable-weight-font.py rename to python/controls/information-displays/text/variable-weight-font.py diff --git a/python/controls/forms/checkbox-basic.py b/python/controls/input-and-selections/checkbox/checkbox-basic.py similarity index 100% rename from python/controls/forms/checkbox-basic.py rename to python/controls/input-and-selections/checkbox/checkbox-basic.py diff --git a/python/controls/forms/checkbox-with-event.py b/python/controls/input-and-selections/checkbox/checkbox-with-event.py similarity index 100% rename from python/controls/forms/checkbox-with-event.py rename to python/controls/input-and-selections/checkbox/checkbox-with-event.py diff --git a/python/controls/forms/styled-checkbox.py b/python/controls/input-and-selections/checkbox/styled-checkbox.py similarity index 100% rename from python/controls/forms/styled-checkbox.py rename to python/controls/input-and-selections/checkbox/styled-checkbox.py diff --git a/python/controls/dropdown/basic-dropdown.py b/python/controls/input-and-selections/dropdown/basic-dropdown.py similarity index 100% rename from python/controls/dropdown/basic-dropdown.py rename to python/controls/input-and-selections/dropdown/basic-dropdown.py diff --git a/python/controls/dropdown/change-items.py b/python/controls/input-and-selections/dropdown/change-items.py similarity index 100% rename from python/controls/dropdown/change-items.py rename to python/controls/input-and-selections/dropdown/change-items.py diff --git a/python/controls/forms/dropdown-add-items.py b/python/controls/input-and-selections/dropdown/dropdown-add-items.py similarity index 100% rename from python/controls/forms/dropdown-add-items.py rename to python/controls/input-and-selections/dropdown/dropdown-add-items.py diff --git a/python/controls/forms/dropdown-random-icon.py b/python/controls/input-and-selections/dropdown/dropdown-random-icon.py similarity index 100% rename from python/controls/forms/dropdown-random-icon.py rename to python/controls/input-and-selections/dropdown/dropdown-random-icon.py diff --git a/python/controls/forms/dropdown.py b/python/controls/input-and-selections/dropdown/dropdown.py similarity index 100% rename from python/controls/forms/dropdown.py rename to python/controls/input-and-selections/dropdown/dropdown.py diff --git a/python/controls/dropdown/label-and-hint.py b/python/controls/input-and-selections/dropdown/label-and-hint.py similarity index 100% rename from python/controls/dropdown/label-and-hint.py rename to python/controls/input-and-selections/dropdown/label-and-hint.py diff --git a/python/controls/dropdown/on-change-event.py b/python/controls/input-and-selections/dropdown/on-change-event.py similarity index 100% rename from python/controls/dropdown/on-change-event.py rename to python/controls/input-and-selections/dropdown/on-change-event.py diff --git a/python/controls/dropdown/styled-dropdown.py b/python/controls/input-and-selections/dropdown/styled-dropdown.py similarity index 100% rename from python/controls/dropdown/styled-dropdown.py rename to python/controls/input-and-selections/dropdown/styled-dropdown.py diff --git a/python/controls/forms/styled-dropdowns.py b/python/controls/input-and-selections/dropdown/styled-dropdowns.py similarity index 100% rename from python/controls/forms/styled-dropdowns.py rename to python/controls/input-and-selections/dropdown/styled-dropdowns.py diff --git a/python/controls/forms/form-controls-misc.py b/python/controls/input-and-selections/form-controls-misc.py similarity index 100% rename from python/controls/forms/form-controls-misc.py rename to python/controls/input-and-selections/form-controls-misc.py diff --git a/python/controls/forms/radiogroup-basic.py b/python/controls/input-and-selections/radio/radiogroup-basic.py similarity index 100% rename from python/controls/forms/radiogroup-basic.py rename to python/controls/input-and-selections/radio/radiogroup-basic.py diff --git a/python/controls/forms/radiogroup-with-event.py b/python/controls/input-and-selections/radio/radiogroup-with-event.py similarity index 100% rename from python/controls/forms/radiogroup-with-event.py rename to python/controls/input-and-selections/radio/radiogroup-with-event.py diff --git a/python/controls/forms/styled-radio.py b/python/controls/input-and-selections/radio/styled-radio.py similarity index 100% rename from python/controls/forms/styled-radio.py rename to python/controls/input-and-selections/radio/styled-radio.py diff --git a/python/controls/forms/slider-basic.py b/python/controls/input-and-selections/slider/slider-basic.py similarity index 100% rename from python/controls/forms/slider-basic.py rename to python/controls/input-and-selections/slider/slider-basic.py diff --git a/python/controls/forms/slider-random-change.py b/python/controls/input-and-selections/slider/slider-random-change.py similarity index 100% rename from python/controls/forms/slider-random-change.py rename to python/controls/input-and-selections/slider/slider-random-change.py diff --git a/python/controls/forms/slider-values.py b/python/controls/input-and-selections/slider/slider-values.py similarity index 100% rename from python/controls/forms/slider-values.py rename to python/controls/input-and-selections/slider/slider-values.py diff --git a/python/controls/forms/slider-with-change.py b/python/controls/input-and-selections/slider/slider-with-change.py similarity index 100% rename from python/controls/forms/slider-with-change.py rename to python/controls/input-and-selections/slider/slider-with-change.py diff --git a/python/controls/forms/switch-basic.py b/python/controls/input-and-selections/switch/switch-basic.py similarity index 100% rename from python/controls/forms/switch-basic.py rename to python/controls/input-and-selections/switch/switch-basic.py diff --git a/python/controls/forms/switch-with-event.py b/python/controls/input-and-selections/switch/switch-with-event.py similarity index 100% rename from python/controls/forms/switch-with-event.py rename to python/controls/input-and-selections/switch/switch-with-event.py diff --git a/python/controls/textfield/basic-textfields.py b/python/controls/input-and-selections/text-field/basic-textfields.py similarity index 100% rename from python/controls/textfield/basic-textfields.py rename to python/controls/input-and-selections/text-field/basic-textfields.py diff --git a/python/controls/textfield/multiline.py b/python/controls/input-and-selections/text-field/multiline.py similarity index 100% rename from python/controls/textfield/multiline.py rename to python/controls/input-and-selections/text-field/multiline.py diff --git a/python/controls/textfield/on-change.py b/python/controls/input-and-selections/text-field/on-change.py similarity index 100% rename from python/controls/textfield/on-change.py rename to python/controls/input-and-selections/text-field/on-change.py diff --git a/python/controls/textfield/password.py b/python/controls/input-and-selections/text-field/password.py similarity index 100% rename from python/controls/textfield/password.py rename to python/controls/input-and-selections/text-field/password.py diff --git a/python/controls/textfield/prefix-suffix.py b/python/controls/input-and-selections/text-field/prefix-suffix.py similarity index 100% rename from python/controls/textfield/prefix-suffix.py rename to python/controls/input-and-selections/text-field/prefix-suffix.py diff --git a/python/controls/forms/styled-textfield.py b/python/controls/input-and-selections/text-field/styled-textfield.py similarity index 100% rename from python/controls/forms/styled-textfield.py rename to python/controls/input-and-selections/text-field/styled-textfield.py diff --git a/python/controls/textfield/textfield-style.py b/python/controls/input-and-selections/text-field/textfield-style.py similarity index 100% rename from python/controls/textfield/textfield-style.py rename to python/controls/input-and-selections/text-field/textfield-style.py diff --git a/python/controls/forms/textfields.py b/python/controls/input-and-selections/text-field/textfields.py similarity index 100% rename from python/controls/forms/textfields.py rename to python/controls/input-and-selections/text-field/textfields.py diff --git a/python/controls/textfield/underlined.py b/python/controls/input-and-selections/text-field/underlined.py similarity index 100% rename from python/controls/textfield/underlined.py rename to python/controls/input-and-selections/text-field/underlined.py diff --git a/python/controls/card/card-with-buttons.py b/python/controls/layout/card/card-with-buttons.py similarity index 100% rename from python/controls/card/card-with-buttons.py rename to python/controls/layout/card/card-with-buttons.py diff --git a/python/controls/column/column-alignment.py b/python/controls/layout/column/column-alignment.py similarity index 100% rename from python/controls/column/column-alignment.py rename to python/controls/layout/column/column-alignment.py diff --git a/python/controls/column/column-horiz-alignment.py b/python/controls/layout/column/column-horiz-alignment.py similarity index 100% rename from python/controls/column/column-horiz-alignment.py rename to python/controls/layout/column/column-horiz-alignment.py diff --git a/python/controls/column/column-infinite-list.py b/python/controls/layout/column/column-infinite-list.py similarity index 100% rename from python/controls/column/column-infinite-list.py rename to python/controls/layout/column/column-infinite-list.py diff --git a/python/controls/column/column-scroll-misc.py b/python/controls/layout/column/column-scroll-misc.py similarity index 100% rename from python/controls/column/column-scroll-misc.py rename to python/controls/layout/column/column-scroll-misc.py diff --git a/python/controls/column/column-scroll-to-key.py b/python/controls/layout/column/column-scroll-to-key.py similarity index 100% rename from python/controls/column/column-scroll-to-key.py rename to python/controls/layout/column/column-scroll-to-key.py diff --git a/python/controls/column/column-scroll.py b/python/controls/layout/column/column-scroll.py similarity index 100% rename from python/controls/column/column-scroll.py rename to python/controls/layout/column/column-scroll.py diff --git a/python/controls/column/column-spacing.py b/python/controls/layout/column/column-spacing.py similarity index 100% rename from python/controls/column/column-spacing.py rename to python/controls/layout/column/column-spacing.py diff --git a/python/controls/column/column-wrap.py b/python/controls/layout/column/column-wrap.py similarity index 100% rename from python/controls/column/column-wrap.py rename to python/controls/layout/column/column-wrap.py diff --git a/python/controls/column/scroll-events.py b/python/controls/layout/column/scroll-events.py similarity index 100% rename from python/controls/column/scroll-events.py rename to python/controls/layout/column/scroll-events.py diff --git a/python/controls/container/clickable-container.py b/python/controls/layout/container/clickable-container.py similarity index 100% rename from python/controls/container/clickable-container.py rename to python/controls/layout/container/clickable-container.py diff --git a/python/controls/container/container-blur.py b/python/controls/layout/container/container-blur.py similarity index 100% rename from python/controls/container/container-blur.py rename to python/controls/layout/container/container-blur.py diff --git a/python/controls/container/container-margin.py b/python/controls/layout/container/container-margin.py similarity index 100% rename from python/controls/container/container-margin.py rename to python/controls/layout/container/container-margin.py diff --git a/python/controls/container/container-on-resize.py b/python/controls/layout/container/container-on-resize.py similarity index 100% rename from python/controls/container/container-on-resize.py rename to python/controls/layout/container/container-on-resize.py diff --git a/python/controls/container/container-padding.py b/python/controls/layout/container/container-padding.py similarity index 100% rename from python/controls/container/container-padding.py rename to python/controls/layout/container/container-padding.py diff --git a/python/controls/container/container-shadow.py b/python/controls/layout/container/container-shadow.py similarity index 100% rename from python/controls/container/container-shadow.py rename to python/controls/layout/container/container-shadow.py diff --git a/python/controls/container/containers-alignment.py b/python/controls/layout/container/containers-alignment.py similarity index 100% rename from python/controls/container/containers-alignment.py rename to python/controls/layout/container/containers-alignment.py diff --git a/python/controls/container/containers-background-color.py b/python/controls/layout/container/containers-background-color.py similarity index 100% rename from python/controls/container/containers-background-color.py rename to python/controls/layout/container/containers-background-color.py diff --git a/python/controls/container/containers-borders.py b/python/controls/layout/container/containers-borders.py similarity index 100% rename from python/controls/container/containers-borders.py rename to python/controls/layout/container/containers-borders.py diff --git a/python/controls/container/gradients.py b/python/controls/layout/container/gradients.py similarity index 100% rename from python/controls/container/gradients.py rename to python/controls/layout/container/gradients.py diff --git a/python/controls/container/linear-gradient.py b/python/controls/layout/container/linear-gradient.py similarity index 100% rename from python/controls/container/linear-gradient.py rename to python/controls/layout/container/linear-gradient.py diff --git a/python/controls/container/nested-themes-simple.py b/python/controls/layout/container/nested-themes-simple.py similarity index 100% rename from python/controls/container/nested-themes-simple.py rename to python/controls/layout/container/nested-themes-simple.py diff --git a/python/controls/container/nested-themes.py b/python/controls/layout/container/nested-themes.py similarity index 100% rename from python/controls/container/nested-themes.py rename to python/controls/layout/container/nested-themes.py diff --git a/python/controls/container/radial-gradient.py b/python/controls/layout/container/radial-gradient.py similarity index 100% rename from python/controls/container/radial-gradient.py rename to python/controls/layout/container/radial-gradient.py diff --git a/python/controls/container/sweep-gradient.py b/python/controls/layout/container/sweep-gradient.py similarity index 100% rename from python/controls/container/sweep-gradient.py rename to python/controls/layout/container/sweep-gradient.py diff --git a/python/controls/datatable/datatable-no-source.py b/python/controls/layout/data-table/datatable-no-source.py similarity index 100% rename from python/controls/datatable/datatable-no-source.py rename to python/controls/layout/data-table/datatable-no-source.py diff --git a/python/controls/divider/divider-horiz.py b/python/controls/layout/divider/divider-horiz.py similarity index 100% rename from python/controls/divider/divider-horiz.py rename to python/controls/layout/divider/divider-horiz.py diff --git a/python/controls/gridview/photo-gallery.py b/python/controls/layout/grid-view/photo-gallery.py similarity index 100% rename from python/controls/gridview/photo-gallery.py rename to python/controls/layout/grid-view/photo-gallery.py diff --git a/python/controls/listtile/listtiles.py b/python/controls/layout/list-tile/listtiles.py similarity index 100% rename from python/controls/listtile/listtiles.py rename to python/controls/layout/list-tile/listtiles.py diff --git a/python/controls/listview/listview-scroll.py b/python/controls/layout/list-view/listview-scroll.py similarity index 100% rename from python/controls/listview/listview-scroll.py rename to python/controls/layout/list-view/listview-scroll.py diff --git a/python/controls/page/app-exit-confirm-dialog.py b/python/controls/layout/page/app-exit-confirm-dialog.py similarity index 100% rename from python/controls/page/app-exit-confirm-dialog.py rename to python/controls/layout/page/app-exit-confirm-dialog.py diff --git a/python/controls/page/keyboard-events.py b/python/controls/layout/page/keyboard-events.py similarity index 100% rename from python/controls/page/keyboard-events.py rename to python/controls/layout/page/keyboard-events.py diff --git a/python/controls/page/splash-test.py b/python/controls/layout/page/splash-test.py similarity index 100% rename from python/controls/page/splash-test.py rename to python/controls/layout/page/splash-test.py diff --git a/python/controls/page/window-hidden-on-start.py b/python/controls/layout/page/window-hidden-on-start.py similarity index 100% rename from python/controls/page/window-hidden-on-start.py rename to python/controls/layout/page/window-hidden-on-start.py diff --git a/python/controls/responsive-row/responsive-layout.py b/python/controls/layout/responsive-row/responsive-layout.py similarity index 100% rename from python/controls/responsive-row/responsive-layout.py rename to python/controls/layout/responsive-row/responsive-layout.py diff --git a/python/controls/row/row-alignment.py b/python/controls/layout/row/row-alignment.py similarity index 100% rename from python/controls/row/row-alignment.py rename to python/controls/layout/row/row-alignment.py diff --git a/python/controls/row/row-spacing.py b/python/controls/layout/row/row-spacing.py similarity index 100% rename from python/controls/row/row-spacing.py rename to python/controls/layout/row/row-spacing.py diff --git a/python/controls/row/row-vert-alignment.py b/python/controls/layout/row/row-vert-alignment.py similarity index 100% rename from python/controls/row/row-vert-alignment.py rename to python/controls/layout/row/row-vert-alignment.py diff --git a/python/controls/row/row-wrap.py b/python/controls/layout/row/row-wrap.py similarity index 100% rename from python/controls/row/row-wrap.py rename to python/controls/layout/row/row-wrap.py diff --git a/python/controls/stack/absolute-positioned.py b/python/controls/layout/stack/absolute-positioned.py similarity index 100% rename from python/controls/stack/absolute-positioned.py rename to python/controls/layout/stack/absolute-positioned.py diff --git a/python/controls/stack/avatar-with-status.py b/python/controls/layout/stack/avatar-with-status.py similarity index 100% rename from python/controls/stack/avatar-with-status.py rename to python/controls/layout/stack/avatar-with-status.py diff --git a/python/controls/stack/image-title.py b/python/controls/layout/stack/image-title.py similarity index 100% rename from python/controls/stack/image-title.py rename to python/controls/layout/stack/image-title.py diff --git a/python/controls/tabs/tabs-dynamic.py b/python/controls/layout/tabs/tabs-dynamic.py similarity index 100% rename from python/controls/tabs/tabs-dynamic.py rename to python/controls/layout/tabs/tabs-dynamic.py diff --git a/python/controls/tabs/tabs-simple.py b/python/controls/layout/tabs/tabs-simple.py similarity index 100% rename from python/controls/tabs/tabs-simple.py rename to python/controls/layout/tabs/tabs-simple.py diff --git a/python/controls/vertical-divider/divider-vert.py b/python/controls/layout/vertical-divider/divider-vert.py similarity index 100% rename from python/controls/vertical-divider/divider-vert.py rename to python/controls/layout/vertical-divider/divider-vert.py diff --git a/python/controls/appbar/appbar-simple.py b/python/controls/navigation/app-bar/appbar-simple.py similarity index 100% rename from python/controls/appbar/appbar-simple.py rename to python/controls/navigation/app-bar/appbar-simple.py diff --git a/python/controls/appbar/appbar-theme-material.py b/python/controls/navigation/app-bar/appbar-theme-material.py similarity index 100% rename from python/controls/appbar/appbar-theme-material.py rename to python/controls/navigation/app-bar/appbar-theme-material.py diff --git a/python/controls/appbar/bottom-appbar.py b/python/controls/navigation/app-bar/bottom-appbar.py similarity index 100% rename from python/controls/appbar/bottom-appbar.py rename to python/controls/navigation/app-bar/bottom-appbar.py diff --git a/python/controls/navigation-bar/navigation-bar-sample.py b/python/controls/navigation/navigation-bar/navigation-bar-sample.py similarity index 100% rename from python/controls/navigation-bar/navigation-bar-sample.py rename to python/controls/navigation/navigation-bar/navigation-bar-sample.py diff --git a/python/controls/navigation-rail/nav-rail-layout.py b/python/controls/navigation/navigation-rail/nav-rail-layout.py similarity index 100% rename from python/controls/navigation-rail/nav-rail-layout.py rename to python/controls/navigation/navigation-rail/nav-rail-layout.py diff --git a/python/controls/navigation-rail/nav-rail-test.py b/python/controls/navigation/navigation-rail/nav-rail-test.py similarity index 100% rename from python/controls/navigation-rail/nav-rail-test.py rename to python/controls/navigation/navigation-rail/nav-rail-test.py diff --git a/python/controls/audio/audio-autoplay.py b/python/controls/utility/audio/audio-autoplay.py similarity index 100% rename from python/controls/audio/audio-autoplay.py rename to python/controls/utility/audio/audio-autoplay.py diff --git a/python/controls/audio/audio-player-async.py b/python/controls/utility/audio/audio-player-async.py similarity index 100% rename from python/controls/audio/audio-player-async.py rename to python/controls/utility/audio/audio-player-async.py diff --git a/python/controls/audio/audio-player-slider.py b/python/controls/utility/audio/audio-player-slider.py similarity index 100% rename from python/controls/audio/audio-player-slider.py rename to python/controls/utility/audio/audio-player-slider.py diff --git a/python/controls/audio/audio-player.py b/python/controls/utility/audio/audio-player.py similarity index 100% rename from python/controls/audio/audio-player.py rename to python/controls/utility/audio/audio-player.py diff --git a/python/controls/drag-and-drop/drag-drop-colors.py b/python/controls/utility/drag-target/drag-drop-colors.py similarity index 100% rename from python/controls/drag-and-drop/drag-drop-colors.py rename to python/controls/utility/drag-target/drag-drop-colors.py diff --git a/python/controls/drag-and-drop/drag-drop-nesting.py b/python/controls/utility/drag-target/drag-drop-nesting.py similarity index 100% rename from python/controls/drag-and-drop/drag-drop-nesting.py rename to python/controls/utility/drag-target/drag-drop-nesting.py diff --git a/python/controls/drag-and-drop/drag-drop-ordering.py b/python/controls/utility/drag-target/drag-drop-ordering.py similarity index 100% rename from python/controls/drag-and-drop/drag-drop-ordering.py rename to python/controls/utility/drag-target/drag-drop-ordering.py diff --git a/python/controls/file-picker/file-picker-all-modes.py b/python/controls/utility/file-picker/file-picker-all-modes.py similarity index 100% rename from python/controls/file-picker/file-picker-all-modes.py rename to python/controls/utility/file-picker/file-picker-all-modes.py diff --git a/python/controls/file-picker/file-picker-upload-progress.py b/python/controls/utility/file-picker/file-picker-upload-progress.py similarity index 100% rename from python/controls/file-picker/file-picker-upload-progress.py rename to python/controls/utility/file-picker/file-picker-upload-progress.py diff --git a/python/controls/gesture-detector/draggable-container_change_mouse_cursor.py b/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py similarity index 100% rename from python/controls/gesture-detector/draggable-container_change_mouse_cursor.py rename to python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py diff --git a/python/controls/gesture-detector/draggable-containers.py b/python/controls/utility/gesture-detector/draggable-containers.py similarity index 100% rename from python/controls/gesture-detector/draggable-containers.py rename to python/controls/utility/gesture-detector/draggable-containers.py diff --git a/python/controls/gesture-detector/gestures-tester.py b/python/controls/utility/gesture-detector/gestures-tester.py similarity index 100% rename from python/controls/gesture-detector/gestures-tester.py rename to python/controls/utility/gesture-detector/gestures-tester.py diff --git a/python/controls/shader-mask/shader-mask-gradient.py b/python/controls/utility/shader-mask/shader-mask-gradient.py similarity index 100% rename from python/controls/shader-mask/shader-mask-gradient.py rename to python/controls/utility/shader-mask/shader-mask-gradient.py diff --git a/python/controls/shader-mask/shader-mask-image.py b/python/controls/utility/shader-mask/shader-mask-image.py similarity index 100% rename from python/controls/shader-mask/shader-mask-image.py rename to python/controls/utility/shader-mask/shader-mask-image.py diff --git a/python/controls/shader-mask/shader-mask-single-image.py b/python/controls/utility/shader-mask/shader-mask-single-image.py similarity index 100% rename from python/controls/shader-mask/shader-mask-single-image.py rename to python/controls/utility/shader-mask/shader-mask-single-image.py diff --git a/python/controls/window-drag-area/no-frame-window.py b/python/controls/utility/window-drag-area/no-frame-window.py similarity index 100% rename from python/controls/window-drag-area/no-frame-window.py rename to python/controls/utility/window-drag-area/no-frame-window.py From 7b299ea638242134a8c332025034ed84977c9ba2 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 25 Feb 2025 17:59:15 -0800 Subject: [PATCH 25/81] update column examples --- .../layout/column/column-alignment.py | 4 +-- .../layout/column/column-horiz-alignment.py | 4 +-- .../layout/column/column-infinite-list.py | 1 - .../layout/column/column-scroll-misc.py | 26 +++++++++---------- .../layout/column/column-scroll-to-key.py | 8 +++--- .../controls/layout/column/column-spacing.py | 2 +- python/controls/layout/column/column-wrap.py | 5 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/python/controls/layout/column/column-alignment.py b/python/controls/layout/column/column-alignment.py index b5e36562..155e14c6 100644 --- a/python/controls/layout/column/column-alignment.py +++ b/python/controls/layout/column/column-alignment.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER_500, + bgcolor=ft.Colors.AMBER_500, ) ) return items @@ -22,7 +22,7 @@ def column_with_alignment(align: ft.MainAxisAlignment): ft.Text(str(align), size=10), ft.Container( content=ft.Column(items(3), alignment=align), - bgcolor=ft.colors.AMBER_100, + bgcolor=ft.Colors.AMBER_100, height=400, ), ] diff --git a/python/controls/layout/column/column-horiz-alignment.py b/python/controls/layout/column/column-horiz-alignment.py index f9b9cb1c..629d8340 100644 --- a/python/controls/layout/column/column-horiz-alignment.py +++ b/python/controls/layout/column/column-horiz-alignment.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER_500, + bgcolor=ft.Colors.AMBER_500, ) ) return items @@ -26,7 +26,7 @@ def column_with_horiz_alignment(align: ft.CrossAxisAlignment): alignment=ft.MainAxisAlignment.START, horizontal_alignment=align, ), - bgcolor=ft.colors.AMBER_100, + bgcolor=ft.Colors.AMBER_100, width=100, ), ] diff --git a/python/controls/layout/column/column-infinite-list.py b/python/controls/layout/column/column-infinite-list.py index ecdbddaf..ebc9290f 100644 --- a/python/controls/layout/column/column-infinite-list.py +++ b/python/controls/layout/column/column-infinite-list.py @@ -1,5 +1,4 @@ import threading - import flet as ft diff --git a/python/controls/layout/column/column-scroll-misc.py b/python/controls/layout/column/column-scroll-misc.py index 74ede1b7..708c23b3 100644 --- a/python/controls/layout/column/column-scroll-misc.py +++ b/python/controls/layout/column/column-scroll-misc.py @@ -5,15 +5,15 @@ def main(page: ft.Page): page.theme = ft.Theme( scrollbar_theme=ft.ScrollbarTheme( track_color={ - ft.MaterialState.HOVERED: ft.colors.AMBER, - ft.MaterialState.DEFAULT: ft.colors.TRANSPARENT, + ft.ControlState.HOVERED: ft.Colors.AMBER, + ft.ControlState.DEFAULT: ft.Colors.TRANSPARENT, }, track_visibility=True, - track_border_color=ft.colors.BLUE, + track_border_color=ft.Colors.BLUE, thumb_visibility=True, thumb_color={ - ft.MaterialState.HOVERED: ft.colors.RED, - ft.MaterialState.DEFAULT: ft.colors.GREY_300, + ft.ControlState.HOVERED: ft.Colors.RED, + ft.ControlState.DEFAULT: ft.Colors.GREY_300, }, thickness=30, radius=15, @@ -33,7 +33,7 @@ def main(page: ft.Page): cl.controls.append(ft.Text(f"Text line {i}", key=str(i))) def scroll_to_offset(e): - cl.scroll_to(offset=100, duration=1000) + cl.scroll_to(offset=500, duration=1000) def scroll_to_start(e): cl.scroll_to(offset=0, duration=1000) @@ -45,25 +45,25 @@ def scroll_to_key(e): cl.scroll_to(key="20", duration=1000) def scroll_to_delta(e): - cl.scroll_to(delta=40, duration=200) + cl.scroll_to(delta=100, duration=200) def scroll_to_minus_delta(e): - cl.scroll_to(delta=-40, duration=200) + cl.scroll_to(delta=-100, duration=200) page.add( ft.Container(cl, border=ft.border.all(1)), - ft.ElevatedButton("Scroll to offset 100", on_click=scroll_to_offset), + ft.ElevatedButton("Scroll to offset 500", on_click=scroll_to_offset), ft.Row( [ - ft.ElevatedButton("Scroll to start", on_click=scroll_to_start), - ft.ElevatedButton("Scroll to end", on_click=scroll_to_end), + ft.ElevatedButton("Scroll -100", on_click=scroll_to_minus_delta), + ft.ElevatedButton("Scroll +100", on_click=scroll_to_delta), ] ), ft.ElevatedButton("Scroll to key '20'", on_click=scroll_to_key), ft.Row( [ - ft.ElevatedButton("Scroll -40", on_click=scroll_to_minus_delta), - ft.ElevatedButton("Scroll +40", on_click=scroll_to_delta), + ft.ElevatedButton("Scroll to start", on_click=scroll_to_start), + ft.ElevatedButton("Scroll to end", on_click=scroll_to_end), ] ), ) diff --git a/python/controls/layout/column/column-scroll-to-key.py b/python/controls/layout/column/column-scroll-to-key.py index 1538547a..0985b04e 100644 --- a/python/controls/layout/column/column-scroll-to-key.py +++ b/python/controls/layout/column/column-scroll-to-key.py @@ -11,28 +11,28 @@ def main(page: ft.Page): ft.Container( ft.Text("Section A"), alignment=ft.alignment.top_left, - bgcolor=ft.colors.YELLOW_200, + bgcolor=ft.Colors.YELLOW_200, height=100, key="A", ), ft.Container( ft.Text("Section B"), alignment=ft.alignment.top_left, - bgcolor=ft.colors.GREEN_200, + bgcolor=ft.Colors.GREEN_200, height=100, key="B", ), ft.Container( ft.Text("Section C"), alignment=ft.alignment.top_left, - bgcolor=ft.colors.BLUE_200, + bgcolor=ft.Colors.BLUE_200, height=100, key="C", ), ft.Container( ft.Text("Section D"), alignment=ft.alignment.top_left, - bgcolor=ft.colors.PINK_200, + bgcolor=ft.Colors.PINK_200, height=100, key="D", ), diff --git a/python/controls/layout/column/column-spacing.py b/python/controls/layout/column/column-spacing.py index 8295df70..6a668346 100644 --- a/python/controls/layout/column/column-spacing.py +++ b/python/controls/layout/column/column-spacing.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER, + bgcolor=ft.Colors.AMBER, border_radius=ft.border_radius.all(5), ) ) diff --git a/python/controls/layout/column/column-wrap.py b/python/controls/layout/column/column-wrap.py index ed63e284..17452f02 100644 --- a/python/controls/layout/column/column-wrap.py +++ b/python/controls/layout/column/column-wrap.py @@ -4,6 +4,7 @@ def main(page: ft.Page): + def items(count): items = [] for i in range(1, count + 1): @@ -13,7 +14,7 @@ def items(count): alignment=ft.alignment.center, width=30, height=30, - bgcolor=ft.colors.AMBER, + bgcolor=ft.Colors.AMBER, border_radius=ft.border_radius.all(5), ) ) @@ -50,7 +51,7 @@ def slider_change(e): width_slider, ] ), - ft.Container(content=col, bgcolor=ft.colors.AMBER_100), + ft.Container(content=col, bgcolor=ft.Colors.TRANSPARENT), ) From 5020cba1c817b5425b69e7bcb706f0695f218d01 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 27 Feb 2025 10:42:37 -0800 Subject: [PATCH 26/81] update containers examples --- .../controls/layout/column/column-scroll.py | 14 ++-- .../controls/layout/column/column-spacing.py | 2 +- python/controls/layout/column/column-wrap.py | 2 +- .../layout/container/clickable-container.py | 9 ++- .../layout/container/container-blur.py | 53 +++++++++---- .../layout/container/container-margin.py | 65 ++++++--------- .../layout/container/container-on-resize.py | 8 +- .../layout/container/container-padding.py | 40 +++++----- .../layout/container/container-shadow.py | 10 +-- .../layout/container/containers-alignment.py | 33 ++++---- .../container/containers-background-color.py | 21 +++-- .../layout/container/containers-borders.py | 79 ++++--------------- python/controls/layout/container/gradients.py | 77 ++++++++---------- .../layout/container/linear-gradient.py | 20 +++-- .../layout/container/nested-themes-simple.py | 12 +-- .../layout/container/nested-themes-switch.py | 59 ++++++++++++++ .../layout/container/nested-themes.py | 28 +++---- .../layout/container/radial-gradient.py | 15 ++-- .../layout/container/sweep-gradient.py | 16 ++-- 19 files changed, 281 insertions(+), 282 deletions(-) create mode 100644 python/controls/layout/container/nested-themes-switch.py diff --git a/python/controls/layout/column/column-scroll.py b/python/controls/layout/column/column-scroll.py index bbfeefbb..06c897d1 100644 --- a/python/controls/layout/column/column-scroll.py +++ b/python/controls/layout/column/column-scroll.py @@ -5,8 +5,8 @@ def main(page: ft.Page): def add_text_box(_): text_field = ft.TextField( label=f"Text Box {len(left_column.controls)}", - label_style=ft.TextStyle(color=ft.colors.GREEN), - color=ft.colors.GREEN, + label_style=ft.TextStyle(color=ft.Colors.GREEN), + color=ft.Colors.GREEN, value=str(len(left_column.controls)), ) left_column.controls.append(text_field) @@ -46,7 +46,7 @@ def change_scroll(_): ) left_column = ft.Column( - [ft.Text("THIS IS COL 1", color=ft.colors.RED_400)], + [ft.Text("THIS IS COL 1", color=ft.Colors.RED_400)], scroll=next(scroll_mode), ) left_container = ft.Container( @@ -54,7 +54,7 @@ def change_scroll(_): expand=True, margin=10, padding=10, - bgcolor=ft.colors.AMBER_100, + bgcolor=ft.Colors.AMBER_100, border_radius=10, alignment=ft.alignment.top_center, ) @@ -70,14 +70,14 @@ def change_scroll(_): ), margin=10, padding=10, - bgcolor=ft.colors.CYAN_500, + bgcolor=ft.Colors.CYAN_500, border_radius=10, expand=True, - alignment=ft.alignment.top_center, + alignment=ft.alignment.top_left, ) row = ft.Row([left_container, right_container], expand=True) page.add(row) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/column/column-spacing.py b/python/controls/layout/column/column-spacing.py index 6a668346..71165c28 100644 --- a/python/controls/layout/column/column-spacing.py +++ b/python/controls/layout/column/column-spacing.py @@ -36,4 +36,4 @@ def spacing_slider_change(e): page.add(ft.Column([ft.Text("Spacing between items"), gap_slider]), col) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/column/column-wrap.py b/python/controls/layout/column/column-wrap.py index 17452f02..537de15a 100644 --- a/python/controls/layout/column/column-wrap.py +++ b/python/controls/layout/column/column-wrap.py @@ -55,4 +55,4 @@ def slider_change(e): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/clickable-container.py b/python/controls/layout/container/clickable-container.py index 10f61052..c0b587ad 100644 --- a/python/controls/layout/container/clickable-container.py +++ b/python/controls/layout/container/clickable-container.py @@ -2,6 +2,7 @@ def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT page.title = "Containers - clickable and not" page.vertical_alignment = ft.MainAxisAlignment.CENTER page.horizontal_alignment = ft.CrossAxisAlignment.CENTER @@ -14,7 +15,7 @@ def main(page: ft.Page): margin=10, padding=10, alignment=ft.alignment.center, - bgcolor=ft.colors.AMBER, + bgcolor=ft.Colors.AMBER, width=150, height=150, border_radius=10, @@ -24,7 +25,7 @@ def main(page: ft.Page): margin=10, padding=10, alignment=ft.alignment.center, - bgcolor=ft.colors.GREEN_200, + bgcolor=ft.Colors.GREEN_200, width=150, height=150, border_radius=10, @@ -35,7 +36,7 @@ def main(page: ft.Page): margin=10, padding=10, alignment=ft.alignment.center, - bgcolor=ft.colors.CYAN_200, + bgcolor=ft.Colors.CYAN_200, width=150, height=150, border_radius=10, @@ -59,4 +60,4 @@ def main(page: ft.Page): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/container-blur.py b/python/controls/layout/container/container-blur.py index e84abd33..d467c144 100644 --- a/python/controls/layout/container/container-blur.py +++ b/python/controls/layout/container/container-blur.py @@ -2,38 +2,57 @@ def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + i = 1 + + img_container = ft.Container( + image=ft.DecorationImage(src="https://picsum.photos/250/250"), + width=250, + height=250, + ) + + def change_img(e): + nonlocal i + print(f"button clicked {i}") + img_container.image = ft.DecorationImage( + src=f"https://picsum.photos/250/250?random={i}" + ) + i += 1 + page.update() page.add( ft.Stack( [ + img_container, ft.Container( - content=ft.Text("Hello"), - image_src="https://picsum.photos/100/100", width=100, height=100, - ), - ft.Container( - width=50, - height=50, blur=10, - bgcolor="#44CCCC00", + bgcolor="#22CCCC00", ), ft.Container( - width=50, - height=50, - left=10, - top=60, + width=100, + height=100, + left=20, + top=120, blur=(0, 10), ), ft.Container( - top=10, - left=60, + top=50, + right=10, blur=ft.Blur(10, 0, ft.BlurTileMode.MIRROR), - width=50, - height=50, + width=100, + height=100, bgcolor="#44CCCCCC", - # border_radius=10, - border=ft.border.all(2, ft.colors.BLACK), + border_radius=10, + border=ft.border.all(2, ft.Colors.BLACK), + ), + ft.ElevatedButton( + text="Change Background", + bottom=5, + right=5, + style=ft.ButtonStyle(text_style=ft.TextStyle(size=8)), + on_click=change_img, ), ] ) diff --git a/python/controls/layout/container/container-margin.py b/python/controls/layout/container/container-margin.py index 418930b8..a60ea9e4 100644 --- a/python/controls/layout/container/container-margin.py +++ b/python/controls/layout/container/container-margin.py @@ -1,60 +1,47 @@ -import flet -from flet import ( - Container, - ElevatedButton, - Page, - Row, - Text, - alignment, - border, - border_radius, - colors, - margin, - padding, -) - - -def main(page: Page): +import flet as ft + + +def main(page: ft.Page): page.title = "Containers with different margins" - c1 = Container( - content=ElevatedButton("container_1"), - bgcolor=colors.AMBER, - # padding=padding.all(10), - margin=margin.all(10), + c1 = ft.Container( + content=ft.ElevatedButton("container_1"), + bgcolor=ft.Colors.AMBER, + # padding=ft.padding.all(10), + margin=ft.margin.all(10), width=150, height=150, ) - c2 = Container( - content=ElevatedButton("container_2"), - bgcolor=colors.AMBER, - # padding=padding.all(20), - margin=margin.all(20), + c2 = ft.Container( + content=ft.ElevatedButton("container_2"), + bgcolor=ft.Colors.AMBER, + # padding=ft.padding.all(20), + margin=ft.margin.all(20), width=150, height=150, ) - c3 = Container( - content=ElevatedButton("container_3"), - bgcolor=colors.AMBER, - # padding=padding.symmetric(horizontal=10), - margin=margin.symmetric(vertical=10), + c3 = ft.Container( + content=ft.ElevatedButton("container_3"), + bgcolor=ft.Colors.AMBER, + # padding=ft.padding.symmetric(horizontal=10), + margin=ft.margin.symmetric(vertical=10), width=150, height=150, ) - c4 = Container( - content=ElevatedButton("container_4"), - bgcolor=colors.AMBER, - # padding=padding.only(left=10), - margin=margin.only(left=10), + c4 = ft.Container( + content=ft.ElevatedButton("container_4"), + bgcolor=ft.Colors.AMBER, + # padding=ft.padding.only(left=10), + margin=ft.margin.only(left=10), width=150, height=150, ) - r = Row([c1, c2, c3, c4], spacing=0) + r = ft.Row([c1, c2, c3, c4], spacing=0) page.add(r) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/container-on-resize.py b/python/controls/layout/container/container-on-resize.py index 28432297..210ae0df 100644 --- a/python/controls/layout/container/container-on-resize.py +++ b/python/controls/layout/container/container-on-resize.py @@ -23,15 +23,15 @@ def main(page: ft.Page): page.add( ft.Row( [ - SizeAwareContainer(ft.colors.RED, expand=2), - SizeAwareContainer(ft.colors.GREEN, expand=4), + SizeAwareContainer(ft.Colors.RED, expand=2), + SizeAwareContainer(ft.Colors.GREEN, expand=4), ], expand=2, ), ft.Row( [ - SizeAwareContainer(ft.colors.YELLOW, expand=2), - SizeAwareContainer(ft.colors.BLUE, expand=4), + SizeAwareContainer(ft.Colors.YELLOW, expand=2), + SizeAwareContainer(ft.Colors.BLUE, expand=4), ], expand=3, ), diff --git a/python/controls/layout/container/container-padding.py b/python/controls/layout/container/container-padding.py index 600ed7d1..04c45650 100644 --- a/python/controls/layout/container/container-padding.py +++ b/python/controls/layout/container/container-padding.py @@ -1,44 +1,44 @@ -import flet +import flet as ft from flet import Container, ElevatedButton, Page, Row, colors, padding -def main(page: Page): +def main(page: ft.Page): page.title = "Containers with different padding" - c1 = Container( - content=ElevatedButton("container_1"), - bgcolor=colors.AMBER, - padding=padding.all(10), + c1 = ft.Container( + content=ft.ElevatedButton("container_1"), + bgcolor=ft.Colors.AMBER, + padding=ft.padding.all(10), width=150, height=150, ) - c2 = Container( - content=ElevatedButton("container_2"), - bgcolor=colors.AMBER, - padding=padding.all(20), + c2 = ft.Container( + content=ft.ElevatedButton("container_2"), + bgcolor=ft.Colors.AMBER, + padding=ft.padding.all(20), width=150, height=150, ) - c3 = Container( - content=ElevatedButton("container_3"), - bgcolor=colors.AMBER, - padding=padding.symmetric(horizontal=10), + c3 = ft.Container( + content=ft.ElevatedButton("container_3"), + bgcolor=ft.Colors.AMBER, + padding=ft.padding.symmetric(horizontal=10), width=150, height=150, ) - c4 = Container( - content=ElevatedButton("container_4"), - bgcolor=colors.AMBER, - padding=padding.only(left=10), + c4 = ft.Container( + content=ft.ElevatedButton("container_4"), + bgcolor=ft.Colors.AMBER, + padding=ft.padding.only(left=10), width=150, height=150, ) - r = Row([c1, c2, c3, c4]) + r = ft.Row([c1, c2, c3, c4]) page.add(r) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/container-shadow.py b/python/controls/layout/container/container-shadow.py index ce8b6990..3bd578cc 100644 --- a/python/controls/layout/container/container-shadow.py +++ b/python/controls/layout/container/container-shadow.py @@ -5,7 +5,7 @@ def main(page: ft.Page): page.add( ft.Container( - bgcolor=ft.colors.YELLOW, + bgcolor=ft.Colors.YELLOW, width=100, height=100, border_radius=50, @@ -13,26 +13,26 @@ def main(page: ft.Page): ft.BoxShadow( spread_radius=1, blur_radius=15, - color=ft.colors.WHITE, + color=ft.Colors.WHITE, offset=ft.Offset(-5, -5), ), ft.BoxShadow( spread_radius=1, blur_radius=15, - color=ft.colors.GREY_600, + color=ft.Colors.GREY_600, offset=ft.Offset(5, 5), ), ], ), ft.Container( - # bgcolor=ft.colors.WHITE, + # bgcolor=ft.Colors.WHITE, border_radius=10, width=100, height=100, shadow=ft.BoxShadow( spread_radius=1, blur_radius=15, - color=ft.colors.BLUE_GREY_300, + color=ft.Colors.BLUE_GREY_300, offset=ft.Offset(0, 0), blur_style=ft.ShadowBlurStyle.OUTER, ), diff --git a/python/controls/layout/container/containers-alignment.py b/python/controls/layout/container/containers-alignment.py index 8186db76..494144a1 100644 --- a/python/controls/layout/container/containers-alignment.py +++ b/python/controls/layout/container/containers-alignment.py @@ -1,39 +1,38 @@ -import flet -from flet import Container, ElevatedButton, Page, Row, alignment, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Containers with different alignments" - c1 = Container( - content=ElevatedButton("Center"), - bgcolor=colors.AMBER, + c1 = ft.Container( + content=ft.ElevatedButton("Center"), + bgcolor=ft.Colors.AMBER, padding=15, - alignment=alignment.center, + alignment=ft.alignment.center, width=150, height=150, ) - c2 = Container( - content=ElevatedButton("Top left"), - bgcolor=colors.AMBER, + c2 = ft.Container( + content=ft.ElevatedButton("Top left"), + bgcolor=ft.Colors.AMBER, padding=15, - alignment=alignment.top_left, + alignment=ft.alignment.top_left, width=150, height=150, ) - c3 = Container( - content=ElevatedButton("-0.5, -0.5"), - bgcolor=colors.AMBER, + c3 = ft.Container( + content=ft.ElevatedButton("-0.5, -0.5"), + bgcolor=ft.Colors.AMBER, padding=15, - alignment=alignment.Alignment(-0.5, -0.5), + alignment=ft.alignment.Alignment(-0.5, -0.5), width=150, height=150, ) - r = Row([c1, c2, c3]) + r = ft.Row([c1, c2, c3]) page.add(r) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/containers-background-color.py b/python/controls/layout/container/containers-background-color.py index 2a89b062..1c5dfd75 100644 --- a/python/controls/layout/container/containers-background-color.py +++ b/python/controls/layout/container/containers-background-color.py @@ -1,28 +1,27 @@ -import flet -from flet import Container, ElevatedButton, OutlinedButton, Page, Text, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Containers with different background color" - c1 = Container( - content=Text("Container_1"), + c1 = ft.Container( + content=ft.Text("Container_1"), bgcolor="#FFCC0000", padding=5, ) - c2 = Container( - content=Text("Container_2"), + c2 = ft.Container( + content=ft.Text("Container_2"), bgcolor="#CC0000", padding=5, ) - c3 = Container( - content=Text("Container_3"), - bgcolor=colors.RED, + c3 = ft.Container( + content=ft.Text("Container_3"), + bgcolor=ft.Colors.RED, padding=5, ) page.add(c1, c2, c3) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/containers-borders.py b/python/controls/layout/container/containers-borders.py index 3884a9c9..044a1537 100644 --- a/python/controls/layout/container/containers-borders.py +++ b/python/controls/layout/container/containers-borders.py @@ -1,86 +1,37 @@ -import flet -from flet import ( - Container, - ElevatedButton, - Page, - Row, - alignment, - border, - border_radius, - colors, - padding, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Containers with different borders" - c1 = Container( - content=ElevatedButton("Center"), - bgcolor=colors.AMBER, + c1 = ft.Container( + bgcolor=ft.colors.AMBER, padding=15, - alignment=alignment.center, - border=border.all(10, colors.PINK_600), - border_radius=border_radius.all(30), + border=ft.border.all(10, ft.Colors.PINK_600), + border_radius=ft.border_radius.all(30), width=150, height=150, ) - c2 = Container( - content=ElevatedButton("Top left"), - bgcolor=colors.AMBER, + c2 = ft.Container( + bgcolor=ft.colors.DEEP_PURPLE, padding=15, - alignment=alignment.top_left, + border=ft.border.all(3, ft.Colors.LIGHT_GREEN_ACCENT), + border_radius=ft.border_radius.only(top_left=10, bottom_right=10), width=150, height=150, ) - c3 = Container( - content=ElevatedButton("-0.5, -0.5"), - bgcolor=colors.AMBER, + c3 = ft.Container( + bgcolor=ft.colors.BLUE_GREY_900, padding=15, - alignment=alignment.Alignment(-0.5, -0.5), + border=ft.border.symmetric(vertical=ft.BorderSide(8, ft.Colors.YELLOW_800)), width=150, height=150, ) - r = Row([c1]) + r = ft.Row([c1, c2, c3]) page.add(r) -flet.app(target=main) - - -# - bgColor (background color - `decoration: BoxDecoration.color`) -# - alignment - `topLeft`, `topCenter`, `topRight`, `centerLeft`, `center`, `centerRight`, `bottomLeft`, `bottomCenter`, `bottomRight` -# - border - width, color -# - borderRadius -# - verticalScroll (S2) -# - horizontalScroll (S2) -# - autoScroll (S2) - `end`, `start` ([example](https://stackoverflow.com/questions/43485529/programmatically-scrolling-to-the-end-of-a-listview)). -# - content - child control of any type -# - margin -# - padding -# - tooltip - -# Common Properties: - -# - visible -# - disabled - -# - expand (int) - The control is forced to fill the available space inside Row or Column. Flex factor specified by the property. Default is 1. The property has affect only for direct descendants of Row and Column controls. (Wrap control into Expanded). -# - flex (S2) (int) - The child can be at most as large as the available space (but is allowed to be smaller) inside Row or Column. Flex factor specified by the property. Default is 1. The property has affect only for direct descendants of Row and Column controls. (Wrap control into Flexible with fit=FlexFit.loose). - -# The only difference if you use Flexible instead of Expanded, is that Flexible lets its child have the same or smaller width than the Flexible itself, while Expanded forces its child to have the exact same width of the Expanded. But both Expanded and Flexible ignore their children’s width when sizing themselves. - -# - width - wrap into SizedBox -# - height - wrap into SizedBox -# - minHeight (S2) - wrap into ConstrainedBox -# - maxHeight (S2) - wrap into ConstrainedBox -# - minWidth (S2) - wrap into ConstrainedBox -# - maxWidth (S2) - wrap into ConstrainedBox - -# - fit (S2) -# - fitAlign (S2) - Wrap into FittedBox - -# - opacity - allows to specify transparency of the control, hide it completely or blend with another if used with Stack. 0.0 - hidden, 1.0 - fully visible. See https://api.flutter.dev/flutter/widgets/Opacity-class.html. +ft.app(main) diff --git a/python/controls/layout/container/gradients.py b/python/controls/layout/container/gradients.py index 144c5bb2..5c8dc952 100644 --- a/python/controls/layout/container/gradients.py +++ b/python/controls/layout/container/gradients.py @@ -1,35 +1,23 @@ import math -import flet -from flet import ( - Alignment, - Container, - LinearGradient, - Page, - RadialGradient, - Row, - SweepGradient, - Text, - alignment, - colors, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Containers with gradient" - page.horizontal_alignment = "center" - page.vertical_alignment = "center" + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.vertical_alignment = ft.MainAxisAlignment.CENTER page.add( - Row( + ft.Row( [ - Container( - content=Text("Linear gradient"), + ft.Container( + content=ft.Text("Linear gradient"), padding=10, - alignment=alignment.center, - gradient=LinearGradient( - begin=alignment.top_left, - end=Alignment(0.8, 1), + alignment=ft.alignment.center, + gradient=ft.LinearGradient( + begin=ft.alignment.top_left, + end=ft.Alignment(0.8, 1), colors=[ "0xff1f005c", "0xff5b0060", @@ -40,34 +28,34 @@ def main(page: Page): "0xfff39060", "0xffffb56b", ], - tile_mode="mirror", + tile_mode=ft.GradientTileMode.MIRROR, rotation=math.pi / 3, ), width=200, height=200, border_radius=10, ), - Container( - content=Text("Linear gradient with stops"), + ft.Container( + content=ft.Text("Linear gradient with stops"), padding=10, - alignment=alignment.center, - gradient=LinearGradient( - begin=alignment.center_left, - end=alignment.center_right, - colors=[colors.RED, colors.GREEN, colors.BLUE], + alignment=ft.alignment.center, + gradient=ft.LinearGradient( + begin=ft.alignment.center_left, + end=ft.alignment.center_right, + colors=[ft.colors.RED, ft.colors.GREEN, ft.colors.BLUE], stops=[0.1, 0.2, 1.0], - tile_mode="mirror", + tile_mode=ft.GradientTileMode.MIRROR, ), width=200, height=200, border_radius=10, ), - Container( - content=Text("Radial gradient"), + ft.Container( + content=ft.Text("Radial gradient"), padding=10, - alignment=alignment.center, - gradient=RadialGradient( - center=Alignment(0.7, -0.6), + alignment=ft.alignment.center, + gradient=ft.RadialGradient( + center=ft.Alignment(0.7, -0.6), radius=0.2, colors=[ "0xFFFFFF00", # yellow sun @@ -79,12 +67,12 @@ def main(page: Page): height=200, border_radius=10, ), - Container( - content=Text("Sweep gradient"), + ft.Container( + content=ft.Text("Sweep gradient"), padding=10, - alignment=alignment.center, - gradient=SweepGradient( - center=alignment.center, + alignment=ft.alignment.center, + gradient=ft.SweepGradient( + center=ft.alignment.center, start_angle=0.0, end_angle=math.pi * 2, colors=[ @@ -102,9 +90,10 @@ def main(page: Page): border_radius=10, ), ], - alignment="center", + alignment=ft.MainAxisAlignment.CENTER, + scroll=ft.ScrollMode.AUTO, ), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/linear-gradient.py b/python/controls/layout/container/linear-gradient.py index 2c788864..965a3123 100644 --- a/python/controls/layout/container/linear-gradient.py +++ b/python/controls/layout/container/linear-gradient.py @@ -1,17 +1,15 @@ import math +import flet as ft -import flet -from flet import Alignment, Container, LinearGradient, Page, alignment - -def main(page: Page): +def main(page: ft.Page): page.add( - Container( - alignment=alignment.center, - gradient=LinearGradient( - begin=alignment.top_left, - end=Alignment(0.8, 1), + ft.Container( + alignment=ft.alignment.center, + gradient=ft.LinearGradient( + begin=ft.alignment.top_left, + end=ft.Alignment(0.8, 1), colors=[ "0xff1f005c", "0xff5b0060", @@ -22,7 +20,7 @@ def main(page: Page): "0xfff39060", "0xffffb56b", ], - tile_mode="mirror", + tile_mode=ft.GradientTileMode.MIRROR, rotation=math.pi / 3, ), width=150, @@ -32,4 +30,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/nested-themes-simple.py b/python/controls/layout/container/nested-themes-simple.py index e3a6539d..9b8a6a0e 100644 --- a/python/controls/layout/container/nested-themes-simple.py +++ b/python/controls/layout/container/nested-themes-simple.py @@ -4,31 +4,31 @@ def main(page: ft.Page): # Yellow page theme with SYSTEM (default) mode page.theme = ft.Theme( - color_scheme_seed=ft.colors.YELLOW, + color_scheme_seed=ft.Colors.YELLOW, ) page.add( # Page theme ft.Container( content=ft.ElevatedButton("Page theme button"), - bgcolor=ft.colors.SURFACE_VARIANT, + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), # Inherited theme with primary color overridden ft.Container( - theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.colors.PINK)), + theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.Colors.PINK)), content=ft.ElevatedButton("Inherited theme button"), - bgcolor=ft.colors.SURFACE_VARIANT, + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), # Unique always DARK theme ft.Container( - theme=ft.Theme(color_scheme_seed=ft.colors.INDIGO), + theme=ft.Theme(color_scheme_seed=ft.Colors.INDIGO), theme_mode=ft.ThemeMode.DARK, content=ft.ElevatedButton("Unique theme button"), - bgcolor=ft.colors.SURFACE_VARIANT, + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, padding=20, width=300, ), diff --git a/python/controls/layout/container/nested-themes-switch.py b/python/controls/layout/container/nested-themes-switch.py new file mode 100644 index 00000000..79f91626 --- /dev/null +++ b/python/controls/layout/container/nested-themes-switch.py @@ -0,0 +1,59 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.DARK + + def change_theme_mode(e): + if page.theme_mode == ft.ThemeMode.DARK: + page.theme_mode = ft.ThemeMode.LIGHT + sw.thumb_icon = ft.Icons.LIGHT_MODE + else: + sw.thumb_icon = ft.Icons.DARK_MODE + page.theme_mode = ft.ThemeMode.DARK + page.update() + + # Yellow page theme with SYSTEM (default) mode + page.theme = ft.Theme( + color_scheme_seed=ft.Colors.YELLOW, + ) + sw = ft.Switch(thumb_icon=ft.Icons.DARK_MODE, on_change=change_theme_mode) + page.add( + # Page theme + ft.Row( + [ + ft.Container( + content=ft.ElevatedButton("Page theme button"), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + padding=20, + width=300, + ), + ft.Container( + content=sw, + padding=ft.padding.only(bottom=50), + alignment=ft.alignment.top_right, + ), + ], + alignment=ft.MainAxisAlignment.SPACE_BETWEEN, + ), + # Inherited theme with primary color overridden + ft.Container( + theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.Colors.PINK)), + content=ft.ElevatedButton("Inherited theme button"), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + padding=20, + width=300, + ), + # Unique always DARK theme + ft.Container( + theme=ft.Theme(color_scheme_seed=ft.Colors.INDIGO), + theme_mode=ft.ThemeMode.DARK, + content=ft.ElevatedButton("Unique theme button"), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + padding=20, + width=300, + ), + ) + + +ft.app(main) diff --git a/python/controls/layout/container/nested-themes.py b/python/controls/layout/container/nested-themes.py index 7c285663..c3be6b3d 100644 --- a/python/controls/layout/container/nested-themes.py +++ b/python/controls/layout/container/nested-themes.py @@ -3,9 +3,9 @@ def main(page: ft.Page): page.theme = ft.Theme( - color_scheme_seed=ft.colors.YELLOW, + color_scheme_seed=ft.Colors.YELLOW, color_scheme=ft.ColorScheme( - primary=ft.colors.GREEN, primary_container=ft.colors.GREEN_200 + primary=ft.Colors.GREEN, primary_container=ft.Colors.GREEN_200 ), ) @@ -16,7 +16,7 @@ def main(page: ft.Page): ft.TextButton("Page theme text button"), ft.Text( "Text in primary container color", - color=ft.colors.PRIMARY_CONTAINER, + color=ft.Colors.PRIMARY_CONTAINER, ), ] ), @@ -28,7 +28,7 @@ def main(page: ft.Page): ] ), height=100, - theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.colors.PINK)), + theme=ft.Theme(color_scheme=ft.ColorScheme(primary=ft.Colors.PINK)), ), ft.Container( content=ft.Row( @@ -37,16 +37,16 @@ def main(page: ft.Page): ft.TextButton("Text button"), ft.Text( "Text in primary container color", - color=ft.colors.PRIMARY_CONTAINER, + color=ft.Colors.PRIMARY_CONTAINER, ), ] ), padding=20, - bgcolor=ft.colors.BACKGROUND, + bgcolor=ft.Colors.SURFACE, theme_mode=ft.ThemeMode.DARK, theme=ft.Theme( - color_scheme_seed=ft.colors.GREEN, - color_scheme=ft.ColorScheme(primary_container=ft.colors.BLUE), + color_scheme_seed=ft.Colors.GREEN, + color_scheme=ft.ColorScheme(primary_container=ft.Colors.BLUE), ), ), ft.Container( @@ -56,13 +56,13 @@ def main(page: ft.Page): ft.TextButton("Text button"), ft.Text( "Text in primary container color", - color=ft.colors.PRIMARY_CONTAINER, + color=ft.Colors.PRIMARY_CONTAINER, ), ] ), padding=20, - bgcolor=ft.colors.SURFACE_VARIANT, - border=ft.border.all(3, ft.colors.OUTLINE), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + border=ft.border.all(3, ft.Colors.OUTLINE), theme_mode=ft.ThemeMode.LIGHT, theme=ft.Theme(), ), @@ -73,13 +73,13 @@ def main(page: ft.Page): ft.TextButton("Text button"), ft.Text( "Text in primary container color", - color=ft.colors.PRIMARY_CONTAINER, + color=ft.Colors.PRIMARY_CONTAINER, ), ] ), padding=20, - bgcolor=ft.colors.SURFACE, - border=ft.border.all(3, ft.colors.OUTLINE), + bgcolor=ft.Colors.SURFACE, + border=ft.border.all(3, ft.Colors.OUTLINE), border_radius=10, theme_mode=ft.ThemeMode.SYSTEM, theme=ft.Theme(), diff --git a/python/controls/layout/container/radial-gradient.py b/python/controls/layout/container/radial-gradient.py index 36f96993..a74b78c2 100644 --- a/python/controls/layout/container/radial-gradient.py +++ b/python/controls/layout/container/radial-gradient.py @@ -1,14 +1,13 @@ -import flet -from flet import Alignment, Container, Page, RadialGradient, alignment +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - Container( - alignment=alignment.center, - gradient=RadialGradient( - center=Alignment(0.7, -0.6), + ft.Container( + alignment=ft.alignment.center, + gradient=ft.RadialGradient( + center=ft.Alignment(0.7, -0.6), radius=0.2, colors=[ "0xFFFFFF00", # yellow sun @@ -23,4 +22,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/container/sweep-gradient.py b/python/controls/layout/container/sweep-gradient.py index 67b3e694..34a0a8ec 100644 --- a/python/controls/layout/container/sweep-gradient.py +++ b/python/controls/layout/container/sweep-gradient.py @@ -1,16 +1,14 @@ import math +import flet as ft -import flet -from flet import Container, Page, SweepGradient, alignment - -def main(page: Page): +def main(page: ft.Page): page.add( - Container( - alignment=alignment.center, - gradient=SweepGradient( - center=alignment.center, + ft.Container( + alignment=ft.alignment.center, + gradient=ft.SweepGradient( + center=ft.alignment.center, start_angle=0.0, end_angle=math.pi * 2, colors=[ @@ -29,4 +27,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) From 5351cf1c18470b2319adeb490da724feac3dd6ce Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 28 Feb 2025 16:50:39 -0800 Subject: [PATCH 27/81] add simple-hover.py --- python/controls/layout/container/simple-hover.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 python/controls/layout/container/simple-hover.py diff --git a/python/controls/layout/container/simple-hover.py b/python/controls/layout/container/simple-hover.py new file mode 100644 index 00000000..0cc41858 --- /dev/null +++ b/python/controls/layout/container/simple-hover.py @@ -0,0 +1,14 @@ +import flet as ft + + +def main(page: ft.Page): + def on_hover(e): + e.control.bgcolor = "blue" if e.data == "true" else "red" + e.control.update() + + page.add( + ft.Container(width=100, height=100, bgcolor="red", ink=False, on_hover=on_hover) + ) + + +ft.app(main) From 90ed13059b21fc8e0448af3d3598a3797987edc4 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sun, 2 Mar 2025 12:05:04 -0800 Subject: [PATCH 28/81] add container-click-event example --- .../container/container-click-events.py | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 python/controls/layout/container/container-click-events.py diff --git a/python/controls/layout/container/container-click-events.py b/python/controls/layout/container/container-click-events.py new file mode 100644 index 00000000..fb64622f --- /dev/null +++ b/python/controls/layout/container/container-click-events.py @@ -0,0 +1,107 @@ +import flet as ft + + +def main(page: ft.Page): + + page.theme_mode = ft.ThemeMode.LIGHT + page.vertical_alignment = ft.MainAxisAlignment.CENTER + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + lp_counter = 0 + cl_counter = 0 + td_counter = 0 + + def on_click(e): + nonlocal cl_counter + cl_counter += 1 + t1.spans[-1] = ft.TextSpan( + f" {cl_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ) + + page.update() + + def on_long_press(e): + nonlocal lp_counter + lp_counter += 1 + t3.spans[-1] = ft.TextSpan( + f" {lp_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ) + page.update() + + def on_tap_down(e: ft.ContainerTapEvent): + nonlocal td_counter + td_counter += 1 + t2.spans[-1] = ft.TextSpan( + f" {td_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ) + page.update() + + c = ft.Container( + bgcolor=ft.Colors.PINK_900, + content=ft.Text( + "Press Me!", + text_align=ft.TextAlign.CENTER, + style=ft.TextStyle( + size=30, + # weight=ft.FontWeight.BOLD, + foreground=ft.Paint( + color=ft.Colors.BLUE_700, + stroke_cap=ft.StrokeCap.BUTT, + stroke_width=2, + stroke_join=ft.StrokeJoin.BEVEL, + style=ft.PaintingStyle.STROKE, + ), + ), + theme_style=ft.TextThemeStyle.DISPLAY_MEDIUM, + ), + alignment=ft.alignment.center, + padding=ft.padding.all(10), + height=150, + width=150, + on_click=on_click, + on_long_press=on_long_press, + on_tap_down=on_tap_down, + ) + t1 = ft.Text( + spans=[ + ft.TextSpan( + "On Click", style=ft.TextStyle(size=16, weight=ft.FontWeight.BOLD) + ), + ft.TextSpan(" counter: ", style=ft.TextStyle(size=16, italic=True)), + ft.TextSpan( + f" {cl_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ), + ] + ) + t2 = ft.Text( + spans=[ + ft.TextSpan( + "Tap Down", style=ft.TextStyle(size=16, weight=ft.FontWeight.BOLD) + ), + ft.TextSpan(" counter: ", style=ft.TextStyle(size=16, italic=True)), + ft.TextSpan( + f" {td_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ), + ] + ) + t3 = ft.Text( + spans=[ + ft.TextSpan( + "Long Press", style=ft.TextStyle(size=16, weight=ft.FontWeight.BOLD) + ), + ft.TextSpan(" counter: ", style=ft.TextStyle(size=16, italic=True)), + ft.TextSpan( + f" {lp_counter} ", + style=ft.TextStyle(size=16, bgcolor=ft.Colors.TEAL_300), + ), + ] + ) + + page.add(c, t1, t3, t2) + + +ft.app(main) From af3eace37e8bc505936a919e31b17d72a3ed6f16 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 3 Mar 2025 15:18:20 -0800 Subject: [PATCH 29/81] add datatble-selectable.py --- .../layout/data-table/datatable-selectable.py | 82 +++++++++++++++++++ .../layout/data-table/simple-datatable.py | 39 +++++++++ 2 files changed, 121 insertions(+) create mode 100644 python/controls/layout/data-table/datatable-selectable.py create mode 100644 python/controls/layout/data-table/simple-datatable.py diff --git a/python/controls/layout/data-table/datatable-selectable.py b/python/controls/layout/data-table/datatable-selectable.py new file mode 100644 index 00000000..edda7937 --- /dev/null +++ b/python/controls/layout/data-table/datatable-selectable.py @@ -0,0 +1,82 @@ +import flet as ft + + +def main(page: ft.Page): + def selection_change(e): + print(f"selection_change called with {e.control.data}") + match e.control.data: + case 1: + dr1.selected = not dr1.selected + case 2: + dr2.selected = not dr2.selected + case 3: + dr3.selected = not dr3.selected + page.update() + + def sort(e): + print(f"sort called with {e.data} {e.control}") + match e.control.data: + case 1: + print(f"{e.column_index}, {e.ascending}") + # dt.sort_column_index = 1 + dt.sort_ascending = not dt.sort_ascending + case 2: + print(f"{e.column_index}, {e.ascending}") + # dt.sort_column_index = 2 + dt.sort_ascending = not dt.sort_ascending + page.update() + + dr1 = ft.DataRow( + [ft.DataCell(ft.Text("A")), ft.DataCell(ft.Text("1"))], + selected=True, + on_select_changed=selection_change, + data=1, + ) + dr2 = ft.DataRow( + [ft.DataCell(ft.Text("B")), ft.DataCell(ft.Text("2"))], + selected=False, + on_select_changed=selection_change, + data=2, + ) + dr3 = ft.DataRow( + [ft.DataCell(ft.Text("C")), ft.DataCell(ft.Text("3"))], + selected=False, + on_select_changed=selection_change, + data=3, + ) + dc1 = ft.DataColumn( + ft.Text("Column 1"), + tooltip="This is the first column", + data=1, + on_sort=sort, + ) + dc2 = ft.DataColumn( + ft.Text("Column 2"), + tooltip="This is a second column", + numeric=True, + data=2, + on_sort=sort, + ) + dt = ft.DataTable( + width=700, + bgcolor=ft.Colors.TEAL_ACCENT_200, + border=ft.border.all(2, ft.Colors.RED_ACCENT_200), + border_radius=10, + vertical_lines=ft.border.BorderSide(3, ft.Colors.BLUE_600), + horizontal_lines=ft.border.BorderSide(1, ft.Colors.GREEN_600), + sort_column_index=0, + sort_ascending=True, + heading_row_color=ft.colors.BLACK12, + heading_row_height=100, + data_row_color={ft.ControlState.HOVERED: "0x30FF0000"}, + show_checkbox_column=True, + divider_thickness=0, + column_spacing=200, + columns=[dc1, dc2], + rows=[dr1, dr2, dr3], + ) + + page.add(dt) + + +ft.app(target=main) diff --git a/python/controls/layout/data-table/simple-datatable.py b/python/controls/layout/data-table/simple-datatable.py new file mode 100644 index 00000000..ca5233e3 --- /dev/null +++ b/python/controls/layout/data-table/simple-datatable.py @@ -0,0 +1,39 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.DataTable( + columns=[ + ft.DataColumn(ft.Text("First name")), + ft.DataColumn(ft.Text("Last name")), + ft.DataColumn(ft.Text("Age"), numeric=True), + ], + rows=[ + ft.DataRow( + cells=[ + ft.DataCell(ft.Text("John")), + ft.DataCell(ft.Text("Smith")), + ft.DataCell(ft.Text("43")), + ], + ), + ft.DataRow( + cells=[ + ft.DataCell(ft.Text("Jack")), + ft.DataCell(ft.Text("Brown")), + ft.DataCell(ft.Text("19")), + ], + ), + ft.DataRow( + cells=[ + ft.DataCell(ft.Text("Alice")), + ft.DataCell(ft.Text("Wong")), + ft.DataCell(ft.Text("25")), + ], + ), + ], + ), + ) + + +ft.app(main) From 3f41b7e9893e57e0eb515e72f504947acfe152ad Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 3 Mar 2025 16:27:28 -0800 Subject: [PATCH 30/81] add dismissable-listview example --- .../dismissable/dismissable-listview.py | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 python/controls/layout/dismissable/dismissable-listview.py diff --git a/python/controls/layout/dismissable/dismissable-listview.py b/python/controls/layout/dismissable/dismissable-listview.py new file mode 100644 index 00000000..b4334f53 --- /dev/null +++ b/python/controls/layout/dismissable/dismissable-listview.py @@ -0,0 +1,60 @@ +import flet as ft + + +def main(page): + def handle_dlg_action_clicked(e): + page.close(dlg) + dlg.data.confirm_dismiss(e.control.data) + + dlg = ft.AlertDialog( + modal=True, + title=ft.Text("Please confirm"), + content=ft.Text("Do you really want to delete this item?"), + actions=[ + ft.TextButton("Yes", data=True, on_click=handle_dlg_action_clicked), + ft.TextButton("No", data=False, on_click=handle_dlg_action_clicked), + ], + actions_alignment=ft.MainAxisAlignment.CENTER, + ) + + def handle_confirm_dismiss(e: ft.DismissibleDismissEvent): + if e.direction == ft.DismissDirection.END_TO_START: # right-to-left slide + # save current dismissible to dialog's data, for confirmation in handle_dlg_action_clicked + dlg.data = e.control + page.open(dlg) + else: # left-to-right slide + e.control.confirm_dismiss(True) + + def handle_dismiss(e): + e.control.parent.controls.remove(e.control) + page.update() + + def handle_update(e: ft.DismissibleUpdateEvent): + print( + f"Update - direction: {e.direction}, progress: {e.progress}, reached: {e.reached}, previous_reached: {e.previous_reached}" + ) + + page.add( + ft.ListView( + expand=True, + controls=[ + ft.Dismissible( + content=ft.ListTile(title=ft.Text(f"Item {i}")), + dismiss_direction=ft.DismissDirection.HORIZONTAL, + background=ft.Container(bgcolor=ft.Colors.GREEN), + secondary_background=ft.Container(bgcolor=ft.Colors.RED), + on_dismiss=handle_dismiss, + on_update=handle_update, + on_confirm_dismiss=handle_confirm_dismiss, + dismiss_thresholds={ + ft.DismissDirection.END_TO_START: 0.2, + ft.DismissDirection.START_TO_END: 0.2, + }, + ) + for i in range(10) + ], + ) + ) + + +ft.app(main) From 1aaa63b92a04fd7d45f77b8a924a28e040e42bb4 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 3 Mar 2025 20:30:42 -0800 Subject: [PATCH 31/81] update divider-horiz.py --- .../controls/layout/divider/divider-horiz.py | 37 ++++++++++--------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/python/controls/layout/divider/divider-horiz.py b/python/controls/layout/divider/divider-horiz.py index 8d6cb03d..8827fe68 100644 --- a/python/controls/layout/divider/divider-horiz.py +++ b/python/controls/layout/divider/divider-horiz.py @@ -1,29 +1,30 @@ -import flet -from flet import Column, Container, Divider, Page, alignment, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - Column( + ft.Column( [ - Container( - bgcolor=colors.AMBER, - alignment=alignment.center, + ft.Container( + bgcolor=ft.Colors.AMBER, + alignment=ft.alignment.center, expand=True, ), - Divider(), - Container(bgcolor=colors.PINK, alignment=alignment.center, expand=True), - Divider(height=1, color="white"), - Container( - bgcolor=colors.BLUE_300, - alignment=alignment.center, + ft.Divider(), + ft.Container( + bgcolor=ft.Colors.PINK, alignment=ft.alignment.center, expand=True + ), + ft.Divider(height=1, color="white"), + ft.Container( + bgcolor=ft.Colors.BLUE_300, + alignment=ft.alignment.center, expand=True, ), - Divider(height=9, thickness=3), - Container( - bgcolor=colors.DEEP_PURPLE_200, - alignment=alignment.center, + ft.Divider(height=9, thickness=3), + ft.Container( + bgcolor=ft.Colors.DEEP_PURPLE_200, + alignment=ft.alignment.center, expand=True, ), ], @@ -33,4 +34,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) From e24dbe35a52fffc4a46f997be77264f9f97c4570 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 3 Mar 2025 22:16:07 -0800 Subject: [PATCH 32/81] add/fix expansion-panel-list example --- .../expansion-panel-list.py | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 python/controls/layout/expansion-panel-list/expansion-panel-list.py diff --git a/python/controls/layout/expansion-panel-list/expansion-panel-list.py b/python/controls/layout/expansion-panel-list/expansion-panel-list.py new file mode 100644 index 00000000..09cab23b --- /dev/null +++ b/python/controls/layout/expansion-panel-list/expansion-panel-list.py @@ -0,0 +1,54 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + + def handle_change(e: ft.ControlEvent): + print(f"change on panel with index {e.data}") + + def handle_delete(e: ft.ControlEvent): + panel.controls.remove(e.control.data) + page.update() + + panel = ft.ExpansionPanelList( + expand_icon_color=ft.Colors.AMBER, + elevation=8, + divider_color=ft.Colors.AMBER, + on_change=handle_change, + controls=[ + ft.ExpansionPanel( + # has no header and content - placeholders will be used + bgcolor=ft.Colors.BLUE_400, + expanded=True, + ) + ], + ) + + colors = [ + ft.Colors.GREEN_500, + ft.Colors.BLUE_800, + ft.Colors.RED_800, + ] + + for i in range(3): + bgcolor = colors[i % len(colors)] + + exp = ft.ExpansionPanel( + bgcolor=bgcolor, + header=ft.ListTile(title=ft.Text(f"Panel {i}"), bgcolor=bgcolor), + ) + + exp.content = ft.ListTile( + title=ft.Text(f"This is in Panel {i}"), + subtitle=ft.Text(f"Press the icon to delete panel {i}"), + trailing=ft.IconButton(ft.Icons.DELETE, on_click=handle_delete, data=exp), + bgcolor=bgcolor, + ) + + panel.controls.append(exp) + + page.add(panel) + + +ft.app(main) From 87951aabf8f3eacf82f56fc738fac4692ea1fe1a Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 4 Mar 2025 13:39:04 -0800 Subject: [PATCH 33/81] add expansion-tile examples --- .../expansion-tile/expansion-tile-borders.py | 35 +++++++ .../expansion-tile/expansion-tile-switch.py | 91 +++++++++++++++++++ .../layout/expansion-tile/expansion-tile.py | 68 ++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 python/controls/layout/expansion-tile/expansion-tile-borders.py create mode 100644 python/controls/layout/expansion-tile/expansion-tile-switch.py create mode 100644 python/controls/layout/expansion-tile/expansion-tile.py diff --git a/python/controls/layout/expansion-tile/expansion-tile-borders.py b/python/controls/layout/expansion-tile/expansion-tile-borders.py new file mode 100644 index 00000000..6ce840c1 --- /dev/null +++ b/python/controls/layout/expansion-tile/expansion-tile-borders.py @@ -0,0 +1,35 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + + page.add( + ft.ExpansionTile( + title=ft.Text("Expansion Tile with changing borders"), + subtitle=ft.Text("Tile border changes when expanded"), + bgcolor=ft.Colors.BLUE_GREY_200, + collapsed_bgcolor=ft.Colors.BLUE_GREY_200, + affinity=ft.TileAffinity.PLATFORM, + maintain_state=True, + shape=ft.StadiumBorder(), + collapsed_shape=ft.StadiumBorder(), + collapsed_text_color=ft.Colors.GREY_800, + text_color=ft.Colors.GREY_800, + controls=[ + ft.ListTile( + title=ft.Text("A sub-tile"), + bgcolor=ft.Colors.BLUE_GREY_200, + # shape=ft.StadiumBorder(), + ), + ft.ListTile( + title=ft.Text("Another sub-tile"), + bgcolor=ft.Colors.BLUE_GREY_200, + # shape=ft.StadiumBorder(), + ), + ], + ), + ) + + +ft.app(main) diff --git a/python/controls/layout/expansion-tile/expansion-tile-switch.py b/python/controls/layout/expansion-tile/expansion-tile-switch.py new file mode 100644 index 00000000..a05426d7 --- /dev/null +++ b/python/controls/layout/expansion-tile/expansion-tile-switch.py @@ -0,0 +1,91 @@ +import flet as ft + + +def main(page: ft.Page): + + page.spacing = 0 + page.padding = 0 + + def change_theme_mode(e): + if page.theme_mode == ft.ThemeMode.DARK: + page.theme_mode = ft.ThemeMode.LIGHT + sw.thumb_icon = ft.Icons.LIGHT_MODE + else: + sw.thumb_icon = ft.Icons.DARK_MODE + page.theme_mode = ft.ThemeMode.DARK + page.update() + + def handle_expansion_tile_change(e): + page.open( + ft.SnackBar( + ft.Text( + f"ExpansionTile was {'expanded' if e.data=='true' else 'collapsed'}" + ), + duration=1000, + ) + ) + if e.control.trailing: + e.control.trailing.name = ( + ft.Icons.ARROW_DROP_DOWN + if e.control.trailing.name == ft.Icons.ARROW_DROP_DOWN_CIRCLE + else ft.Icons.ARROW_DROP_DOWN_CIRCLE + ) + page.update() + + sw = ft.Switch(thumb_icon=ft.Icons.DARK_MODE, on_change=change_theme_mode) + + page.add( + ft.ExpansionTile( + title=ft.Text("ExpansionTile 1"), + subtitle=ft.Text("Trailing expansion arrow icon"), + bgcolor=ft.Colors.BLUE_GREY_200, + collapsed_bgcolor=ft.Colors.BLUE_GREY_200, + affinity=ft.TileAffinity.PLATFORM, + maintain_state=True, + collapsed_text_color=ft.Colors.RED, + text_color=ft.Colors.RED, + controls=[ + ft.ListTile( + title=ft.Text("This is sub-tile number 1"), + bgcolor=ft.Colors.BLUE_GREY_200, + ) + ], + ), + ft.ExpansionTile( + title=ft.Text("ExpansionTile 2"), + subtitle=ft.Text("Custom expansion arrow icon"), + trailing=ft.Icon(ft.Icons.ARROW_DROP_DOWN), + collapsed_text_color=ft.Colors.GREEN, + text_color=ft.Colors.GREEN, + on_change=handle_expansion_tile_change, + controls=[ft.ListTile(title=ft.Text("This is sub-tile number 2"))], + ), + ft.ExpansionTile( + title=ft.Text("ExpansionTile 3"), + subtitle=ft.Text("Leading expansion arrow icon"), + affinity=ft.TileAffinity.LEADING, + initially_expanded=True, + collapsed_text_color=ft.Colors.BLUE_800, + text_color=ft.Colors.BLUE_200, + controls=[ + ft.ListTile(title=ft.Text("This is sub-tile number 3")), + ft.ListTile(title=ft.Text("This is sub-tile number 4")), + ft.ListTile(title=ft.Text("This is sub-tile number 5")), + ], + ), + ft.Row( + [ + ft.Container( + content=sw, + padding=ft.padding.only(bottom=50), + alignment=ft.alignment.bottom_right, + expand=True, + ), + ], + expand=True, + alignment=ft.MainAxisAlignment.END, + ), + ) + + +ft.app(main) diff --git a/python/controls/layout/expansion-tile/expansion-tile.py b/python/controls/layout/expansion-tile/expansion-tile.py new file mode 100644 index 00000000..616d95f9 --- /dev/null +++ b/python/controls/layout/expansion-tile/expansion-tile.py @@ -0,0 +1,68 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + page.spacing = 0 + page.padding = 0 + + def handle_expansion_tile_change(e): + page.open( + ft.SnackBar( + ft.Text( + f"ExpansionTile was {'expanded' if e.data=='true' else 'collapsed'}" + ), + duration=1000, + ) + ) + if e.control.trailing: + e.control.trailing.name = ( + ft.Icons.ARROW_DROP_DOWN + if e.control.trailing.name == ft.Icons.ARROW_DROP_DOWN_CIRCLE + else ft.Icons.ARROW_DROP_DOWN_CIRCLE + ) + page.update() + + page.add( + ft.ExpansionTile( + title=ft.Text("ExpansionTile 1"), + subtitle=ft.Text("Trailing expansion arrow icon"), + bgcolor=ft.Colors.BLUE_GREY_200, + collapsed_bgcolor=ft.Colors.BLUE_GREY_200, + affinity=ft.TileAffinity.PLATFORM, + maintain_state=True, + collapsed_text_color=ft.Colors.RED, + text_color=ft.Colors.RED, + controls=[ + ft.ListTile( + title=ft.Text("This is sub-tile number 1"), + bgcolor=ft.Colors.BLUE_GREY_200, + ) + ], + ), + ft.ExpansionTile( + title=ft.Text("ExpansionTile 2"), + subtitle=ft.Text("Custom expansion arrow icon"), + trailing=ft.Icon(ft.Icons.ARROW_DROP_DOWN), + collapsed_text_color=ft.Colors.GREEN, + text_color=ft.Colors.GREEN, + on_change=handle_expansion_tile_change, + controls=[ft.ListTile(title=ft.Text("This is sub-tile number 2"))], + ), + ft.ExpansionTile( + title=ft.Text("ExpansionTile 3"), + subtitle=ft.Text("Leading expansion arrow icon"), + affinity=ft.TileAffinity.LEADING, + initially_expanded=True, + collapsed_text_color=ft.Colors.BLUE_800, + text_color=ft.Colors.BLUE_200, + controls=[ + ft.ListTile(title=ft.Text("This is sub-tile number 3")), + ft.ListTile(title=ft.Text("This is sub-tile number 4")), + ft.ListTile(title=ft.Text("This is sub-tile number 5")), + ], + ), + ) + + +ft.app(main) From aaf3ed03b4d97a8fa46d9f451a758b5a56d40f37 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 4 Mar 2025 14:38:17 -0800 Subject: [PATCH 34/81] update list-tiles and grid-view --- .../layout/grid-view/photo-gallery.py | 19 ++--- python/controls/layout/list-tile/listtiles.py | 85 ------------------- 2 files changed, 9 insertions(+), 95 deletions(-) delete mode 100644 python/controls/layout/list-tile/listtiles.py diff --git a/python/controls/layout/grid-view/photo-gallery.py b/python/controls/layout/grid-view/photo-gallery.py index ffc0ef72..90bdd2ea 100644 --- a/python/controls/layout/grid-view/photo-gallery.py +++ b/python/controls/layout/grid-view/photo-gallery.py @@ -1,14 +1,13 @@ -import flet -from flet import GridView, Image, Page, border_radius +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "GridView Example" - page.theme_mode = "dark" + page.theme_mode = ft.ThemeMode.DARK page.padding = 50 page.update() - images = GridView( + images = ft.GridView( expand=1, runs_count=5, max_extent=150, @@ -21,14 +20,14 @@ def main(page: Page): for i in range(0, 60): images.controls.append( - Image( + ft.Image( src=f"https://picsum.photos/150/150?{i}", - fit="none", - repeat="noRepeat", - border_radius=border_radius.all(10), + fit=ft.ImageFit.NONE, + repeat=ft.ImageRepeat.NO_REPEAT, + border_radius=ft.border_radius.all(10), ) ) page.update() -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/list-tile/listtiles.py b/python/controls/layout/list-tile/listtiles.py deleted file mode 100644 index 91d7cdd9..00000000 --- a/python/controls/layout/list-tile/listtiles.py +++ /dev/null @@ -1,85 +0,0 @@ -import logging - -import flet -from flet import ( - Card, - Column, - Container, - Icon, - Image, - ListTile, - PopupMenuButton, - PopupMenuItem, - Text, - icons, - padding, -) - -logging.basicConfig(level=logging.DEBUG) - - -def main(page): - page.title = "ListTile Examples" - # page.theme_mode = "dark" - page.add( - Card( - content=Container( - width=500, - content=Column( - [ - ListTile( - title=Text("One-line list tile"), - ), - ListTile(title=Text("One-line dense list tile"), dense=True), - ListTile( - leading=Icon(icons.SETTINGS), - title=Text("One-line selected list tile"), - selected=True, - ), - ListTile( - leading=Image(src="/icons/icon-192.png", fit="contain"), - title=Text("One-line with leading control"), - ), - ListTile( - title=Text("One-line with trailing control"), - trailing=PopupMenuButton( - icon=icons.MORE_VERT, - items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(text="Item 2"), - ], - ), - ), - ListTile( - leading=Icon(icons.ALBUM), - title=Text("One-line with leading and trailing controls"), - trailing=PopupMenuButton( - icon=icons.MORE_VERT, - items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(text="Item 2"), - ], - ), - ), - ListTile( - leading=Icon(icons.SNOOZE), - title=Text("Two-line with leading and trailing controls"), - subtitle=Text("Here is a second title."), - trailing=PopupMenuButton( - icon=icons.MORE_VERT, - items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(text="Item 2"), - ], - ), - ), - ], - spacing=0, - ), - padding=padding.symmetric(vertical=10), - ) - ) - ) - - -flet.app(target=main) From 5d4c04dd09ae303dca352366c334f6d4431d1bb8 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 4 Mar 2025 14:41:21 -0800 Subject: [PATCH 35/81] add list-tile folder --- .../layout/list-tile/list-tile-examples.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 python/controls/layout/list-tile/list-tile-examples.py diff --git a/python/controls/layout/list-tile/list-tile-examples.py b/python/controls/layout/list-tile/list-tile-examples.py new file mode 100644 index 00000000..bfac216f --- /dev/null +++ b/python/controls/layout/list-tile/list-tile-examples.py @@ -0,0 +1,73 @@ +import flet as ft + + +def main(page): + page.title = "ListTile Examples" + page.add( + ft.Card( + content=ft.Container( + width=500, + content=ft.Column( + [ + ft.ListTile( + title=ft.Text("One-line list tile"), + ), + ft.ListTile( + title=ft.Text("One-line dense list tile"), dense=True + ), + ft.ListTile( + leading=ft.Icon(ft.Icons.SETTINGS), + title=ft.Text("One-line selected list tile"), + selected=True, + ), + ft.ListTile( + leading=ft.Image(src="/icons/icon-192.png", fit="contain"), + title=ft.Text("One-line with leading control"), + ), + ft.ListTile( + title=ft.Text("One-line with trailing control"), + trailing=ft.PopupMenuButton( + icon=ft.Icons.MORE_VERT, + items=[ + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(text="Item 2"), + ], + ), + ), + ft.ListTile( + leading=ft.Icon(ft.Icons.ALBUM), + title=ft.Text( + "One-line with leading and trailing controls" + ), + trailing=ft.PopupMenuButton( + icon=ft.Icons.MORE_VERT, + items=[ + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(text="Item 2"), + ], + ), + ), + ft.ListTile( + leading=ft.Icon(ft.Icons.SNOOZE), + title=ft.Text( + "Two-line with leading and trailing controls" + ), + subtitle=ft.Text("Here is a second title."), + trailing=ft.PopupMenuButton( + icon=ft.Icons.MORE_VERT, + items=[ + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(text="Item 2"), + ], + ), + ), + ], + spacing=0, + ), + padding=ft.padding.symmetric(vertical=10), + ) + ) + ) + + +ft.app(main) From 642eb5f301599efd3080d103600109036758757d Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 06:30:57 -0800 Subject: [PATCH 36/81] add listview-toggle-scroll example --- .../layout/list-view/listview-scroll.py | 14 +++--- .../list-view/listview-toggle-scroll.py | 47 +++++++++++++++++++ 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 python/controls/layout/list-view/listview-toggle-scroll.py diff --git a/python/controls/layout/list-view/listview-scroll.py b/python/controls/layout/list-view/listview-scroll.py index 93fc2c53..ffc60c7b 100644 --- a/python/controls/layout/list-view/listview-scroll.py +++ b/python/controls/layout/list-view/listview-scroll.py @@ -1,27 +1,25 @@ from time import sleep +import flet as ft -import flet -from flet import ListView, Page, Text - -def main(page: Page): +def main(page: ft.Page): page.title = "Auto-scrolling ListView" - lv = ListView(expand=1, spacing=10, padding=20, auto_scroll=True) + lv = ft.ListView(expand=1, spacing=10, padding=20, auto_scroll=True) count = 1 for i in range(0, 60): - lv.controls.append(Text(f"Line {count}")) + lv.controls.append(ft.Text(f"Line {count}")) count += 1 page.add(lv) for i in range(0, 60): sleep(1) - lv.controls.append(Text(f"Line {count}")) + lv.controls.append(ft.Text(f"Line {count}")) count += 1 page.update() -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/list-view/listview-toggle-scroll.py b/python/controls/layout/list-view/listview-toggle-scroll.py new file mode 100644 index 00000000..583a3a0c --- /dev/null +++ b/python/controls/layout/list-view/listview-toggle-scroll.py @@ -0,0 +1,47 @@ +from time import sleep +import flet as ft + + +def main(page: ft.Page): + page.title = "Auto-scrolling ListView" + + def change_auto_scroll(e): + print("Change auto scroll triggered") + lv.auto_scroll = not lv.auto_scroll + page.update() + + lv = ft.ListView(spacing=10, padding=20, width=150, auto_scroll=True) + lvc = ft.Container( + content=lv, + bgcolor=ft.Colors.GREY_500, + ) + sw = ft.Switch( + thumb_icon=ft.Icons.LIST_OUTLINED, + value=True, + label="Auto-scroll", + label_position=ft.LabelPosition.RIGHT, + on_change=change_auto_scroll, + ) + + c = ft.Row( + [lvc, sw], + expand=True, + vertical_alignment=ft.CrossAxisAlignment.START, + ) + + count = 1 + + for i in range(0, 60): + lv.controls.append(ft.Text(f"Line {count}", color=ft.Colors.ON_SECONDARY)) + count += 1 + + page.add(c) + + for i in range(0, 60): + sleep(1) + lv.controls.append(ft.Text(f"Line {count}", color=ft.Colors.ON_SECONDARY)) + count += 1 + page.update() + + +ft.app(main) From fee269c23d7da7412d599c784b3f2ab2a0b3ae01 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 08:01:00 -0800 Subject: [PATCH 37/81] update page examples --- .../list-view/listview-toggle-scroll.py | 1 - .../layout/page/app-exit-confirm-dialog.py | 32 +++++++++---------- .../controls/layout/page/keyboard-events.py | 25 ++++++++------- python/controls/layout/page/set-platform.py | 24 ++++++++++++++ python/controls/layout/page/splash-test.py | 13 ++++---- .../layout/page/window-hidden-on-start.py | 17 ++++------ 6 files changed, 66 insertions(+), 46 deletions(-) create mode 100644 python/controls/layout/page/set-platform.py diff --git a/python/controls/layout/list-view/listview-toggle-scroll.py b/python/controls/layout/list-view/listview-toggle-scroll.py index 583a3a0c..0b15df5e 100644 --- a/python/controls/layout/list-view/listview-toggle-scroll.py +++ b/python/controls/layout/list-view/listview-toggle-scroll.py @@ -3,7 +3,6 @@ def main(page: ft.Page): - page.title = "Auto-scrolling ListView" def change_auto_scroll(e): print("Change auto scroll triggered") diff --git a/python/controls/layout/page/app-exit-confirm-dialog.py b/python/controls/layout/page/app-exit-confirm-dialog.py index 53fcc458..3c88213d 100644 --- a/python/controls/layout/page/app-exit-confirm-dialog.py +++ b/python/controls/layout/page/app-exit-confirm-dialog.py @@ -1,38 +1,36 @@ -import flet -from flet import AlertDialog, ElevatedButton, OutlinedButton, Page, Text +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "MyApp" def window_event(e): if e.data == "close": - page.dialog = confirm_dialog - confirm_dialog.open = True + page.open(confirm_dialog) page.update() - page.window_prevent_close = True - page.on_window_event = window_event + page.window.prevent_close = True + page.window.on_event = window_event def yes_click(e): - page.window_destroy() + page.window.destroy() def no_click(e): - confirm_dialog.open = False + page.close(confirm_dialog) page.update() - confirm_dialog = AlertDialog( + confirm_dialog = ft.AlertDialog( modal=True, - title=Text("Please confirm"), - content=Text("Do you really want to exit this app?"), + title=ft.Text("Please confirm"), + content=ft.Text("Do you really want to exit this app?"), actions=[ - ElevatedButton("Yes", on_click=yes_click), - OutlinedButton("No", on_click=no_click), + ft.ElevatedButton("Yes", on_click=yes_click), + ft.OutlinedButton("No", on_click=no_click), ], - actions_alignment="end", + actions_alignment=ft.MainAxisAlignment.END, ) - page.add(Text('Try exiting this app by clicking window\'s "Close" button!')) + page.add(ft.Text('Try exiting this app by clicking window\'s "Close" button!')) -flet.app(target=main, view=flet.FLET_APP) +ft.app(main) diff --git a/python/controls/layout/page/keyboard-events.py b/python/controls/layout/page/keyboard-events.py index 0198d59d..bec17f5b 100644 --- a/python/controls/layout/page/keyboard-events.py +++ b/python/controls/layout/page/keyboard-events.py @@ -1,20 +1,19 @@ -import flet -from flet import Container, Page, Row, Text, border, colors, KeyboardEvent +import flet as ft -class ButtonControl(Container): +class ButtonControl(ft.Container): def __init__(self, text): super().__init__() - self.content = Text(text) - self.border = border.all(1, colors.BLACK54) + self.content: ft.Text = ft.Text(text) + self.border = ft.border.all(1, ft.Colors.BLACK54) self.border_radius = 3 self.bgcolor = "0x09000000" self.padding = 10 self.visible = False -def main(page: Page): - def on_keyboard(e: KeyboardEvent): +def main(page: ft.Page): + def on_keyboard(e: ft.KeyboardEvent): key.content.value = e.key key.visible = True shift.visible = e.shift @@ -32,12 +31,14 @@ def on_keyboard(e: KeyboardEvent): meta = ButtonControl("Meta") page.spacing = 50 - page.vertical_alignment = "center" - page.horizontal_alignment = "center" + page.vertical_alignment = ft.MainAxisAlignment.CENTER + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER page.add( - Text("Press any key with a combination of CTRL, ALT, SHIFT and META keys..."), - Row([key, shift, ctrl, alt, meta], alignment="center"), + ft.Text( + "Press any key with a combination of CTRL, ALT, SHIFT and META keys..." + ), + ft.Row([key, shift, ctrl, alt, meta], alignment=ft.MainAxisAlignment.CENTER), ) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/layout/page/set-platform.py b/python/controls/layout/page/set-platform.py new file mode 100644 index 00000000..a838aaa6 --- /dev/null +++ b/python/controls/layout/page/set-platform.py @@ -0,0 +1,24 @@ +import flet as ft + + +def main(page): + def set_android(e): + page.platform = ft.PagePlatform.ANDROID + page.update() + print("New platform:", page.platform) + + def set_ios(e): + page.platform = "ios" + page.update() + print("New platform:", page.platform) + + page.add( + ft.Switch(label="Switch A", adaptive=True), + ft.ElevatedButton("Set Android", on_click=set_android), + ft.ElevatedButton("Set iOS", on_click=set_ios), + ) + + print("Default platform:", page.platform) + + +ft.app(main) diff --git a/python/controls/layout/page/splash-test.py b/python/controls/layout/page/splash-test.py index a2a81cdf..c736cbe5 100644 --- a/python/controls/layout/page/splash-test.py +++ b/python/controls/layout/page/splash-test.py @@ -1,11 +1,11 @@ from time import sleep import flet as ft -from flet import ElevatedButton, ProgressBar -def main(page): + +def main(page: ft.Page): def button_click(e): - my_bar = ProgressBar() - + my_bar = ft.ProgressBar() + page.overlay.append(my_bar) btn.disabled = True page.update() @@ -15,7 +15,8 @@ def button_click(e): btn.disabled = False page.update() - btn = ElevatedButton("Do some lengthy task!", on_click=button_click) + btn = ft.ElevatedButton("Do some lengthy task!", on_click=button_click) page.add(btn) -ft.app(target=main) + +ft.app(main) diff --git a/python/controls/layout/page/window-hidden-on-start.py b/python/controls/layout/page/window-hidden-on-start.py index a4bd11e9..0d0a8cdd 100644 --- a/python/controls/layout/page/window-hidden-on-start.py +++ b/python/controls/layout/page/window-hidden-on-start.py @@ -1,17 +1,14 @@ from time import sleep -import flet -from flet import Page, Text +import flet as ft -def main(page: Page): - - page.add( - Text("Hello!") - ) +def main(page: ft.Page): + page.add(ft.Text("Hello!")) sleep(3) - page.window_visible = True - page.update() + page.window.visible = True + page.update() -flet.app(target=main, view=flet.FLET_APP_HIDDEN) + +ft.app(main, view=ft.AppView.FLET_APP_HIDDEN) From 334570ae44713d98c5b6cf48660d45113bbe7971 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 11:38:31 -0800 Subject: [PATCH 38/81] add pagelet example --- .../layout/pagelet/pagelet-example.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 python/controls/layout/pagelet/pagelet-example.py diff --git a/python/controls/layout/pagelet/pagelet-example.py b/python/controls/layout/pagelet/pagelet-example.py new file mode 100644 index 00000000..35bab418 --- /dev/null +++ b/python/controls/layout/pagelet/pagelet-example.py @@ -0,0 +1,46 @@ +import flet as ft + + +def main(page: ft.Page): + def open_pagelet_end_drawer(e): + pagelet.show_drawer(ed) + + ed = ft.NavigationDrawer( + controls=[ + ft.NavigationDrawerDestination( + icon=ft.Icons.ADD_TO_HOME_SCREEN_SHARP, label="Item 1" + ), + ft.NavigationDrawerDestination(icon=ft.Icons.ADD_COMMENT, label="Item 2"), + ], + ) + pagelet = ft.Pagelet( + appbar=ft.AppBar( + title=ft.Text("Pagelet AppBar Title"), bgcolor=ft.Colors.AMBER_ACCENT + ), + content=ft.Container(ft.Text("Pagelet Body"), padding=ft.padding.all(16)), + bgcolor=ft.Colors.AMBER_100, + bottom_app_bar=ft.BottomAppBar( + bgcolor=ft.Colors.BLUE, + shape=ft.NotchShape.CIRCULAR, + content=ft.Row( + controls=[ + ft.IconButton(icon=ft.Icons.MENU, icon_color=ft.Colors.WHITE), + ft.Container(expand=True), + ft.IconButton(icon=ft.Icons.SEARCH, icon_color=ft.Colors.WHITE), + ft.IconButton(icon=ft.Icons.FAVORITE, icon_color=ft.Colors.WHITE), + ] + ), + ), + end_drawer=ed, + floating_action_button=ft.FloatingActionButton( + "Open", on_click=open_pagelet_end_drawer, shape=ft.CircleBorder() + ), + floating_action_button_location=ft.FloatingActionButtonLocation.CENTER_DOCKED, + width=400, + height=400, + ) + + page.add(pagelet) + + +ft.app(main) From 348375111447b2d191295bd84b341992fcbc056c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 11:56:29 -0800 Subject: [PATCH 39/81] add placeholder-example --- .../controls/layout/placeholder/placeholder-example.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 python/controls/layout/placeholder/placeholder-example.py diff --git a/python/controls/layout/placeholder/placeholder-example.py b/python/controls/layout/placeholder/placeholder-example.py new file mode 100644 index 00000000..7cb7cdcb --- /dev/null +++ b/python/controls/layout/placeholder/placeholder-example.py @@ -0,0 +1,10 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.Placeholder(expand=True, color=ft.Colors.random()) # random material color + ) + + +ft.app(main) From 378bc122b6da24bf309ed0a097a222a2faf8c4b4 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 12:10:39 -0800 Subject: [PATCH 40/81] add reorderable-list-view-example.py --- .../reorderable-list-view-example.py | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 python/controls/layout/reorderable-list-view/reorderable-list-view-example.py diff --git a/python/controls/layout/reorderable-list-view/reorderable-list-view-example.py b/python/controls/layout/reorderable-list-view/reorderable-list-view-example.py new file mode 100644 index 00000000..9eba08a8 --- /dev/null +++ b/python/controls/layout/reorderable-list-view/reorderable-list-view-example.py @@ -0,0 +1,53 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "ReorderableListView Demo" + + # the primary color is the color of the reorder handle + page.theme = page.dark_theme = ft.Theme( + color_scheme=ft.ColorScheme(primary=ft.Colors.BLUE) + ) + + def handle_reorder(e: ft.OnReorderEvent): + print(f"Reordered from {e.old_index} to {e.new_index}") + + get_color = lambda i: ( + ft.Colors.ERROR if i % 2 == 0 else ft.Colors.ON_ERROR_CONTAINER + ) + + # horizontal + h = ft.ReorderableListView( + expand=True, + horizontal=True, + on_reorder=handle_reorder, + controls=[ + ft.Container( + content=ft.Text(f"Item {i}", color=ft.Colors.BLACK), + bgcolor=get_color(i), + margin=ft.margin.symmetric(horizontal=5, vertical=10), + width=100, + alignment=ft.alignment.center, + ) + for i in range(10) + ], + ) + + # vertical + v = ft.ReorderableListView( + expand=True, + on_reorder=handle_reorder, + controls=[ + ft.ListTile( + title=ft.Text(f"Item {i}", color=ft.Colors.BLACK), + leading=ft.Icon(ft.Icons.CHECK, color=ft.Colors.RED), + bgcolor=get_color(i), + ) + for i in range(10) + ], + ) + + page.add(h, v) + + +ft.app(main) From 2327945b82c054ae1a3a15c803820cc370b787b6 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 13:02:48 -0800 Subject: [PATCH 41/81] update responsive-row example --- .../responsive-row/responsive-layout.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python/controls/layout/responsive-row/responsive-layout.py b/python/controls/layout/responsive-row/responsive-layout.py index ee26906d..bd22ca7e 100644 --- a/python/controls/layout/responsive-row/responsive-layout.py +++ b/python/controls/layout/responsive-row/responsive-layout.py @@ -6,9 +6,9 @@ def page_resize(e): pw.value = f"{page.width} px" pw.update() - page.on_resize = page_resize + page.on_resized = page_resize - pw = ft.Text(bottom=50, right=50, style="displaySmall") + pw = ft.Text(bottom=50, right=50, style=ft.TextTheme.display_small) page.overlay.append(pw) page.add( ft.ResponsiveRow( @@ -16,26 +16,26 @@ def page_resize(e): ft.Container( ft.Text("Column 1"), padding=5, - bgcolor=ft.colors.YELLOW, - col={"sm": 6, "md": 4, "xl": 2}, + bgcolor=ft.Colors.YELLOW, + col={"xs": 12, "md": 6, "lg": 3}, ), ft.Container( ft.Text("Column 2"), padding=5, - bgcolor=ft.colors.GREEN, - col={"sm": 6, "md": 4, "xl": 2}, + bgcolor=ft.Colors.GREEN, + col={"xs": 12, "md": 6, "lg": 3}, ), ft.Container( ft.Text("Column 3"), padding=5, - bgcolor=ft.colors.BLUE, - col={"sm": 6, "md": 4, "xl": 2}, + bgcolor=ft.Colors.BLUE, + col={"xs": 12, "md": 6, "lg": 3}, ), ft.Container( ft.Text("Column 4"), padding=5, - bgcolor=ft.colors.PINK_300, - col={"sm": 6, "md": 4, "xl": 2}, + bgcolor=ft.Colors.PINK_300, + col={"xs": 12, "md": 6, "lg": 3}, ), ], ), @@ -51,4 +51,4 @@ def page_resize(e): page_resize(None) -ft.app(target=main) +ft.app(main) From 7334f3df5faa84ddaa70a0686a01c5c0b29994c9 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 5 Mar 2025 15:51:44 -0800 Subject: [PATCH 42/81] update row examples --- python/controls/layout/row/row-alignment.py | 27 ++++++++++++------- python/controls/layout/row/row-spacing.py | 6 ++--- .../controls/layout/row/row-vert-alignment.py | 6 ++--- python/controls/layout/row/row-wrap.py | 10 +++---- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/python/controls/layout/row/row-alignment.py b/python/controls/layout/row/row-alignment.py index 70c56fe3..a5fc6d1e 100644 --- a/python/controls/layout/row/row-alignment.py +++ b/python/controls/layout/row/row-alignment.py @@ -2,6 +2,8 @@ def main(page: ft.Page): + page.scroll = ft.ScrollMode.AUTO + def items(count): items = [] for i in range(1, count + 1): @@ -11,7 +13,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER_500, + bgcolor=ft.Colors.AMBER_500, ) ) return items @@ -22,19 +24,24 @@ def row_with_alignment(align: ft.MainAxisAlignment): ft.Text(str(align), size=16), ft.Container( content=ft.Row(items(3), alignment=align), - bgcolor=ft.colors.AMBER_100, + bgcolor=ft.Colors.AMBER_100, ), - ] + ], ) page.add( - row_with_alignment(ft.MainAxisAlignment.START), - row_with_alignment(ft.MainAxisAlignment.CENTER), - row_with_alignment(ft.MainAxisAlignment.END), - row_with_alignment(ft.MainAxisAlignment.SPACE_BETWEEN), - row_with_alignment(ft.MainAxisAlignment.SPACE_AROUND), - row_with_alignment(ft.MainAxisAlignment.SPACE_EVENLY), + ft.Column( + [ + row_with_alignment(ft.MainAxisAlignment.START), + row_with_alignment(ft.MainAxisAlignment.CENTER), + row_with_alignment(ft.MainAxisAlignment.END), + row_with_alignment(ft.MainAxisAlignment.SPACE_BETWEEN), + row_with_alignment(ft.MainAxisAlignment.SPACE_AROUND), + row_with_alignment(ft.MainAxisAlignment.SPACE_EVENLY), + ], + scroll=ft.ScrollMode.AUTO, + ) ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/row/row-spacing.py b/python/controls/layout/row/row-spacing.py index c75436e5..90deec14 100644 --- a/python/controls/layout/row/row-spacing.py +++ b/python/controls/layout/row/row-spacing.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER, + bgcolor=ft.Colors.AMBER, border_radius=ft.border_radius.all(5), ) ) @@ -30,9 +30,9 @@ def gap_slider_change(e): on_change=gap_slider_change, ) - row = ft.Row(spacing=0, controls=items(10)) + row = ft.Row(spacing=0, controls=items(10), scroll=ft.ScrollMode.AUTO) page.add(ft.Column([ft.Text("Spacing between items"), gap_slider]), row) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/row/row-vert-alignment.py b/python/controls/layout/row/row-vert-alignment.py index be82c590..7271c0ab 100644 --- a/python/controls/layout/row/row-vert-alignment.py +++ b/python/controls/layout/row/row-vert-alignment.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER_500, + bgcolor=ft.Colors.AMBER_500, ) ) return items @@ -22,7 +22,7 @@ def row_with_vertical_alignment(align: ft.CrossAxisAlignment): ft.Text(str(align), size=16), ft.Container( content=ft.Row(items(3), vertical_alignment=align), - bgcolor=ft.colors.AMBER_100, + bgcolor=ft.Colors.AMBER_100, height=150, ), ] @@ -35,4 +35,4 @@ def row_with_vertical_alignment(align: ft.CrossAxisAlignment): ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/layout/row/row-wrap.py b/python/controls/layout/row/row-wrap.py index 286eb23a..ee5ac8fd 100644 --- a/python/controls/layout/row/row-wrap.py +++ b/python/controls/layout/row/row-wrap.py @@ -11,7 +11,7 @@ def items(count): alignment=ft.alignment.center, width=50, height=50, - bgcolor=ft.colors.AMBER, + bgcolor=ft.Colors.AMBER, border_radius=ft.border_radius.all(5), ) ) @@ -23,9 +23,9 @@ def slider_change(e): width_slider = ft.Slider( min=0, - max=page.window_width, + max=page.window.width, divisions=20, - value=page.window_width, + value=page.window.width, label="{value}", on_change=slider_change, ) @@ -35,7 +35,7 @@ def slider_change(e): spacing=10, run_spacing=10, controls=items(30), - width=page.window_width, + width=page.window.width, ) page.add( @@ -51,4 +51,4 @@ def slider_change(e): ) -ft.app(target=main) +ft.app(main) From b9aa5435b52555a81d79d552b5b7dcd9a8eb4275 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 6 Mar 2025 13:10:14 -0800 Subject: [PATCH 43/81] add safe area example --- .../layout/safe-area/safe-area-example.py | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 python/controls/layout/safe-area/safe-area-example.py diff --git a/python/controls/layout/safe-area/safe-area-example.py b/python/controls/layout/safe-area/safe-area-example.py new file mode 100644 index 00000000..2d15d95f --- /dev/null +++ b/python/controls/layout/safe-area/safe-area-example.py @@ -0,0 +1,30 @@ +import flet as ft + + +class State: + counter = 0 + + +def main(page: ft.Page): + state = State() + + def add_click(e): + state.counter += 1 + counter.value = str(state.counter) + counter.update() + + page.floating_action_button = ft.FloatingActionButton( + icon=ft.Icons.ADD, on_click=add_click + ) + page.add( + ft.SafeArea( + ft.Container( + counter := ft.Text("0", size=50), + alignment=ft.alignment.center, + ), + expand=True, + ) + ) + + +ft.app(main) From e726632df9281a56153a938c27f97dbbcae2b3c9 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 6 Mar 2025 14:18:58 -0800 Subject: [PATCH 44/81] update stack examples --- .../layout/stack/absolute-positioned.py | 47 ++++++++++--------- .../layout/stack/avatar-with-status.py | 18 ++++--- python/controls/layout/stack/image-title.py | 23 +++++---- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/python/controls/layout/stack/absolute-positioned.py b/python/controls/layout/stack/absolute-positioned.py index 059a9f06..8649d71b 100644 --- a/python/controls/layout/stack/absolute-positioned.py +++ b/python/controls/layout/stack/absolute-positioned.py @@ -1,61 +1,62 @@ -import flet -from flet import Column, Container, Page, Stack, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): - page.horizontal_alignment = "center" - page.vertical_alignment = "center" + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.vertical_alignment = ft.MainAxisAlignment.CENTER page.add( - Container( - Stack( + ft.Container( + ft.Stack( [ - Container(width=20, height=20, bgcolor=colors.RED, border_radius=5), - Container( + ft.Container( + width=20, height=20, bgcolor=ft.Colors.RED, border_radius=5 + ), + ft.Container( width=20, height=20, - bgcolor=colors.YELLOW, + bgcolor=ft.Colors.YELLOW, border_radius=5, right=0, ), - Container( + ft.Container( width=20, height=20, - bgcolor=colors.BLUE, + bgcolor=ft.Colors.BLUE, border_radius=5, right=0, bottom=0, ), - Container( + ft.Container( width=20, height=20, - bgcolor=colors.GREEN, + bgcolor=ft.Colors.GREEN, border_radius=5, left=0, bottom=0, ), - Column( + ft.Column( [ - Container( + ft.Container( width=20, height=20, - bgcolor=colors.PURPLE, + bgcolor=ft.Colors.PURPLE, border_radius=5, ) ], - left=35, - top=35, + left=85, + top=85, ), ] ), border_radius=8, padding=5, - width=100, - height=100, - bgcolor=colors.BLACK, + width=200, + height=200, + bgcolor=ft.Colors.BLACK, ) ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/stack/avatar-with-status.py b/python/controls/layout/stack/avatar-with-status.py index 194a2fbc..0b2c8663 100644 --- a/python/controls/layout/stack/avatar-with-status.py +++ b/python/controls/layout/stack/avatar-with-status.py @@ -1,18 +1,16 @@ -import flet -from flet import CircleAvatar, Container, Stack, alignment, colors +import flet as ft def main(page): - # avatar with online status page.add( - Stack( + ft.Stack( [ - CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" + ft.CircleAvatar( + foreground_image_src="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" ), - Container( - content=CircleAvatar(bgcolor=colors.GREEN, radius=5), - alignment=alignment.bottom_left, + ft.Container( + content=ft.CircleAvatar(bgcolor=ft.Colors.GREEN, radius=5), + alignment=ft.alignment.bottom_left, ), ], width=40, @@ -21,4 +19,4 @@ def main(page): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/stack/image-title.py b/python/controls/layout/stack/image-title.py index dc57fe51..4dfe9f8e 100644 --- a/python/controls/layout/stack/image-title.py +++ b/python/controls/layout/stack/image-title.py @@ -1,27 +1,26 @@ -import flet -from flet import Image, Page, Row, Stack, Text +import flet as ft -def main(page: Page): - st = Stack( +def main(page: ft.Page): + st = ft.Stack( [ - Image( + ft.Image( src=f"https://picsum.photos/300/300", width=300, height=300, - fit="contain", + fit=ft.ImageFit.CONTAIN, ), - Row( + ft.Row( [ - Text( + ft.Text( "Image title", - color="white", + color=ft.Colors.ON_SURFACE, size=40, - weight="bold", + weight=ft.FontWeight.BOLD, opacity=0.5, ) ], - alignment="center", + alignment=ft.MainAxisAlignment.CENTER, ), ], width=300, @@ -31,4 +30,4 @@ def main(page: Page): page.add(st) -flet.app(target=main) +ft.app(main) From 86f55ab8985152ce114c7ba17c7cc97b9d17f4de Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 6 Mar 2025 16:29:03 -0800 Subject: [PATCH 45/81] update tabs, add nested example --- python/controls/layout/tabs/nested-tabs.py | 53 +++++++++++++++++++++ python/controls/layout/tabs/tabs-dynamic.py | 43 ++++++++--------- python/controls/layout/tabs/tabs-simple.py | 35 ++++++++------ 3 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 python/controls/layout/tabs/nested-tabs.py diff --git a/python/controls/layout/tabs/nested-tabs.py b/python/controls/layout/tabs/nested-tabs.py new file mode 100644 index 00000000..c7e0c94c --- /dev/null +++ b/python/controls/layout/tabs/nested-tabs.py @@ -0,0 +1,53 @@ +import flet as ft + + +def main(page: ft.Page): + + dt = ft.Tabs( + is_secondary=True, + tabs=[ + ft.Tab(text="Fast Food", content=ft.Text("Grab something on the go!")), + ft.Tab(text="Fine Dining", content=ft.Text("Take your time!")), + ], + ) + et = ft.Tabs( + is_secondary=True, + tabs=[ + ft.Tab(text="Cinema", content=ft.Text("Find a Film!")), + ft.Tab(text="Music", content=ft.Text("Listen to some Tunes!")), + ], + ) + lt = ft.Tabs( + is_secondary=True, + tabs=[ + ft.Tab(text="Hotel", content=ft.Text("Enjoy your Room!")), + ft.Tab(text="Hostel", content=ft.Text("Grab a Bunk!")), + ], + ) + t = ft.Tabs( + selected_index=1, + animation_duration=300, + tabs=[ + ft.Tab( + text="Dining", + icon=ft.Icons.RESTAURANT, + content=dt, + ), + ft.Tab( + text="Entertainment", + icon=ft.Icons.LOCAL_ACTIVITY, + content=et, + ), + ft.Tab( + text="Lodging", + icon=ft.Icons.HOTEL, + content=lt, + ), + ], + expand=1, + ) + + page.add(t) + + +ft.app(main) diff --git a/python/controls/layout/tabs/tabs-dynamic.py b/python/controls/layout/tabs/tabs-dynamic.py index a9931dad..1fbb5a0b 100644 --- a/python/controls/layout/tabs/tabs-dynamic.py +++ b/python/controls/layout/tabs/tabs-dynamic.py @@ -1,33 +1,30 @@ import logging from time import sleep -import flet -from flet import Container, Icon, Page, Tab, Tabs, Text, alignment, icons +import flet as ft -logging.basicConfig(level=logging.DEBUG) - -def main(page: Page): +def main(page: ft.Page): page.title = "Tabs example" - t = Tabs( + t = ft.Tabs( selected_index=1, animation_duration=300, tabs=[ - Tab( + ft.Tab( text="Tab 1", - content=Container( - content=Text("This is Tab 1"), alignment=alignment.center + content=ft.Container( + content=ft.Text("This is Tab 1"), alignment=ft.alignment.center ), ), - Tab( - tab_content=Icon(icons.MESSAGE), - content=Text("This is Tab 2"), + ft.Tab( + tab_content=ft.Icon(ft.Icons.MESSAGE), + content=ft.Text("This is Tab 2"), ), - Tab( + ft.Tab( text="Tab 3", - icon=icons.IRON, - content=Text("This is Tab 3"), + icon=ft.Icons.IRON, + content=ft.Text("This is Tab 3"), ), ], expand=1, @@ -44,27 +41,27 @@ def main(page: Page): sleep(3) t.selected_index = 1 t.tabs.pop(0) - t.tabs[1].content = Text("Blah blah blah") + t.tabs[1].content = ft.Text("Blah blah blah") page.update() sleep(3) t.tabs.clear() page.update() sleep(3) t.tabs.append( - Tab( + ft.Tab( text="Tab 4", - icon=icons.LOCK, - content=Text("This is Tab 4"), + icon=ft.Icons.LOCK, + content=ft.Text("This is Tab 4"), ) ) t.tabs.append( - Tab( + ft.Tab( text="Tab 5", - icon=icons.SIP_SHARP, - content=Text("This is Tab 5"), + icon=ft.Icons.SIP_SHARP, + content=ft.Text("This is Tab 5"), ) ) page.update() -flet.app(target=main) +ft.app(main) diff --git a/python/controls/layout/tabs/tabs-simple.py b/python/controls/layout/tabs/tabs-simple.py index 51619159..3f67902d 100644 --- a/python/controls/layout/tabs/tabs-simple.py +++ b/python/controls/layout/tabs/tabs-simple.py @@ -1,27 +1,32 @@ -import flet -from flet import Container, Icon, Page, Tab, Tabs, Text, alignment, icons +import flet as ft -def main(page: Page): +def main(page: ft.Page): - t = Tabs( + t = ft.Tabs( selected_index=1, animation_duration=300, tabs=[ - Tab( + ft.Tab( text="Tab 1", - content=Container( - content=Text("This is Tab 1"), alignment=alignment.center + content=ft.Container( + content=ft.Text("This is Tab 1"), alignment=ft.alignment.center ), ), - Tab( - tab_content=Icon(icons.SEARCH), - content=Text("This is Tab 2"), + ft.Tab( + text="Tab 2", + icon=ft.Icons.SETTINGS, + content=ft.Container( + content=ft.Text("This is Tab 2"), alignment=ft.alignment.center + ), ), - Tab( - text="Tab 3", - icon=icons.SETTINGS, - content=Text("This is Tab 3"), + ft.Tab( + tab_content=ft.CircleAvatar( + foreground_image_src="https://avatars.githubusercontent.com/u/7119543?s=88&v=4" + ), + content=ft.Container( + content=ft.Text("This is Tab 3"), alignment=ft.alignment.center + ), ), ], expand=1, @@ -30,4 +35,4 @@ def main(page: Page): page.add(t) -flet.app(target=main) +ft.app(main) From b052f29f43ce86793058ecebc53f6b525da33687 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 7 Mar 2025 11:52:38 -0800 Subject: [PATCH 46/81] update navigation control examples --- .../layout/vertical-divider/divider-vert.py | 39 +++--- .../app-bar/appbar-theme-material.py | 8 +- .../bottom-appbar.py | 3 +- .../navigation/menu-bar/menu-bar-example.py | 114 ++++++++++++++++++ .../navigation-bar/navigation-bar-sample.py | 2 +- .../navigation-drawer/nav-drawer-example.py | 40 ++++++ .../navigation-rail/nav-rail-layout.py | 81 ------------- .../navigation-rail/nav-rail-test.py | 56 ++++----- 8 files changed, 208 insertions(+), 135 deletions(-) rename python/controls/navigation/{app-bar => bottom-app-bar}/bottom-appbar.py (88%) create mode 100644 python/controls/navigation/menu-bar/menu-bar-example.py create mode 100644 python/controls/navigation/navigation-drawer/nav-drawer-example.py delete mode 100644 python/controls/navigation/navigation-rail/nav-rail-layout.py diff --git a/python/controls/layout/vertical-divider/divider-vert.py b/python/controls/layout/vertical-divider/divider-vert.py index 0d197b57..1ca61b44 100644 --- a/python/controls/layout/vertical-divider/divider-vert.py +++ b/python/controls/layout/vertical-divider/divider-vert.py @@ -1,33 +1,32 @@ -import flet -from flet import Container, Page, Row, VerticalDivider, alignment, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - Row( + ft.Row( [ - Container( - bgcolor=colors.ORANGE_300, - alignment=alignment.center, + ft.Container( + bgcolor=ft.Colors.ORANGE_300, + alignment=ft.alignment.center, expand=True, ), - VerticalDivider(), - Container( - bgcolor=colors.BROWN_400, - alignment=alignment.center, + ft.VerticalDivider(), + ft.Container( + bgcolor=ft.Colors.BROWN_400, + alignment=ft.alignment.center, expand=True, ), - VerticalDivider(width=1, color="white"), - Container( - bgcolor=colors.BLUE_300, - alignment=alignment.center, + ft.VerticalDivider(width=1, color="white"), + ft.Container( + bgcolor=ft.Colors.BLUE_300, + alignment=ft.alignment.center, expand=True, ), - VerticalDivider(width=9, thickness=3), - Container( - bgcolor=colors.GREEN_300, - alignment=alignment.center, + ft.VerticalDivider(width=9, thickness=3), + ft.Container( + bgcolor=ft.Colors.GREEN_300, + alignment=ft.alignment.center, expand=True, ), ], @@ -37,4 +36,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/navigation/app-bar/appbar-theme-material.py b/python/controls/navigation/app-bar/appbar-theme-material.py index 72f9ecbe..6b0402f7 100644 --- a/python/controls/navigation/app-bar/appbar-theme-material.py +++ b/python/controls/navigation/app-bar/appbar-theme-material.py @@ -26,13 +26,17 @@ def toggle_theme_mode(e): ) lightMode.icon = ( ft.Icons.WB_SUNNY_OUTLINED - if page.theme_mode == "light" + if page.theme_mode == ft.ThemeMode.LIGHT else ft.Icons.WB_SUNNY ) page.update() lightMode = ft.IconButton( - ft.Icons.WB_SUNNY_OUTLINED if page.theme_mode == "light" else ft.Icons.WB_SUNNY, + ( + ft.Icons.WB_SUNNY_OUTLINED + if page.theme_mode == ft.ThemeMode.LIGHT + else ft.Icons.WB_SUNNY + ), on_click=toggle_theme_mode, ) diff --git a/python/controls/navigation/app-bar/bottom-appbar.py b/python/controls/navigation/bottom-app-bar/bottom-appbar.py similarity index 88% rename from python/controls/navigation/app-bar/bottom-appbar.py rename to python/controls/navigation/bottom-app-bar/bottom-appbar.py index d6d8d2cc..aa94f09f 100644 --- a/python/controls/navigation/app-bar/bottom-appbar.py +++ b/python/controls/navigation/bottom-app-bar/bottom-appbar.py @@ -2,7 +2,8 @@ def main(page: ft.Page): - page.horizontal_alignment = page.vertical_alignment = "center" + page.vertical_alignment = ft.MainAxisAlignment.CENTER + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER page.floating_action_button = ft.FloatingActionButton( icon=ft.Icons.ADD, shape=ft.CircleBorder() diff --git a/python/controls/navigation/menu-bar/menu-bar-example.py b/python/controls/navigation/menu-bar/menu-bar-example.py new file mode 100644 index 00000000..55584681 --- /dev/null +++ b/python/controls/navigation/menu-bar/menu-bar-example.py @@ -0,0 +1,114 @@ +import flet as ft + + +def main(page: ft.Page): + appbar_text_ref = ft.Ref[ft.Text]() + + def handle_menu_item_click(e): + print(f"{e.control.content.value}.on_click") + page.open( + ft.SnackBar(content=ft.Text(f"{e.control.content.value} was clicked!")) + ) + appbar_text_ref.current.value = e.control.content.value + page.update() + + def handle_submenu_open(e): + print(f"{e.control.content.value}.on_open") + + def handle_submenu_close(e): + print(f"{e.control.content.value}.on_close") + + def handle_submenu_hover(e): + print(f"{e.control.content.value}.on_hover") + + page.appbar = ft.AppBar( + title=ft.Text("Menus", ref=appbar_text_ref), + center_title=True, + bgcolor=ft.Colors.BLUE, + ) + + menubar = ft.MenuBar( + expand=True, + style=ft.MenuStyle( + alignment=ft.alignment.top_left, + bgcolor=ft.Colors.RED_300, + mouse_cursor={ + ft.ControlState.HOVERED: ft.MouseCursor.WAIT, + ft.ControlState.DEFAULT: ft.MouseCursor.ZOOM_OUT, + }, + ), + controls=[ + ft.SubmenuButton( + content=ft.Text("File"), + on_open=handle_submenu_open, + on_close=handle_submenu_close, + on_hover=handle_submenu_hover, + controls=[ + ft.MenuItemButton( + content=ft.Text("About"), + leading=ft.Icon(ft.Icons.INFO), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.GREEN_100} + ), + on_click=handle_menu_item_click, + ), + ft.MenuItemButton( + content=ft.Text("Save"), + leading=ft.Icon(ft.Icons.SAVE), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.GREEN_100} + ), + on_click=handle_menu_item_click, + ), + ft.MenuItemButton( + content=ft.Text("Quit"), + leading=ft.Icon(ft.Icons.CLOSE), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.GREEN_100} + ), + on_click=handle_menu_item_click, + ), + ], + ), + ft.SubmenuButton( + content=ft.Text("View"), + on_open=handle_submenu_open, + on_close=handle_submenu_close, + on_hover=handle_submenu_hover, + controls=[ + ft.SubmenuButton( + content=ft.Text("Zoom"), + controls=[ + ft.MenuItemButton( + content=ft.Text("Magnify"), + leading=ft.Icon(ft.Icons.ZOOM_IN), + close_on_click=False, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.PURPLE_200 + } + ), + on_click=handle_menu_item_click, + ), + ft.MenuItemButton( + content=ft.Text("Minify"), + leading=ft.Icon(ft.Icons.ZOOM_OUT), + close_on_click=False, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.PURPLE_200 + } + ), + on_click=handle_menu_item_click, + ), + ], + ) + ], + ), + ], + ) + + page.add(ft.Row([menubar])) + + +ft.app(main) diff --git a/python/controls/navigation/navigation-bar/navigation-bar-sample.py b/python/controls/navigation/navigation-bar/navigation-bar-sample.py index 2e7d09ca..5da07b91 100644 --- a/python/controls/navigation/navigation-bar/navigation-bar-sample.py +++ b/python/controls/navigation/navigation-bar/navigation-bar-sample.py @@ -11,7 +11,7 @@ def main(page: ft.Page): ft.NavigationBarDestination( icon=ft.icons.BOOKMARK_BORDER, selected_icon=ft.icons.BOOKMARK, - label="Explore", + label="Favorites", ), ] ) diff --git a/python/controls/navigation/navigation-drawer/nav-drawer-example.py b/python/controls/navigation/navigation-drawer/nav-drawer-example.py new file mode 100644 index 00000000..a35f855c --- /dev/null +++ b/python/controls/navigation/navigation-drawer/nav-drawer-example.py @@ -0,0 +1,40 @@ +import flet as ft + + +def main(page: ft.Page): + + def handle_dismissal(e): + print(f"Drawer dismissed!") + + def handle_change(e): + print(f"Selected Index changed: {e.control.selected_index}") + page.close(drawer) + + drawer = ft.NavigationDrawer( + on_dismiss=handle_dismissal, + on_change=handle_change, + controls=[ + ft.Container(height=12), + ft.NavigationDrawerDestination( + label="Item 1", + icon=ft.Icons.DOOR_BACK_DOOR_OUTLINED, + selected_icon=ft.Icon(ft.Icons.DOOR_BACK_DOOR), + ), + ft.Divider(thickness=2), + ft.NavigationDrawerDestination( + icon=ft.Icon(ft.Icons.MAIL_OUTLINED), + label="Item 2", + selected_icon=ft.Icons.MAIL, + ), + ft.NavigationDrawerDestination( + icon=ft.Icon(ft.Icons.PHONE_OUTLINED), + label="Item 3", + selected_icon=ft.Icons.PHONE, + ), + ], + ) + + page.add(ft.ElevatedButton("Show drawer", on_click=lambda e: page.open(drawer))) + + +ft.app(main) diff --git a/python/controls/navigation/navigation-rail/nav-rail-layout.py b/python/controls/navigation/navigation-rail/nav-rail-layout.py deleted file mode 100644 index b249ff5e..00000000 --- a/python/controls/navigation/navigation-rail/nav-rail-layout.py +++ /dev/null @@ -1,81 +0,0 @@ -import logging -from time import sleep - -import flet -from flet import ( - Column, - FloatingActionButton, - Icon, - NavigationRail, - NavigationRailDestination, - Page, - Row, - Text, - VerticalDivider, - icons, -) - -logging.basicConfig(level=logging.DEBUG) - - -def main(page: Page): - def fab_click(e): - rail.selected_index = 2 - select_page() - page.update() - - pages = [ - Text("First", visible=False), - Text("Second!", visible=False), - Text("Settings", visible=False), - ] - - def select_page(): - print(f"Selected index: {rail.selected_index}") - for index, p in enumerate(pages): - p.visible = True if index == rail.selected_index else False - page.update() - - def dest_change(e): - select_page() - - rail = NavigationRail( - selected_index=0, - label_type="all", - # extended=True, - min_width=100, - min_extended_width=400, - leading=FloatingActionButton(icon=icons.CREATE, text="Add", on_click=fab_click), - # trailing=Text("Something"), - group_alignment=-0.9, - destinations=[ - NavigationRailDestination( - icon=icons.FAVORITE_BORDER, selected_icon=icons.FAVORITE, label="First" - ), - NavigationRailDestination( - icon_content=Icon(icons.BOOKMARK_BORDER), - selected_icon_content=Icon(icons.BOOKMARK), - label="Second", - ), - NavigationRailDestination( - icon=icons.SETTINGS, label_content=Text("Settings") - ), - ], - on_change=dest_change, - ) - - select_page() - - page.add( - Row( - [ - rail, - VerticalDivider(width=1), - Column(pages, alignment="start", expand=True), - ], - expand=True, - ) - ) - - -flet.app(target=main) diff --git a/python/controls/navigation/navigation-rail/nav-rail-test.py b/python/controls/navigation/navigation-rail/nav-rail-test.py index 95ed4c05..302a46b1 100644 --- a/python/controls/navigation/navigation-rail/nav-rail-test.py +++ b/python/controls/navigation/navigation-rail/nav-rail-test.py @@ -1,56 +1,52 @@ -import flet -from flet import ( - Column, - FloatingActionButton, - Icon, - NavigationRail, - NavigationRailDestination, - Page, - Row, - Text, - VerticalDivider, - icons, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): - rail = NavigationRail( + rail = ft.NavigationRail( selected_index=0, - label_type="all", + label_type=ft.NavigationRailLabelType.ALL, # extended=True, min_width=100, min_extended_width=400, - leading=FloatingActionButton(icon=icons.CREATE, text="Add"), + leading=ft.FloatingActionButton( + icon=ft.Icons.CREATE, text="Add", on_click=lambda e: print("FAB clicked!") + ), group_alignment=-0.9, destinations=[ - NavigationRailDestination( - icon=icons.FAVORITE_BORDER, selected_icon=icons.FAVORITE, label="First" + ft.NavigationRailDestination( + icon=ft.Icons.FAVORITE_BORDER, + selected_icon=ft.Icons.FAVORITE, + label="First", ), - NavigationRailDestination( - icon_content=Icon(icons.BOOKMARK_BORDER), - selected_icon_content=Icon(icons.BOOKMARK), + ft.NavigationRailDestination( + icon=ft.Icon(ft.Icons.BOOKMARK_BORDER), + selected_icon=ft.Icon(ft.Icons.BOOKMARK), label="Second", ), - NavigationRailDestination( - icon=icons.SETTINGS_OUTLINED, - selected_icon_content=Icon(icons.SETTINGS), - label_content=Text("Settings"), + ft.NavigationRailDestination( + icon=ft.Icons.SETTINGS_OUTLINED, + selected_icon=ft.Icon(ft.Icons.SETTINGS), + label_content=ft.Text("Settings"), ), ], on_change=lambda e: print("Selected destination:", e.control.selected_index), ) page.add( - Row( + ft.Row( [ rail, - VerticalDivider(width=1), - Column([Text("Body!")], alignment="start", expand=True), + ft.VerticalDivider(width=1), + ft.Column( + [ft.Text("Body!")], + alignment=ft.MainAxisAlignment.START, + expand=True, + ), ], expand=True, ) ) -flet.app(target=main) +ft.app(main) From cd2fffa7b90e23def82355656c803f1af4397f73 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 7 Mar 2025 13:24:40 -0800 Subject: [PATCH 47/81] add nav-drawer-end example --- .../navigation-drawer/nav-drawer-end.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 python/controls/navigation/navigation-drawer/nav-drawer-end.py diff --git a/python/controls/navigation/navigation-drawer/nav-drawer-end.py b/python/controls/navigation/navigation-drawer/nav-drawer-end.py new file mode 100644 index 00000000..f27d8eae --- /dev/null +++ b/python/controls/navigation/navigation-drawer/nav-drawer-end.py @@ -0,0 +1,32 @@ +import flet as ft + + +def main(page: ft.Page): + + def handle_dismissal(e): + print("End drawer dismissed") + + def handle_change(e): + print(f"Selected Index changed: {e.control.selected_index}") + page.close(end_drawer) + + end_drawer = ft.NavigationDrawer( + position=ft.NavigationDrawerPosition.END, + on_dismiss=handle_dismissal, + on_change=handle_change, + controls=[ + ft.NavigationDrawerDestination( + icon=ft.Icons.ADD_TO_HOME_SCREEN_SHARP, label="Item 1" + ), + ft.NavigationDrawerDestination( + icon=ft.Icon(ft.Icons.ADD_COMMENT), label="Item 2" + ), + ], + ) + + page.add( + ft.ElevatedButton("Show end drawer", on_click=lambda e: page.open(end_drawer)) + ) + + +ft.app(main) From 9e77ea7776ac4e74280bb3ccd964e77a64abcfdb Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Fri, 7 Mar 2025 16:09:13 -0800 Subject: [PATCH 48/81] add cupertino navigation and layout examples --- .../cupertino-list-tile-example.py | 30 +++++++++++++++ .../cupertino-appbar-example.py | 17 +++++++++ .../cupertino-appbar-theme-example.py | 37 +++++++++++++++++++ .../cupertino-navbar-wired.py | 36 ++++++++++++++++++ .../cupertino-navigation-bar-example.py | 24 ++++++++++++ .../navigation-rail/nav-rail-test.py | 1 - 6 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 python/controls/cupertino/cupertino-layout/cupertino-list-tile-example.py create mode 100644 python/controls/cupertino/cupertino-navigation/cupertino-appbar-example.py create mode 100644 python/controls/cupertino/cupertino-navigation/cupertino-appbar-theme-example.py create mode 100644 python/controls/cupertino/cupertino-navigation/cupertino-navbar-wired.py create mode 100644 python/controls/cupertino/cupertino-navigation/cupertino-navigation-bar-example.py diff --git a/python/controls/cupertino/cupertino-layout/cupertino-list-tile-example.py b/python/controls/cupertino/cupertino-layout/cupertino-list-tile-example.py new file mode 100644 index 00000000..f4be82f7 --- /dev/null +++ b/python/controls/cupertino/cupertino-layout/cupertino-list-tile-example.py @@ -0,0 +1,30 @@ +import flet as ft + + +def main(page: ft.Page): + def tile_clicked(e): + print("Tile clicked") + + page.add( + ft.CupertinoListTile( + additional_info=ft.Text("Wed Jan 24"), + bgcolor_activated=ft.Colors.AMBER_ACCENT, + leading=ft.Icon(name=ft.CupertinoIcons.GAME_CONTROLLER), + title=ft.Text("CupertinoListTile: notched = False"), + subtitle=ft.Text("Subtitle"), + trailing=ft.Icon(name=ft.CupertinoIcons.ALARM), + on_click=tile_clicked, + ), + ft.CupertinoListTile( + notched=True, + additional_info=ft.Text("Thu Jan 25"), + leading=ft.Icon(name=ft.CupertinoIcons.GAME_CONTROLLER), + title=ft.Text("CupertinoListTile: notched = True"), + subtitle=ft.Text("Subtitle"), + trailing=ft.Icon(name=ft.CupertinoIcons.ALARM), + on_click=tile_clicked, + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-navigation/cupertino-appbar-example.py b/python/controls/cupertino/cupertino-navigation/cupertino-appbar-example.py new file mode 100644 index 00000000..9324af06 --- /dev/null +++ b/python/controls/cupertino/cupertino-navigation/cupertino-appbar-example.py @@ -0,0 +1,17 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + + page.appbar = ft.CupertinoAppBar( + leading=ft.Icon(ft.Icons.PALETTE), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + trailing=ft.Icon(ft.Icons.WB_SUNNY_OUTLINED), + middle=ft.Text("CupertinoAppBar Example"), + brightness=ft.Brightness.LIGHT, + ) + page.add(ft.Text("Body!")) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-navigation/cupertino-appbar-theme-example.py b/python/controls/cupertino/cupertino-navigation/cupertino-appbar-theme-example.py new file mode 100644 index 00000000..ec6290d2 --- /dev/null +++ b/python/controls/cupertino/cupertino-navigation/cupertino-appbar-theme-example.py @@ -0,0 +1,37 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + + def toggle_theme_mode(e): + page.theme_mode = ( + ft.ThemeMode.DARK + if page.theme_mode == ft.ThemeMode.LIGHT + else ft.ThemeMode.LIGHT + ) + lightMode.icon = ( + ft.Icons.WB_SUNNY_OUTLINED + if page.theme_mode == ft.ThemeMode.LIGHT + else ft.Icons.WB_SUNNY + ) + page.update() + + lightMode = ft.IconButton( + ( + ft.Icons.WB_SUNNY_OUTLINED + if page.theme_mode == ft.ThemeMode.LIGHT + else ft.Icons.WB_SUNNY + ), + on_click=toggle_theme_mode, + ) + page.appbar = ft.CupertinoAppBar( + leading=ft.Icon(ft.Icons.PALETTE), + bgcolor=ft.Colors.SURFACE_CONTAINER_HIGHEST, + trailing=lightMode, + middle=ft.Text("CupertinoAppBar Example"), + ) + page.add(ft.Text("Body!")) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-navigation/cupertino-navbar-wired.py b/python/controls/cupertino/cupertino-navigation/cupertino-navbar-wired.py new file mode 100644 index 00000000..b7a3d42a --- /dev/null +++ b/python/controls/cupertino/cupertino-navigation/cupertino-navbar-wired.py @@ -0,0 +1,36 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "CupertinoNavigationBar Example" + + def on_nav_change(e): + # print(e.control.label) + if e.control.selected_index == 0: + body.content.value = "Explore!" + elif e.control.selected_index == 1: + body.content.value = "Find Your Way!" + else: + body.content.value = "Your Favorites!" + page.update() + + body = ft.SafeArea(ft.Text("Explore!")) + page.navigation_bar = ft.CupertinoNavigationBar( + bgcolor=ft.Colors.AMBER_100, + inactive_color=ft.Colors.GREY, + active_color=ft.Colors.BLACK, + on_change=on_nav_change, + destinations=[ + ft.NavigationBarDestination(icon=ft.Icons.EXPLORE, label="Explore"), + ft.NavigationBarDestination(icon=ft.Icons.COMMUTE, label="Commute"), + ft.NavigationBarDestination( + icon=ft.Icons.BOOKMARK_BORDER, + selected_icon=ft.Icons.BOOKMARK, + label="Favorites", + ), + ], + ) + page.add(body) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-navigation/cupertino-navigation-bar-example.py b/python/controls/cupertino/cupertino-navigation/cupertino-navigation-bar-example.py new file mode 100644 index 00000000..f4c700e0 --- /dev/null +++ b/python/controls/cupertino/cupertino-navigation/cupertino-navigation-bar-example.py @@ -0,0 +1,24 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "CupertinoNavigationBar Example" + page.navigation_bar = ft.CupertinoNavigationBar( + bgcolor=ft.Colors.AMBER_100, + inactive_color=ft.Colors.GREY, + active_color=ft.Colors.BLACK, + on_change=lambda e: print("Selected tab:", e.control.selected_index), + destinations=[ + ft.NavigationBarDestination(icon=ft.Icons.EXPLORE, label="Explore"), + ft.NavigationBarDestination(icon=ft.Icons.COMMUTE, label="Commute"), + ft.NavigationBarDestination( + icon=ft.Icons.BOOKMARK_BORDER, + selected_icon=ft.Icons.BOOKMARK, + label="Favorites", + ), + ], + ) + page.add(ft.SafeArea(ft.Text("Body!"))) + + +ft.app(main) diff --git a/python/controls/navigation/navigation-rail/nav-rail-test.py b/python/controls/navigation/navigation-rail/nav-rail-test.py index 302a46b1..e32b0873 100644 --- a/python/controls/navigation/navigation-rail/nav-rail-test.py +++ b/python/controls/navigation/navigation-rail/nav-rail-test.py @@ -6,7 +6,6 @@ def main(page: ft.Page): rail = ft.NavigationRail( selected_index=0, label_type=ft.NavigationRailLabelType.ALL, - # extended=True, min_width=100, min_extended_width=400, leading=ft.FloatingActionButton( From f307257d270492770043483a147fba5969e33e0e Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 8 Mar 2025 22:32:10 -0800 Subject: [PATCH 49/81] update cupertino button examples --- ...ino-button.py => cupertino-button-example.py} | 0 .../cupertino-filled-button-example.py | 14 ++++++++++++++ ....py => cupertino-segmented-button-example.py} | 5 +++-- .../cupertino-segmented-button-padding.py | 2 -- .../cupertino-activity-indicator-example.py | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 4 deletions(-) rename python/controls/cupertino/cupertino-buttons/{cupertino-button.py => cupertino-button-example.py} (100%) create mode 100644 python/controls/cupertino/cupertino-buttons/cupertino-filled-button-example.py rename python/controls/cupertino/cupertino-buttons/{cupertino-segmented-button.py => cupertino-segmented-button-example.py} (77%) create mode 100644 python/controls/cupertino/cupertino-information-displays/cupertino-activity-indicator-example.py diff --git a/python/controls/cupertino/cupertino-buttons/cupertino-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-button-example.py similarity index 100% rename from python/controls/cupertino/cupertino-buttons/cupertino-button.py rename to python/controls/cupertino/cupertino-buttons/cupertino-button-example.py diff --git a/python/controls/cupertino/cupertino-buttons/cupertino-filled-button-example.py b/python/controls/cupertino/cupertino-buttons/cupertino-filled-button-example.py new file mode 100644 index 00000000..26448b7e --- /dev/null +++ b/python/controls/cupertino/cupertino-buttons/cupertino-filled-button-example.py @@ -0,0 +1,14 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.CupertinoFilledButton( + content=ft.Text("CupertinoFilled"), + opacity_on_click=0.3, + on_click=lambda e: print("CupertinoFilledButton clicked!"), + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-example.py similarity index 77% rename from python/controls/cupertino/cupertino-buttons/cupertino-segmented-button.py rename to python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-example.py index 6fbad250..949ddc16 100644 --- a/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button.py +++ b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-example.py @@ -12,14 +12,15 @@ def main(page): controls=[ ft.Text("One"), ft.Container( - padding=ft.padding.symmetric(0, 30), + padding=ft.padding.symmetric(10, 30), content=ft.Text("Two"), ), ft.Container( - padding=ft.padding.symmetric(0, 10), + padding=ft.padding.symmetric(5, 10), content=ft.Text("Three"), ), ], + padding=ft.padding.symmetric(20, 50), ), ) diff --git a/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py index 0655f5c7..6b8dfb22 100644 --- a/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py +++ b/python/controls/cupertino/cupertino-buttons/cupertino-segmented-button-padding.py @@ -26,12 +26,10 @@ def handle_horizontal_change(e): ft.Container( padding=ft.padding.symmetric(30, 0), content=ft.Text("None"), - # alignment=ft.alignment.top_left, ), ft.Container( padding=ft.padding.symmetric(0, 30), content=ft.Text("Some"), - # alignment=ft.alignment.bottom_right, ), ], ) diff --git a/python/controls/cupertino/cupertino-information-displays/cupertino-activity-indicator-example.py b/python/controls/cupertino/cupertino-information-displays/cupertino-activity-indicator-example.py new file mode 100644 index 00000000..6abc00d5 --- /dev/null +++ b/python/controls/cupertino/cupertino-information-displays/cupertino-activity-indicator-example.py @@ -0,0 +1,16 @@ +import flet as ft + + +def main(page): + page.theme_mode = ft.ThemeMode.LIGHT + + page.add( + ft.CupertinoActivityIndicator( + radius=50, + color=ft.Colors.RED, + animating=True, + ) + ) + + +ft.app(main) From 17f072336f153dbf0aa4c6522ea32ce92b121da1 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 8 Mar 2025 22:40:45 -0800 Subject: [PATCH 50/81] update cupertino sliding segment button example --- .../cupertino-buttons/cupertino-sliding-segmented-button.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py b/python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py index c9143186..707689fc 100644 --- a/python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py +++ b/python/controls/cupertino/cupertino-buttons/cupertino-sliding-segmented-button.py @@ -7,15 +7,13 @@ def main(page): def handle_change(e): print(f"selected_index: {e.data}") - page.add(ft.Text(f"segment {int(e.data) + 1} chosen")) - page.update() + page.open(ft.SnackBar(ft.Text(f"segment {int(e.data) + 1} chosen"))) page.add( ft.CupertinoSlidingSegmentedButton( selected_index=1, thumb_color=ft.Colors.BLUE_400, on_change=handle_change, - padding=ft.padding.symmetric(0, 10), controls=[ ft.Text("One"), ft.Text("Two"), From f946d161208bc4e44f5303bbc1c096a34b5b864c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 10 Mar 2025 15:32:13 -0700 Subject: [PATCH 51/81] add cupertino input and selections examples --- .../cupertino-checkbox-example.py | 16 +++++++ .../cupertino-checkbox-properties.py | 46 +++++++++++++++++++ .../cupertino-radio-example.py | 38 +++++++++++++++ .../cupertino-slider-example.py | 36 +++++++++++++++ .../cupertino-switch-example.py | 29 ++++++++++++ .../cupertino-textfield-example.py | 23 ++++++++++ 6 files changed, 188 insertions(+) create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-example.py create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-properties.py create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-radio-example.py create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-slider-example.py create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-switch-example.py create mode 100644 python/controls/cupertino/cupertino-input-and-selections/cupertino-textfield-example.py diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-example.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-example.py new file mode 100644 index 00000000..a8122d1c --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-example.py @@ -0,0 +1,16 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.CupertinoCheckbox(label="Cupertino Checkbox", value=True), + ft.Checkbox(label="Material Checkbox", value=True), + ft.Container(height=20), + ft.Text( + "Adaptive Checkbox shows as CupertinoCheckbox on macOS and iOS and as Checkbox on other platforms:" + ), + ft.Checkbox(adaptive=True, label="Adaptive Checkbox", value=True), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-properties.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-properties.py new file mode 100644 index 00000000..cf082e1d --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-checkbox-properties.py @@ -0,0 +1,46 @@ +import flet as ft + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + c = ft.Column( + [ + ft.CupertinoCheckbox( + label="Cupertino Checkbox tristate", + value=True, + tristate=True, + fill_color={ + ft.ControlState.HOVERED: ft.Colors.PINK_200, + ft.ControlState.PRESSED: ft.Colors.LIME_ACCENT_200, + ft.ControlState.SELECTED: ft.Colors.DEEP_ORANGE_200, + ft.ControlState.DEFAULT: ft.Colors.TEAL_200, + }, + check_color=ft.Colors.GREY_900, + ), + ft.CupertinoCheckbox( + label="Cupertino Checkbox circle border", + value=True, + shape=ft.CircleBorder(), + scale=ft.Scale(2, alignment=ft.Alignment(-1, 0)), + ), + ft.CupertinoCheckbox( + label="Cupertino Checkbox border states", + value=True, + border_side={ + ft.ControlState.HOVERED: ft.BorderSide(width=5, stroke_align=5), + ft.ControlState.DEFAULT: ft.BorderSide(width=3, stroke_align=5), + ft.ControlState.FOCUSED: ft.BorderSide(width=3, stroke_align=5), + }, + # scale=ft.Scale(2, alignment=ft.Alignment(-0.9, 0)), + ), + ft.CupertinoCheckbox( + label="Cupertino Checkbox label position", + value=True, + label_position=ft.LabelPosition.LEFT, + ), + ] + ) + page.add(c) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-radio-example.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-radio-example.py new file mode 100644 index 00000000..2599dcd5 --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-radio-example.py @@ -0,0 +1,38 @@ +import flet as ft + + +def main(page): + def button_clicked(e): + t.value = f"Your favorite color is: {cg.value}" + page.update() + + t = ft.Text() + b = ft.ElevatedButton(text="Submit", on_click=button_clicked) + cg = ft.RadioGroup( + content=ft.Column( + [ + ft.CupertinoRadio( + value="red", + label="Red - Cupertino Radio", + active_color=ft.Colors.RED, + inactive_color=ft.Colors.RED, + ), + ft.Radio( + value="green", + label="Green - Material Radio", + fill_color=ft.Colors.GREEN, + ), + ft.Radio( + value="blue", + label="Blue - Adaptive Radio", + adaptive=True, + active_color=ft.Colors.BLUE, + ), + ] + ) + ) + + page.add(ft.Text("Select your favorite color:"), cg, b, t) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-slider-example.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-slider-example.py new file mode 100644 index 00000000..51317229 --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-slider-example.py @@ -0,0 +1,36 @@ +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.vertical_alignment = ft.MainAxisAlignment.CENTER + page.theme_mode = ft.ThemeMode.LIGHT + + def handle_change_start(e): + slider_status.value = "Sliding" + page.update() + + def handle_change(e): + slider_value.value = str(e.control.value) + page.update() + + def handle_change_end(e): + slider_status.value = "Finished sliding" + page.update() + + page.add( + slider_value := ft.Text("0.0"), + ft.CupertinoSlider( + divisions=5, + max=100, + active_color=ft.Colors.PURPLE, + thumb_color=ft.Colors.PURPLE, + on_change_start=handle_change_start, + on_change_end=handle_change_end, + on_change=handle_change, + ), + slider_status := ft.Text(), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-switch-example.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-switch-example.py new file mode 100644 index 00000000..68495ea3 --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-switch-example.py @@ -0,0 +1,29 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.CupertinoSwitch( + label="Cupertino Switch", + value=True, + ), + ft.Switch( + label="Material Switch", + value=True, + thumb_color={ft.ControlState.SELECTED: ft.Colors.BLUE}, + track_color=ft.Colors.YELLOW, + focus_color=ft.Colors.PURPLE, + ), + ft.Container(height=20), + ft.Text( + "Adaptive Switch shows as CupertinoSwitch on macOS and iOS and as Switch on other platforms:" + ), + ft.Switch( + adaptive=True, + label="Adaptive Switch", + value=True, + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-input-and-selections/cupertino-textfield-example.py b/python/controls/cupertino/cupertino-input-and-selections/cupertino-textfield-example.py new file mode 100644 index 00000000..f82f92f5 --- /dev/null +++ b/python/controls/cupertino/cupertino-input-and-selections/cupertino-textfield-example.py @@ -0,0 +1,23 @@ +import flet as ft + + +def main(page: ft.Page): + + page.add( + ft.TextField( + label="Material text field", + label_style=ft.TextStyle(color=ft.Colors.GREY_400), + ), + ft.CupertinoTextField( + placeholder_text="Cupertino text field", + placeholder_style=ft.TextStyle(color=ft.Colors.GREY_400), + ), + ft.TextField( + adaptive=True, + label="Adaptive text field", + label_style=ft.TextStyle(color=ft.Colors.GREY_400), + ), + ) + + +ft.app(main) From fce92c2dd1cd776a9914bdcedd43478f2b8f2810 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 11 Mar 2025 17:42:35 -0700 Subject: [PATCH 52/81] add cupertino dialogs alerts panels examples --- .../cupertino-action-sheet-example.py | 52 ++++++++++++++ .../cupertino-alert-dialog-example.py | 72 +++++++++++++++++++ .../cupertino-context-menu-example.py | 35 +++++++++ .../cupertino-date-picker-example.py | 32 +++++++++ .../cupertino-picker-example.py | 0 .../cupertino-time-picker-example.py | 50 +++++++++++++ 6 files changed, 241 insertions(+) create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-action-sheet-example.py create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-example.py create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-context-menu-example.py create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-date-picker-example.py create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-picker-example.py create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-time-picker-example.py diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-action-sheet-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-action-sheet-example.py new file mode 100644 index 00000000..e188714a --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-action-sheet-example.py @@ -0,0 +1,52 @@ +import flet as ft + + +def main(page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + def handle_click(e): + page.add(ft.Text(f"Action clicked: {e.control.content.value}")) + page.close(bottom_sheet) + + action_sheet = ft.CupertinoActionSheet( + title=ft.Row( + [ft.Text("Title"), ft.Icon(ft.Icons.BEDTIME)], + alignment=ft.MainAxisAlignment.CENTER, + ), + message=ft.Row( + [ft.Text("Description"), ft.Icon(ft.Icons.AUTO_AWESOME)], + alignment=ft.MainAxisAlignment.CENTER, + ), + cancel=ft.CupertinoActionSheetAction( + content=ft.Text("Cancel"), + on_click=handle_click, + ), + actions=[ + ft.CupertinoActionSheetAction( + content=ft.Text("Default Action"), + is_default_action=True, + on_click=handle_click, + ), + ft.CupertinoActionSheetAction( + content=ft.Text("Normal Action"), + on_click=handle_click, + ), + ft.CupertinoActionSheetAction( + content=ft.Text("Destructive Action"), + is_destructive_action=True, + on_click=handle_click, + ), + ], + ) + + bottom_sheet = ft.CupertinoBottomSheet(action_sheet) + + page.add( + ft.CupertinoFilledButton( + "Open CupertinoBottomSheet", + on_click=lambda e: page.open(bottom_sheet), + ) + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-example.py new file mode 100644 index 00000000..de0fd5c0 --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-example.py @@ -0,0 +1,72 @@ +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.scroll = True + + def handle_action_click(e): + page.add(ft.Text(f"Action clicked: {e.control.text}")) + # e.control is the clicked action button, e.control.parent is the corresponding parent dialog of the button + page.close(e.control.parent) + + cupertino_actions = [ + ft.CupertinoDialogAction( + "Yes", + is_destructive_action=True, + on_click=handle_action_click, + ), + ft.CupertinoDialogAction( + text="No", + is_default_action=False, + on_click=handle_action_click, + ), + ] + + material_actions = [ + ft.TextButton(text="Yes", on_click=handle_action_click), + ft.TextButton(text="No", on_click=handle_action_click), + ] + + page.add( + ft.FilledButton( + text="Open Material Dialog", + on_click=lambda e: page.open( + ft.AlertDialog( + title=ft.Text("Material Alert Dialog"), + content=ft.Text("Do you want to delete this file?"), + actions=material_actions, + ) + ), + ), + ft.CupertinoFilledButton( + text="Open Cupertino Dialog", + on_click=lambda e: page.open( + ft.CupertinoAlertDialog( + title=ft.Text("Cupertino Alert Dialog"), + content=ft.Text("Do you want to delete this file?"), + actions=cupertino_actions, + ) + ), + ), + ft.FilledButton( + text="Open Adaptive Dialog", + adaptive=True, + bgcolor=ft.Colors.BLUE_ACCENT, + on_click=lambda e: page.open( + ft.AlertDialog( + adaptive=True, + title=ft.Text("Adaptive Alert Dialog"), + content=ft.Text("Do you want to delete this file?"), + actions=( + cupertino_actions + if page.platform in [ft.PagePlatform.IOS, ft.PagePlatform.MACOS] + else material_actions + ), + ) + ), + ), + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-context-menu-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-context-menu-example.py new file mode 100644 index 00000000..2a9bcb6d --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-context-menu-example.py @@ -0,0 +1,35 @@ +import flet as ft + + +def main(page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.vertical_alignment = ft.MainAxisAlignment.CENTER + + page.add( + ft.CupertinoContextMenu( + enable_haptic_feedback=True, + content=ft.Image("https://picsum.photos/200/200"), + actions=[ + ft.CupertinoContextMenuAction( + text="Action 1", + is_default_action=True, + trailing_icon=ft.Icons.CHECK, + on_click=lambda e: print("Action 1"), + ), + ft.CupertinoContextMenuAction( + text="Action 2", + trailing_icon=ft.Icons.MORE, + on_click=lambda e: print("Action 2"), + ), + ft.CupertinoContextMenuAction( + text="Action 3", + is_destructive_action=True, + trailing_icon=ft.Icons.CANCEL, + on_click=lambda e: print("Action 3"), + ), + ], + ) + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-date-picker-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-date-picker-example.py new file mode 100644 index 00000000..03e780e9 --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-date-picker-example.py @@ -0,0 +1,32 @@ +import flet as ft + + +def main(page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + d = ft.Text(f"chosen Time: ") + + def handle_date_change(e: ft.ControlEvent): + d.value = f"Chosen Date: {e.control.value.strftime('%Y-%m-%d %H:%M %p')}" + page.update() + + cupertino_date_picker = ft.CupertinoDatePicker( + date_picker_mode=ft.CupertinoDatePickerMode.DATE_AND_TIME, + on_change=handle_date_change, + ) + page.add( + ft.CupertinoFilledButton( + "Open CupertinoDatePicker", + on_click=lambda e: page.open( + ft.CupertinoBottomSheet( + cupertino_date_picker, + height=216, + padding=ft.padding.only(top=6), + ) + ), + ), + d, + ) + + +ft.app(main) diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-picker-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-picker-example.py new file mode 100644 index 00000000..e69de29b diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-time-picker-example.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-time-picker-example.py new file mode 100644 index 00000000..ef0f5e56 --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-time-picker-example.py @@ -0,0 +1,50 @@ +import time +import flet as ft + + +def main(page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + timer_picker_value_ref = ft.Ref[ft.Text]() + + def handle_timer_picker_change(e): + # e.data is the selected time in seconds + timer_picker_value_ref.current.value = time.strftime( + "%H:%M:%S", time.gmtime(int(e.data)) + ) + page.update() + + cupertino_timer_picker = ft.CupertinoTimerPicker( + value=3600, + second_interval=10, + minute_interval=1, + mode=ft.CupertinoTimerPickerMode.HOUR_MINUTE_SECONDS, + on_change=handle_timer_picker_change, + ) + + page.add( + ft.Row( + tight=True, + controls=[ + ft.Text("TimerPicker Value:", size=23), + ft.CupertinoButton( + content=ft.Text( + ref=timer_picker_value_ref, + value="00:01:10", + size=23, + color=ft.CupertinoColors.DESTRUCTIVE_RED, + ), + on_click=lambda e: page.open( + ft.CupertinoBottomSheet( + cupertino_timer_picker, + height=216, + padding=ft.padding.only(top=6), + ) + ), + ), + ], + ), + ) + + +ft.app(main) From 7987207d470d7dbbc59cc92a74200e67accbc2de Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 11 Mar 2025 17:59:43 -0700 Subject: [PATCH 53/81] add simple cupertino-alert-dialog-example --- .../cupertino-alert-dialog-simple.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-simple.py diff --git a/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-simple.py b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-simple.py new file mode 100644 index 00000000..b992d846 --- /dev/null +++ b/python/controls/cupertino/cupertino-dialogs-alerts-panels/cupertino-alert-dialog-simple.py @@ -0,0 +1,38 @@ +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + def dialog_dismissed(e): + page.add(ft.Text("Dialog dismissed")) + + def handle_action_click(e): + page.add(ft.Text(f"Action clicked: {e.control.text}")) + page.close(cupertino_alert_dialog) + + cupertino_alert_dialog = ft.CupertinoAlertDialog( + title=ft.Text("Cupertino Alert Dialog"), + content=ft.Text("Do you want to delete this file?"), + on_dismiss=dialog_dismissed, + actions=[ + ft.CupertinoDialogAction( + text="Yes", + is_destructive_action=True, + on_click=handle_action_click, + ), + ft.CupertinoDialogAction( + text="No", is_default_action=True, on_click=handle_action_click + ), + ], + ) + + page.add( + ft.CupertinoFilledButton( + text="Open CupertinoAlertDialog", + on_click=lambda e: page.open(cupertino_alert_dialog), + ) + ) + + +ft.app(main) From 45bb1be4594db5dc7806ba8bde5b242de01a8480 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 11 Mar 2025 23:04:10 -0700 Subject: [PATCH 54/81] elevated, filled, icon, filled-tonal button examples --- .../elevated-buttons-with-custom-content.py | 6 +-- .../elevated-buttons-with-icons.py | 4 +- .../buttons/elevated-button/styled-button.py | 49 +++++++++--------- .../filled-button/filled-button-example.py | 13 +++++ .../filled-tonal-button-example.py | 13 +++++ .../buttons/floating-action-button/fab.py | 38 -------------- .../floating-action-button.py | 50 +++++++++++++++++++ .../icon-button-with-click-event.py | 13 +++-- .../buttons/icon-button/icon-buttons.py | 35 +++++++------ .../buttons/icon-button/toggle-icon-button.py | 25 ++++++---- 10 files changed, 148 insertions(+), 98 deletions(-) create mode 100644 python/controls/buttons/filled-button/filled-button-example.py create mode 100644 python/controls/buttons/filled-tonal-button/filled-tonal-button-example.py delete mode 100644 python/controls/buttons/floating-action-button/fab.py create mode 100644 python/controls/buttons/floating-action-button/floating-action-button.py diff --git a/python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py b/python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py index 64200d60..d6ad12a1 100644 --- a/python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py +++ b/python/controls/buttons/elevated-button/elevated-buttons-with-custom-content.py @@ -8,9 +8,9 @@ def main(page: ft.Page): width=150, content=ft.Row( [ - ft.Icon(name=ft.Icons.FAVORITE, color="pink"), - ft.Icon(name=ft.Icons.AUDIOTRACK, color="green"), - ft.Icon(name=ft.Icons.BEACH_ACCESS, color="blue"), + ft.Icon(name=ft.Icons.FAVORITE, color=ft.Colors.PINK), + ft.Icon(name=ft.Icons.AUDIOTRACK, color=ft.Colors.GREEN), + ft.Icon(name=ft.Icons.BEACH_ACCESS, color=ft.Colors.BLUE), ], alignment=ft.MainAxisAlignment.SPACE_AROUND, ), diff --git a/python/controls/buttons/elevated-button/elevated-buttons-with-icons.py b/python/controls/buttons/elevated-button/elevated-buttons-with-icons.py index c81f6437..9bec1739 100644 --- a/python/controls/buttons/elevated-button/elevated-buttons-with-icons.py +++ b/python/controls/buttons/elevated-button/elevated-buttons-with-icons.py @@ -5,10 +5,10 @@ def main(page: ft.Page): page.title = "Elevated buttons with icons" page.add( - ft.ElevatedButton("Button with icon", icon="chair_outlined"), + ft.ElevatedButton("Button with icon", icon=ft.Icons.WAVES_ROUNDED), ft.ElevatedButton( "Button with colorful icon", - icon="park_rounded", + icon=ft.Icons.PARK_ROUNDED, icon_color=ft.Colors.GREEN_400, ), ) diff --git a/python/controls/buttons/elevated-button/styled-button.py b/python/controls/buttons/elevated-button/styled-button.py index 516aa962..ad0df338 100644 --- a/python/controls/buttons/elevated-button/styled-button.py +++ b/python/controls/buttons/elevated-button/styled-button.py @@ -1,41 +1,42 @@ -import flet -from flet import ( - BorderSide, - ButtonStyle, - ElevatedButton, - Page, - RoundedRectangleBorder, - colors, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.padding = 50 + page.theme_mode = ft.ThemeMode.LIGHT page.add( - ElevatedButton( + ft.ElevatedButton( "Styled button 1", - style=ButtonStyle( + style=ft.ButtonStyle( color={ - "hovered": colors.WHITE, - "focused": colors.BLUE, - "": colors.BLACK, + ft.ControlState.HOVERED: ft.colors.WHITE, + ft.ControlState.FOCUSED: ft.colors.BLUE, + ft.ControlState.DEFAULT: ft.colors.BLACK, + }, + bgcolor={ + ft.ControlState.FOCUSED: ft.colors.PINK_200, + ft.ControlState.DEFAULT: ft.colors.YELLOW, + }, + padding={ft.ControlState.HOVERED: 20}, + overlay_color=ft.colors.TRANSPARENT, + elevation={ + ft.ControlState.DEFAULT: 0, + ft.ControlState.HOVERED: 5, + ft.ControlState.PRESSED: 10, }, - bgcolor={"focused": colors.PINK_200, "": colors.YELLOW}, - padding={"hovered": 20}, - overlay_color=colors.TRANSPARENT, - elevation={"pressed": 0, "": 1}, animation_duration=500, side={ - "": BorderSide(1, colors.BLUE), - "hovered": BorderSide(2, colors.BLUE), + ft.ControlState.DEFAULT: ft.BorderSide(1, color=ft.colors.BLUE_100), + ft.ControlState.HOVERED: ft.BorderSide(3, color=ft.colors.BLUE_400), + ft.ControlState.PRESSED: ft.BorderSide(6, color=ft.Colors.BLUE_600), }, shape={ - "hovered": RoundedRectangleBorder(radius=20), - "": RoundedRectangleBorder(radius=2), + ft.ControlState.HOVERED: ft.RoundedRectangleBorder(radius=20), + ft.ControlState.DEFAULT: ft.RoundedRectangleBorder(radius=2), }, ), ) ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/filled-button/filled-button-example.py b/python/controls/buttons/filled-button/filled-button-example.py new file mode 100644 index 00000000..a6bfdac0 --- /dev/null +++ b/python/controls/buttons/filled-button/filled-button-example.py @@ -0,0 +1,13 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "Basic filled buttons" + page.add( + ft.FilledButton(text="Filled button"), + ft.FilledButton("Disabled button", disabled=True), + ft.FilledButton("Button with icon", icon=ft.Icons.ADD_OUTLINED), + ) + + +ft.app(main) diff --git a/python/controls/buttons/filled-tonal-button/filled-tonal-button-example.py b/python/controls/buttons/filled-tonal-button/filled-tonal-button-example.py new file mode 100644 index 00000000..e7a549e2 --- /dev/null +++ b/python/controls/buttons/filled-tonal-button/filled-tonal-button-example.py @@ -0,0 +1,13 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "Basic filled tonal buttons" + page.add( + ft.FilledTonalButton(text="Filled tonal button"), + ft.FilledTonalButton("Disabled button", disabled=True), + ft.FilledTonalButton("Button with icon", icon=ft.Icons.ADD_OUTLINED), + ) + + +ft.app(main) diff --git a/python/controls/buttons/floating-action-button/fab.py b/python/controls/buttons/floating-action-button/fab.py deleted file mode 100644 index 9d60727f..00000000 --- a/python/controls/buttons/floating-action-button/fab.py +++ /dev/null @@ -1,38 +0,0 @@ -import flet as ft - - -def main(page: ft.Page): - page.title = "Floating Action Button" - page.theme_mode = ft.ThemeMode.LIGHT - page.horizontal_alignment = ft.CrossAxisAlignment.CENTER - page.auto_scroll = True - page.scroll = ft.ScrollMode.HIDDEN - page.appbar = ft.AppBar( - title=ft.Text( - "Floating Action Button", weight=ft.FontWeight.BOLD, color=ft.colors.BLACK87 - ), - bgcolor=ft.colors.BLUE, - center_title=True, - actions=[ - ft.IconButton(ft.icons.MENU, tooltip="Menu", icon_color=ft.colors.BLACK87) - ], - color=ft.colors.WHITE, - ) - - # keeps track of the number of tiles already added - page.count = 0 - - def fab_pressed(e): - page.add(ft.ListTile(title=ft.Text(f"Tile {page.count}"))) - page.show_snack_bar( - ft.SnackBar(ft.Text("Tile was added successfully!"), open=True) - ) - page.count += 1 - - page.floating_action_button = ft.FloatingActionButton( - icon=ft.icons.ADD, on_click=fab_pressed, bgcolor=ft.colors.LIME_300 - ) - page.add(ft.Text("Press the FAB to add a tile!")) - - -ft.app(target=main) diff --git a/python/controls/buttons/floating-action-button/floating-action-button.py b/python/controls/buttons/floating-action-button/floating-action-button.py new file mode 100644 index 00000000..33d86c88 --- /dev/null +++ b/python/controls/buttons/floating-action-button/floating-action-button.py @@ -0,0 +1,50 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "Floating Action Button" + page.theme_mode = ft.ThemeMode.LIGHT + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.padding = 0 + page.scroll = ft.ScrollMode.HIDDEN + + # keeps track of the number of tiles already added + count = 1 + + def fab_pressed(e): + nonlocal count # to modify the count variable found in the outer scope + page.add( + ft.ListTile( + title=ft.Text(f"Tile {count}"), + bgcolor=ft.Colors.TEAL_300, + leading=ft.Icon( + ft.Icons.CIRCLE_OUTLINED, color=ft.Colors.DEEP_ORANGE_300 + ), + on_click=lambda x: print(x.control.title.value + " was clicked!"), + ) + ) + page.open(ft.SnackBar(ft.Text("Tile was added successfully!"))) + count += 1 + + page.floating_action_button = ft.FloatingActionButton( + icon=ft.Icons.ADD, on_click=fab_pressed, bgcolor=ft.Colors.LIME_300 + ) + page.add( + ft.Container( + ft.Row( + [ + ft.Text( + "Floating Action Button Example", + style=ft.TextStyle(size=20, weight=ft.FontWeight.W_500), + ) + ], + alignment=ft.MainAxisAlignment.CENTER, + ), + bgcolor=ft.Colors.BLUE, + padding=ft.padding.all(20), + ), + ft.Text("Press the FAB to add a tile!"), + ) + + +ft.app(main) diff --git a/python/controls/buttons/icon-button/icon-button-with-click-event.py b/python/controls/buttons/icon-button/icon-button-with-click-event.py index 9f12fa60..bfd5c29f 100644 --- a/python/controls/buttons/icon-button/icon-button-with-click-event.py +++ b/python/controls/buttons/icon-button/icon-button-with-click-event.py @@ -1,8 +1,7 @@ -import flet -from flet import IconButton, Page, Text, icons +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Icon button with 'click' event" def button_clicked(e): @@ -10,12 +9,12 @@ def button_clicked(e): t.value = f"Button clicked {b.data} time(s)" page.update() - b = IconButton( - icon=icons.PLAY_CIRCLE_FILL_OUTLINED, on_click=button_clicked, data=0 + b = ft.IconButton( + icon=ft.Icons.PLAY_CIRCLE_FILL_OUTLINED, on_click=button_clicked, data=0 ) - t = Text() + t = ft.Text() page.add(b, t) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/buttons/icon-button/icon-buttons.py b/python/controls/buttons/icon-button/icon-buttons.py index 01b529cc..672813c7 100644 --- a/python/controls/buttons/icon-button/icon-buttons.py +++ b/python/controls/buttons/icon-button/icon-buttons.py @@ -1,27 +1,32 @@ -import flet -from flet import IconButton, Page, Row, icons +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Icon buttons" + + sby = ft.SnackBar(ft.Icon(ft.Icons.CHECK_CIRCLE, color=ft.Colors.GREEN_300)) + sbn = ft.SnackBar(ft.Icon(ft.Icons.CANCEL, color=ft.Colors.PINK_700)) page.add( - Row( + ft.Row( [ - IconButton( - icon=icons.PAUSE_CIRCLE_FILLED_ROUNDED, - icon_color="blue400", - icon_size=20, - tooltip="Pause record", + ft.IconButton( + icon=ft.Icons.CHECK_CIRCLE, + icon_color=ft.Colors.GREEN_300, + icon_size=40, + tooltip="Yep", + on_click=lambda e: page.open(sby), ), - IconButton( - icon=icons.DELETE_FOREVER_ROUNDED, - icon_color="pink600", + ft.IconButton( + icon=ft.Icons.CANCEL, + icon_color=ft.Colors.PINK_700, icon_size=40, - tooltip="Delete record", + tooltip="Nope", + on_click=lambda e: page.open(sbn), ), - ] + ], + alignment=ft.MainAxisAlignment.CENTER, ), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/icon-button/toggle-icon-button.py b/python/controls/buttons/icon-button/toggle-icon-button.py index 0d48fd58..9d1d8746 100644 --- a/python/controls/buttons/icon-button/toggle-icon-button.py +++ b/python/controls/buttons/icon-button/toggle-icon-button.py @@ -1,23 +1,30 @@ -import flet -from flet import ButtonStyle, IconButton, Page, colors, icons +import flet as ft -def main(page: Page): - page.padding = 50 +def main(page: ft.Page): + page.padding = 10 + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.vertical_alignment = ft.MainAxisAlignment.CENTER def toggle_icon_button(e): e.control.selected = not e.control.selected e.control.update() page.add( - IconButton( - icon=icons.BATTERY_1_BAR, - selected_icon=icons.BATTERY_FULL, + ft.IconButton( + icon=ft.Icons.BATTERY_1_BAR, + selected_icon=ft.Icons.BATTERY_FULL, + scale=5, on_click=toggle_icon_button, selected=False, - style=ButtonStyle(color={"selected": colors.GREEN, "": colors.RED}), + style=ft.ButtonStyle( + color={ + ft.ControlState.SELECTED: ft.Colors.GREEN, + ft.ControlState.DEFAULT: ft.Colors.RED, + } + ), ) ) -flet.app(target=main) +ft.app(main) From ec4ad7cf6020c0e57efb2667b7dbccb1ecdc0ded Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 12 Mar 2025 23:34:51 -0700 Subject: [PATCH 55/81] update menu-item-button examples --- .../elevated-button-with-click-event.py | 1 + .../menu-item-button-example.py | 74 +++++++++++++++++++ .../outlined-button/basic-outlined-buttons.py | 11 ++- .../outlined-button-with-click-event.py | 12 +-- .../outlined-buttons-with-custom-content.py | 44 +++++------ .../outlined-buttons-with-icons.py | 11 ++- 6 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 python/controls/buttons/menu-item-button/menu-item-button-example.py diff --git a/python/controls/buttons/elevated-button/elevated-button-with-click-event.py b/python/controls/buttons/elevated-button/elevated-button-with-click-event.py index 982f5c7b..5b3fa0ce 100644 --- a/python/controls/buttons/elevated-button/elevated-button-with-click-event.py +++ b/python/controls/buttons/elevated-button/elevated-button-with-click-event.py @@ -3,6 +3,7 @@ def main(page: ft.Page): page.title = "Elevated button with 'click' event" + page.theme_mode = ft.ThemeMode.LIGHT def button_clicked(e): b.data += 1 diff --git a/python/controls/buttons/menu-item-button/menu-item-button-example.py b/python/controls/buttons/menu-item-button/menu-item-button-example.py new file mode 100644 index 00000000..922fe1b6 --- /dev/null +++ b/python/controls/buttons/menu-item-button/menu-item-button-example.py @@ -0,0 +1,74 @@ +import flet as ft + + +def main(page: ft.Page): + page.padding = 0 + page.spacing = 0 + page.theme_mode = ft.ThemeMode.LIGHT + + bg_container = ft.Ref[ft.Container]() + + def handle_color_click(e): + color = e.control.content.value + print(f"{color}.on_click") + bg_container.current.content.value = f"{color} background color" + bg_container.current.bgcolor = color.lower() + page.update() + + def handle_on_hover(e): + print(f"{e.control.content.value}.on_hover") + + menubar = ft.MenuBar( + expand=True, + controls=[ + ft.SubmenuButton( + content=ft.Text("BgColors"), + controls=[ + ft.MenuItemButton( + content=ft.Text("Blue"), + leading=ft.Icon(ft.Icons.COLORIZE), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.BLUE} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ft.MenuItemButton( + content=ft.Text("Green"), + leading=ft.Icon(ft.Icons.COLORIZE), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.GREEN} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ft.MenuItemButton( + content=ft.Text("Red"), + leading=ft.Icon(ft.Icons.COLORIZE), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.RED} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ], + ), + ], + ) + + page.add( + ft.Row([menubar]), + ft.Container( + ref=bg_container, + expand=True, + bgcolor=ft.Colors.SURFACE, + content=ft.Text( + "Choose a bgcolor from the menu", + style=ft.TextStyle(weight=ft.FontWeight.W_500), + ), + alignment=ft.alignment.center, + ), + ) + + +ft.app(main) diff --git a/python/controls/buttons/outlined-button/basic-outlined-buttons.py b/python/controls/buttons/outlined-button/basic-outlined-buttons.py index 1d095bba..10bfeaa2 100644 --- a/python/controls/buttons/outlined-button/basic-outlined-buttons.py +++ b/python/controls/buttons/outlined-button/basic-outlined-buttons.py @@ -1,13 +1,12 @@ -import flet -from flet import OutlinedButton, Page +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Basic outlined buttons" page.add( - OutlinedButton(text="Outlined button"), - OutlinedButton("Disabled button", disabled=True), + ft.OutlinedButton(text="Outlined button"), + ft.OutlinedButton("Disabled button", disabled=True), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/outlined-button/outlined-button-with-click-event.py b/python/controls/buttons/outlined-button/outlined-button-with-click-event.py index 6a5ba97b..a5bed6c2 100644 --- a/python/controls/buttons/outlined-button/outlined-button-with-click-event.py +++ b/python/controls/buttons/outlined-button/outlined-button-with-click-event.py @@ -1,19 +1,19 @@ -import flet -from flet import OutlinedButton, Page, Text +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Outlined button with 'click' event" + page.theme_mode = ft.ThemeMode.LIGHT def button_clicked(e): b.data += 1 t.value = f"Button clicked {b.data} time(s)" page.update() - b = OutlinedButton("Button with 'click' event", on_click=button_clicked, data=0) - t = Text() + b = ft.OutlinedButton("Button with 'click' event", on_click=button_clicked, data=0) + t = ft.Text() page.add(b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py b/python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py index 8d9fb134..83dcff4d 100644 --- a/python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py +++ b/python/controls/buttons/outlined-button/outlined-buttons-with-custom-content.py @@ -1,45 +1,35 @@ -import flet -from flet import ( - Column, - Container, - Icon, - OutlinedButton, - Page, - Row, - Text, - icons, - padding, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Outlined buttons with custom content" + page.theme_mode = ft.ThemeMode.LIGHT page.add( - OutlinedButton( + ft.OutlinedButton( width=150, - content=Row( + content=ft.Row( [ - Icon(name=icons.FAVORITE, color="pink"), - Icon(name=icons.AUDIOTRACK, color="green"), - Icon(name=icons.BEACH_ACCESS, color="blue"), + ft.Icon(name=ft.Icons.FAVORITE, color=ft.Colors.PINK), + ft.Icon(name=ft.Icons.AUDIOTRACK, color=ft.Colors.GREEN), + ft.Icon(name=ft.Icons.BEACH_ACCESS, color=ft.Colors.BLUE), ], - alignment="spaceAround", + alignment=ft.MainAxisAlignment.SPACE_AROUND, ), ), - OutlinedButton( - content=Container( - content=Column( + ft.OutlinedButton( + content=ft.Container( + content=ft.Column( [ - Text(value="Compound button", size=20), - Text(value="This is secondary text"), + ft.Text(value="Compound button", size=20), + ft.Text(value="This is secondary text"), ], - alignment="center", + alignment=ft.MainAxisAlignment.CENTER, spacing=5, ), - padding=padding.all(10), + padding=ft.padding.all(10), ), ), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/outlined-button/outlined-buttons-with-icons.py b/python/controls/buttons/outlined-button/outlined-buttons-with-icons.py index 89df18d3..37cbdfef 100644 --- a/python/controls/buttons/outlined-button/outlined-buttons-with-icons.py +++ b/python/controls/buttons/outlined-button/outlined-buttons-with-icons.py @@ -1,12 +1,11 @@ -import flet -from flet import OutlinedButton, Page +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Outlined buttons with icons" page.add( - OutlinedButton("Button with icon", icon="chair_outlined"), - OutlinedButton( + ft.OutlinedButton("Button with icon", icon="chair_outlined"), + ft.OutlinedButton( "Button with colorful icon", icon="park_rounded", icon_color="green400", @@ -14,4 +13,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) From ab0f9143924acc3ed2a1c9f83fd078f5e2acd846 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 13 Mar 2025 11:12:50 -0700 Subject: [PATCH 56/81] add segmented button example --- .../popup-menu-button/popup-button-example.py | 31 +++++++++ .../buttons/popup-menu-button/popup-button.py | 32 --------- .../segmented-button-example.py | 69 +++++++++++++++++++ 3 files changed, 100 insertions(+), 32 deletions(-) create mode 100644 python/controls/buttons/popup-menu-button/popup-button-example.py delete mode 100644 python/controls/buttons/popup-menu-button/popup-button.py create mode 100644 python/controls/buttons/segmented-button/segmented-button-example.py diff --git a/python/controls/buttons/popup-menu-button/popup-button-example.py b/python/controls/buttons/popup-menu-button/popup-button-example.py new file mode 100644 index 00000000..ec45ab71 --- /dev/null +++ b/python/controls/buttons/popup-menu-button/popup-button-example.py @@ -0,0 +1,31 @@ +import flet as ft + + +def main(page: ft.Page): + def check_item_clicked(e): + e.control.checked = not e.control.checked + page.update() + + pb = ft.PopupMenuButton( + items=[ + ft.PopupMenuItem(text="Item 1"), + ft.PopupMenuItem(icon=ft.Icons.POWER_INPUT, text="Check power"), + ft.PopupMenuItem( + content=ft.Row( + [ + ft.Icon(ft.Icons.HOURGLASS_TOP_OUTLINED), + ft.Text("Item with a custom content"), + ] + ), + on_click=lambda _: print("Button with custom content clicked!"), + ), + ft.PopupMenuItem(), # divider + ft.PopupMenuItem( + text="Checked item", checked=False, on_click=check_item_clicked + ), + ] + ) + page.add(pb) + + +ft.app(main) diff --git a/python/controls/buttons/popup-menu-button/popup-button.py b/python/controls/buttons/popup-menu-button/popup-button.py deleted file mode 100644 index 6bd44402..00000000 --- a/python/controls/buttons/popup-menu-button/popup-button.py +++ /dev/null @@ -1,32 +0,0 @@ -import flet -from flet import Icon, Page, PopupMenuButton, PopupMenuItem, Row, Text, icons - - -def main(page: Page): - def check_item_clicked(e): - e.control.checked = not e.control.checked - page.update() - - pb = PopupMenuButton( - items=[ - PopupMenuItem(text="Item 1"), - PopupMenuItem(icon=icons.POWER_INPUT, text="Check power"), - PopupMenuItem( - content=Row( - [ - Icon(icons.HOURGLASS_TOP_OUTLINED), - Text("Item with a custom content"), - ] - ), - on_click=lambda _: print("Button with a custom content clicked!"), - ), - PopupMenuItem(), # divider - PopupMenuItem( - text="Checked item", checked=False, on_click=check_item_clicked - ), - ] - ) - page.add(pb) - - -flet.app(target=main) diff --git a/python/controls/buttons/segmented-button/segmented-button-example.py b/python/controls/buttons/segmented-button/segmented-button-example.py new file mode 100644 index 00000000..d240d1a3 --- /dev/null +++ b/python/controls/buttons/segmented-button/segmented-button-example.py @@ -0,0 +1,69 @@ +import flet as ft + + +def main(page: ft.Page): + def handle_change(e): + print("on_change data : " + str(e.data)) + + page.add( + ft.SegmentedButton( + on_change=handle_change, + selected_icon=ft.Icon(ft.Icons.CHECK_SHARP), + selected={"1"}, + allow_empty_selection=True, + allow_multiple_selection=True, + segments=[ + ft.Segment( + value="1", + label=ft.Text("1"), + icon=ft.Icon(ft.Icons.LOOKS_ONE), + ), + ft.Segment( + value="2", + label=ft.Text("2"), + icon=ft.Icon(ft.Icons.LOOKS_TWO), + ), + ft.Segment( + value="3", + label=ft.Text("3"), + icon=ft.Icon(ft.Icons.LOOKS_3), + ), + ft.Segment( + value="4", + label=ft.Text("4"), + icon=ft.Icon(ft.Icons.LOOKS_4), + ), + ], + ), + ft.SegmentedButton( + on_change=handle_change, + selected_icon=ft.Icon(ft.Icons.ONETWOTHREE), + selected={"2"}, + allow_multiple_selection=False, + segments=[ + ft.Segment( + value="1", + label=ft.Text("1"), + icon=ft.Icon(ft.Icons.LOOKS_ONE), + ), + ft.Segment( + value="2", + label=ft.Text("2"), + icon=ft.Icon(ft.Icons.LOOKS_TWO), + ), + ft.Segment( + value="3", + label=ft.Text("3"), + icon=ft.Icon(ft.Icons.LOOKS_3), + ), + ft.Segment( + value="4", + label=ft.Text("4"), + icon=ft.Icon(ft.Icons.LOOKS_4), + ), + ], + ), + ) + + +ft.app(main) From c25ddecbb9a19942313ee56be548dbae1fbf407d Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 13 Mar 2025 15:23:18 -0700 Subject: [PATCH 57/81] add submenu button example --- .../submenu-button/submentu-button-example.py | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 python/controls/buttons/submenu-button/submentu-button-example.py diff --git a/python/controls/buttons/submenu-button/submentu-button-example.py b/python/controls/buttons/submenu-button/submentu-button-example.py new file mode 100644 index 00000000..6b85a340 --- /dev/null +++ b/python/controls/buttons/submenu-button/submentu-button-example.py @@ -0,0 +1,156 @@ +import flet as ft + + +def main(page: ft.Page): + page.padding = 0 + page.spacing = 0 + + bg_container = ft.Ref[ft.Container]() + + def handle_color_click(e): + color = e.control.content.value + print(f"{color}.on_click") + bg_container.current.content.value = f"{color} background color" + bg_container.current.bgcolor = color.lower() + page.update() + + def handle_alignment_click(e): + print("in handle alignment click method") + print( + f"bg_container.alignment: {bg_container.alignment}, bg_container.content: {bg_container.content}" + ) + bg_container.current.alignment = e.control.data + # page.update() + # bg_container.alignment = e.control.data + print( + f"e.control.content.value: {e.control.content.value}, e.control.data: {e.control.data}" + ) + page.update() + + def handle_on_hover(e): + print(f"{e.control.content.value}.on_hover") + + bg_container = ft.Container( + # ref=bg_container, + expand=True, + bgcolor=ft.Colors.SURFACE, + content=ft.Text( + "Choose a bgcolor from the menu", + style=ft.TextStyle(size=24, weight=ft.FontWeight.BOLD), + ), + alignment=ft.alignment.center, + ) + menubar = ft.MenuBar( + expand=True, + controls=[ + ft.SubmenuButton( + content=ft.Text("Change Body"), + controls=[ + ft.SubmenuButton( + content=ft.Text("BG Color"), + leading=ft.Icon(ft.Icons.COLORIZE), + controls=[ + ft.MenuItemButton( + content=ft.Text("Blue"), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.BLUE} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ft.MenuItemButton( + content=ft.Text("Green"), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.GREEN} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ft.MenuItemButton( + content=ft.Text("Red"), + style=ft.ButtonStyle( + bgcolor={ft.ControlState.HOVERED: ft.Colors.RED} + ), + on_click=handle_color_click, + on_hover=handle_on_hover, + ), + ], + ), + ft.SubmenuButton( + content=ft.Text("Text alignment"), + leading=ft.Icon(ft.Icons.LOCATION_PIN), + controls=[ + ft.MenuItemButton( + content=ft.Text("bottom_center"), + data=ft.alignment.bottom_center, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.GREY_100 + } + ), + on_click=handle_alignment_click, + # on_hover=handle_on_hover, + ), + ft.MenuItemButton( + content=ft.Text("bottom_left"), + data=ft.alignment.bottom_left, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.GREY_100 + } + ), + on_click=handle_alignment_click, + ), + ft.MenuItemButton( + content=ft.Text("top_center"), + data=ft.alignment.top_center, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.GREY_100 + } + ), + on_click=handle_alignment_click, + ), + ft.MenuItemButton( + content=ft.Text("center_left"), + data=ft.alignment.center_left, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.GREY_100 + } + ), + on_click=handle_alignment_click, + ), + ft.MenuItemButton( + content=ft.Text("center_right"), + data=ft.alignment.center_right, + style=ft.ButtonStyle( + bgcolor={ + ft.ControlState.HOVERED: ft.Colors.GREY_100 + } + ), + on_click=handle_alignment_click, + ), + ], + ), + ], + ) + ], + ) + + page.add( + ft.Row([menubar]), + ft.Container( + ref=bg_container, + expand=True, + bgcolor=ft.Colors.SURFACE, + content=ft.Text( + "Choose a bgcolor from the menu", + style=ft.TextStyle(size=24, weight=ft.FontWeight.BOLD), + ), + alignment=ft.alignment.center, + ), + ) + + +ft.app(main) From a17d8bad4da89c275ebc20f4997623d6cc73c7a0 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 13 Mar 2025 16:34:53 -0700 Subject: [PATCH 58/81] add text-button examples --- .../buttons/text-button/basic-text-buttons.py | 11 +++---- .../text-button-with-click-event.py | 11 +++---- .../text-buttons-with-custom-content.py | 33 +++++++++---------- .../text-button/text-buttons-with-icons.py | 15 ++++----- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/python/controls/buttons/text-button/basic-text-buttons.py b/python/controls/buttons/text-button/basic-text-buttons.py index dfa30058..5a03b202 100644 --- a/python/controls/buttons/text-button/basic-text-buttons.py +++ b/python/controls/buttons/text-button/basic-text-buttons.py @@ -1,13 +1,12 @@ -import flet -from flet import Page, TextButton +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Basic text buttons" page.add( - TextButton(text="Text button"), - TextButton("Disabled button", disabled=True), + ft.TextButton(text="Text button"), + ft.TextButton("Disabled button", disabled=True), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/text-button/text-button-with-click-event.py b/python/controls/buttons/text-button/text-button-with-click-event.py index 4b6b39f9..8c336ea9 100644 --- a/python/controls/buttons/text-button/text-button-with-click-event.py +++ b/python/controls/buttons/text-button/text-button-with-click-event.py @@ -1,8 +1,7 @@ -import flet -from flet import Page, Text, TextButton +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Text button with 'click' event" def button_clicked(e): @@ -10,10 +9,10 @@ def button_clicked(e): t.value = f"Button clicked {b.data} time(s)" page.update() - b = TextButton("Button with 'click' event", on_click=button_clicked, data=0) - t = Text() + b = ft.TextButton("Button with 'click' event", on_click=button_clicked, data=0) + t = ft.Text() page.add(b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/text-button/text-buttons-with-custom-content.py b/python/controls/buttons/text-button/text-buttons-with-custom-content.py index 4731bcc4..fd4a54ce 100644 --- a/python/controls/buttons/text-button/text-buttons-with-custom-content.py +++ b/python/controls/buttons/text-button/text-buttons-with-custom-content.py @@ -1,35 +1,34 @@ -import flet -from flet import Column, Container, Icon, Page, Row, Text, TextButton, icons, padding +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Text buttons with custom content" page.add( - TextButton( + ft.TextButton( width=150, - content=Row( + content=ft.Row( [ - Icon(name=icons.FAVORITE, color="pink"), - Icon(name=icons.AUDIOTRACK, color="green"), - Icon(name=icons.BEACH_ACCESS, color="blue"), + ft.Icon(name=ft.Icons.FAVORITE, color=ft.Colors.PINK), + ft.Icon(name=ft.Icons.AUDIOTRACK, color=ft.Colors.GREEN), + ft.Icon(name=ft.Icons.BEACH_ACCESS, color=ft.Colors.BLUE), ], - alignment="spaceAround", + alignment=ft.MainAxisAlignment.SPACE_AROUND, ), ), - TextButton( - content=Container( - content=Column( + ft.TextButton( + content=ft.Container( + content=ft.Column( [ - Text(value="Compound button", size=20), - Text(value="This is secondary text"), + ft.Text(value="Compound button", size=20), + ft.Text(value="This is secondary text"), ], - alignment="center", + alignment=ft.MainAxisAlignment.CENTER, spacing=5, ), - padding=padding.all(10), + padding=ft.padding.all(10), ), ), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/buttons/text-button/text-buttons-with-icons.py b/python/controls/buttons/text-button/text-buttons-with-icons.py index 649c7381..6ef1ff48 100644 --- a/python/controls/buttons/text-button/text-buttons-with-icons.py +++ b/python/controls/buttons/text-button/text-buttons-with-icons.py @@ -1,17 +1,16 @@ -import flet -from flet import Page, TextButton +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Text buttons with icons" page.add( - TextButton("Button with icon", icon="chair_outlined"), - TextButton( + ft.TextButton("Button with icon", icon=ft.Icons.WAVES_OUTLINED), + ft.TextButton( "Button with colorful icon", - icon="park_rounded", - icon_color="green400", + icon=ft.Icons.PARK_ROUNDED, + icon_color=ft.Colors.GREEN_400, ), ) -flet.app(target=main) +ft.app(main) From fb922f63975461eb94a63c0f53baad1cc6e18c9e Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 17 Mar 2025 23:15:23 -0700 Subject: [PATCH 59/81] update auto-complete, autofill, checkbox, chip, dropdown, radio, range-slider, searchbar, textfield examples --- .../auto-complete/auto-complete-example.py | 18 +++++ .../autofill-group/autofill-example.py | 36 +++++++++ .../checkbox/styled-checkbox.py | 10 +-- .../input-and-selections/chip/chip-example.py | 34 ++++++++ .../dropdown/basic-dropdown.py | 23 ------ .../dropdown/change-items.py | 42 ---------- .../dropdown/dropdown-add-items.py | 20 ----- .../dropdown/dropdown-example.py | 41 ++++++++++ .../dropdown/dropdown-icon-example.py | 33 ++++++++ .../input-and-selections/dropdown/dropdown.py | 30 ------- .../dropdown/label-and-hint.py | 20 ----- .../dropdown/on-change-event.py | 23 ------ .../dropdown/styled-dropdown.py | 23 ------ .../dropdown/styled-dropdowns.py | 79 ++++++++++++++++--- .../dropdownM2/basic-dropdown.py | 22 ++++++ .../dropdownM2/dropdown-change-items.py | 35 ++++++++ .../dropdownM2/dropdown-label-and-hint.py | 19 +++++ .../dropdownM2/dropdown-on-change-event.py | 22 ++++++ .../dropdown-random-icon.py | 13 ++- .../radio/radiogroup-basic.py | 21 +++-- .../radio/radiogroup-with-event.py | 19 +++-- .../radio/styled-radio.py | 25 +++--- .../range-slider/range-slider-example.py | 33 ++++++++ .../range-slider/range-slider-with-event.py | 47 +++++++++++ .../search-bar/search-bar-example.py | 49 ++++++++++++ .../search-bar/search-bar-toggle.py | 68 ++++++++++++++++ .../text-field/basic-textfields.py | 21 +++-- .../{multiline.py => multiline-example.py} | 13 ++- .../text-field/password.py | 9 +-- .../text-field/prefix-suffix.py | 42 +++++----- .../text-field/styled-textfield.py | 27 +++---- ...-change.py => textfield-with-on-change.py} | 11 ++- .../underlined-borderless-example.py | 29 +++++++ .../text-field/underlined.py | 24 ------ 34 files changed, 658 insertions(+), 323 deletions(-) create mode 100644 python/controls/input-and-selections/auto-complete/auto-complete-example.py create mode 100644 python/controls/input-and-selections/autofill-group/autofill-example.py create mode 100644 python/controls/input-and-selections/chip/chip-example.py delete mode 100644 python/controls/input-and-selections/dropdown/basic-dropdown.py delete mode 100644 python/controls/input-and-selections/dropdown/change-items.py delete mode 100644 python/controls/input-and-selections/dropdown/dropdown-add-items.py create mode 100644 python/controls/input-and-selections/dropdown/dropdown-example.py create mode 100644 python/controls/input-and-selections/dropdown/dropdown-icon-example.py delete mode 100644 python/controls/input-and-selections/dropdown/dropdown.py delete mode 100644 python/controls/input-and-selections/dropdown/label-and-hint.py delete mode 100644 python/controls/input-and-selections/dropdown/on-change-event.py delete mode 100644 python/controls/input-and-selections/dropdown/styled-dropdown.py create mode 100644 python/controls/input-and-selections/dropdownM2/basic-dropdown.py create mode 100644 python/controls/input-and-selections/dropdownM2/dropdown-change-items.py create mode 100644 python/controls/input-and-selections/dropdownM2/dropdown-label-and-hint.py create mode 100644 python/controls/input-and-selections/dropdownM2/dropdown-on-change-event.py rename python/controls/input-and-selections/{dropdown => dropdownM2}/dropdown-random-icon.py (67%) create mode 100644 python/controls/input-and-selections/range-slider/range-slider-example.py create mode 100644 python/controls/input-and-selections/range-slider/range-slider-with-event.py create mode 100644 python/controls/input-and-selections/search-bar/search-bar-example.py create mode 100644 python/controls/input-and-selections/search-bar/search-bar-toggle.py rename python/controls/input-and-selections/text-field/{multiline.py => multiline-example.py} (64%) rename python/controls/input-and-selections/text-field/{on-change.py => textfield-with-on-change.py} (57%) create mode 100644 python/controls/input-and-selections/text-field/underlined-borderless-example.py delete mode 100644 python/controls/input-and-selections/text-field/underlined.py diff --git a/python/controls/input-and-selections/auto-complete/auto-complete-example.py b/python/controls/input-and-selections/auto-complete/auto-complete-example.py new file mode 100644 index 00000000..ea0d30d0 --- /dev/null +++ b/python/controls/input-and-selections/auto-complete/auto-complete-example.py @@ -0,0 +1,18 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.AutoComplete( + suggestions=[ + ft.AutoCompleteSuggestion(key="one 1", value="One"), + ft.AutoCompleteSuggestion(key="two 2", value="Two"), + ft.AutoCompleteSuggestion(key="three 3", value="Three"), + ], + on_select=lambda e: print(e.control.selected_index, e.selection), + ), + ft.Text("Type in 1, 2 or 3 to receive suggestions."), + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/autofill-group/autofill-example.py b/python/controls/input-and-selections/autofill-group/autofill-example.py new file mode 100644 index 00000000..fc217c63 --- /dev/null +++ b/python/controls/input-and-selections/autofill-group/autofill-example.py @@ -0,0 +1,36 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.AutofillGroup( + ft.Column( + controls=[ + ft.TextField( + label="Name", + autofill_hints=ft.AutofillHint.NAME, + ), + ft.TextField( + label="Email", + autofill_hints=[ft.AutofillHint.EMAIL], + ), + ft.TextField( + label="Phone Number", + autofill_hints=[ft.AutofillHint.TELEPHONE_NUMBER], + ), + ft.TextField( + label="Street Address", + autofill_hints=ft.AutofillHint.FULL_STREET_ADDRESS, + ), + ft.TextField( + label="Postal Code", + autofill_hints=ft.AutofillHint.POSTAL_CODE, + ), + ] + ) + ) + ) + + +# run with 'flet run -w' +ft.app(main) diff --git a/python/controls/input-and-selections/checkbox/styled-checkbox.py b/python/controls/input-and-selections/checkbox/styled-checkbox.py index f34cf9af..43f621f6 100644 --- a/python/controls/input-and-selections/checkbox/styled-checkbox.py +++ b/python/controls/input-and-selections/checkbox/styled-checkbox.py @@ -6,15 +6,15 @@ def main(page: ft.Page): ft.Checkbox(label="Checkbox with default style"), ft.Checkbox( label="Checkbox with constant fill color", - fill_color="red", - check_color="yellow", + fill_color=ft.Colors.RED, + check_color=ft.Colors.YELLOW, ), ft.Checkbox( label="Checkbox with dynamic fill color", fill_color={ - ft.MaterialState.HOVERED: "blue", - ft.MaterialState.SELECTED: "green", - ft.MaterialState.DEFAULT: "red", + ft.ControlState.HOVERED: ft.Colors.BLUE, + ft.ControlState.SELECTED: ft.Colors.GREEN, + ft.ControlState.DEFAULT: ft.Colors.RED, }, ), ) diff --git a/python/controls/input-and-selections/chip/chip-example.py b/python/controls/input-and-selections/chip/chip-example.py new file mode 100644 index 00000000..d68e33f9 --- /dev/null +++ b/python/controls/input-and-selections/chip/chip-example.py @@ -0,0 +1,34 @@ +import flet as ft + + +def main(page: ft.Page): + def save_to_favorites_clicked(e): + e.control.label.value = "Saved to favorites" + e.control.leading = ft.Icon(ft.Icons.FAVORITE_OUTLINED) + e.control.disabled = True + page.update() + + def open_google_maps(e): + page.launch_url("https://maps.google.com") + page.update() + + save_to_favourites = ft.Chip( + label=ft.Text("Save to favourites"), + leading=ft.Icon(ft.Icons.FAVORITE_BORDER_OUTLINED), + bgcolor=ft.Colors.GREEN_200, + disabled_color=ft.Colors.GREEN_100, + autofocus=True, + on_click=save_to_favorites_clicked, + ) + + open_in_maps = ft.Chip( + label=ft.Text("9 min walk"), + leading=ft.Icon(ft.Icons.MAP_SHARP), + bgcolor=ft.Colors.GREEN_200, + on_click=open_google_maps, + ) + + page.add(ft.Row([save_to_favourites, open_in_maps])) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/basic-dropdown.py b/python/controls/input-and-selections/dropdown/basic-dropdown.py deleted file mode 100644 index a0f4aa81..00000000 --- a/python/controls/input-and-selections/dropdown/basic-dropdown.py +++ /dev/null @@ -1,23 +0,0 @@ -import flet -from flet import Dropdown, ElevatedButton, Page, Text, dropdown - - -def main(page: Page): - def button_clicked(e): - t.value = f"Dropdown value is: {dd.value}" - page.update() - - t = Text() - b = ElevatedButton(text="Submit", on_click=button_clicked) - dd = Dropdown( - width=100, - options=[ - dropdown.Option("Red"), - dropdown.Option("Green"), - dropdown.Option("Blue"), - ], - ) - page.add(dd, b, t) - - -flet.app(target=main) diff --git a/python/controls/input-and-selections/dropdown/change-items.py b/python/controls/input-and-selections/dropdown/change-items.py deleted file mode 100644 index 8626354c..00000000 --- a/python/controls/input-and-selections/dropdown/change-items.py +++ /dev/null @@ -1,42 +0,0 @@ -import flet -from flet import ( - Column, - Container, - Dropdown, - ElevatedButton, - OutlinedButton, - Page, - Row, - TextField, - dropdown, -) - - -def main(page: Page): - def find_option(option_name): - for option in d.options: - if option_name == option.key: - return option - return None - - def add_clicked(e): - d.options.append(dropdown.Option(option_textbox.value)) - d.value = option_textbox.value - option_textbox.value = "" - page.update() - - def delete_clicked(e): - option = find_option(d.value) - if option != None: - d.options.remove(option) - # d.value = None - page.update() - - d = Dropdown() - option_textbox = TextField(hint_text="Enter item name") - add = ElevatedButton("Add", on_click=add_clicked) - delete = OutlinedButton("Delete selected", on_click=delete_clicked) - page.add(d, Row(controls=[option_textbox, add, delete])) - - -flet.app(port=8550, target=main, view=flet.WEB_BROWSER) diff --git a/python/controls/input-and-selections/dropdown/dropdown-add-items.py b/python/controls/input-and-selections/dropdown/dropdown-add-items.py deleted file mode 100644 index 8214be78..00000000 --- a/python/controls/input-and-selections/dropdown/dropdown-add-items.py +++ /dev/null @@ -1,20 +0,0 @@ -import flet as ft - - -def main(page: ft.Page): - page.title = "Add items to dropdown options" - - def add_clicked(e): - d.options.append(ft.dropdown.Option(option_textbox.value)) - d.value = option_textbox.value - option_textbox.value = "" - page.update() - - d = ft.Dropdown() - option_textbox = ft.TextField(hint_text="Enter item name") - add = ft.ElevatedButton("Add", on_click=add_clicked) - - page.add(ft.Column(controls=[d, ft.Row(controls=[option_textbox, add])])) - - -ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/dropdown-example.py b/python/controls/input-and-selections/dropdown/dropdown-example.py new file mode 100644 index 00000000..c4831e25 --- /dev/null +++ b/python/controls/input-and-selections/dropdown/dropdown-example.py @@ -0,0 +1,41 @@ +import flet as ft + + +def main(page: ft.Page): + colors = [ + ft.Colors.RED, + ft.colors.BLUE, + ft.Colors.YELLOW, + ft.Colors.PURPLE, + ft.Colors.LIME, + ] + + def get_options(): + options = [] + for color in colors: + options.append( + ft.DropdownOption( + key=color.value, + content=ft.Text( + value=color.value, + color=color, + ), + ) + ) + return options + + def dropdown_changed(e): + e.control.color = e.control.value + page.update() + + dd = ft.Dropdown( + editable=True, + label="Color", + options=get_options(), + on_change=dropdown_changed, + ) + + page.add(dd) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/dropdown-icon-example.py b/python/controls/input-and-selections/dropdown/dropdown-icon-example.py new file mode 100644 index 00000000..ee61eb0d --- /dev/null +++ b/python/controls/input-and-selections/dropdown/dropdown-icon-example.py @@ -0,0 +1,33 @@ +import flet as ft + + +def main(page: ft.Page): + + icons = [ + {"name": "Smile", "icon_name": ft.Icons.SENTIMENT_SATISFIED_OUTLINED}, + {"name": "Cloud", "icon_name": ft.Icons.CLOUD_OUTLINED}, + {"name": "Brush", "icon_name": ft.Icons.BRUSH_OUTLINED}, + {"name": "Heart", "icon_name": ft.Icons.FAVORITE}, + ] + + def get_options(): + options = [] + for icon in icons: + options.append( + ft.DropdownOption(key=icon["name"], leading_icon=icon["icon_name"]) + ) + return options + + dd = ft.Dropdown( + border=ft.InputBorder.UNDERLINE, + enable_filter=True, + editable=True, + leading_icon=ft.Icons.SEARCH, + label="Icon", + options=get_options(), + ) + + page.add(dd) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/dropdown.py b/python/controls/input-and-selections/dropdown/dropdown.py deleted file mode 100644 index f85f9fcc..00000000 --- a/python/controls/input-and-selections/dropdown/dropdown.py +++ /dev/null @@ -1,30 +0,0 @@ -import logging -import flet as ft - -logging.basicConfig(level=logging.INFO) - - -def main(page: ft.Page): - dd = ft.Dropdown( - options=[ - ft.dropdown.Option("a", "Item A"), - ft.dropdown.Option("b", "Item B"), - ft.dropdown.Option("c", "Item C"), - ] - ) - - def btn2_click(e): - dd.options.append(ft.dropdown.Option("d", "Item D")) - page.update() - - def btn3_click(e): - dd.options[1].text = "Item Blah Blah Blah" - page.update() - - btn2 = ft.ElevatedButton("Add new item!", on_click=btn2_click) - btn3 = ft.ElevatedButton("Change second item", on_click=btn3_click) - - page.add(dd, btn2, btn3) - - -ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/label-and-hint.py b/python/controls/input-and-selections/dropdown/label-and-hint.py deleted file mode 100644 index 24c93f3d..00000000 --- a/python/controls/input-and-selections/dropdown/label-and-hint.py +++ /dev/null @@ -1,20 +0,0 @@ -import flet -from flet import Dropdown, Page, dropdown - - -def main(page: Page): - page.add( - Dropdown( - label="Color", - hint_text="Choose your favourite color?", - options=[ - dropdown.Option("Red"), - dropdown.Option("Green"), - dropdown.Option("Blue"), - ], - autofocus=True, - ) - ) - - -flet.app(target=main) diff --git a/python/controls/input-and-selections/dropdown/on-change-event.py b/python/controls/input-and-selections/dropdown/on-change-event.py deleted file mode 100644 index 0fa2eb0e..00000000 --- a/python/controls/input-and-selections/dropdown/on-change-event.py +++ /dev/null @@ -1,23 +0,0 @@ -import flet -from flet import Dropdown, Page, Text, dropdown - - -def main(page: Page): - def dropdown_changed(e): - t.value = f"Dropdown changed to {dd.value}" - page.update() - - t = Text() - dd = Dropdown( - on_change=dropdown_changed, - options=[ - dropdown.Option("Red"), - dropdown.Option("Green"), - dropdown.Option("Blue"), - ], - width=200, - ) - page.add(dd, t) - - -flet.app(target=main) diff --git a/python/controls/input-and-selections/dropdown/styled-dropdown.py b/python/controls/input-and-selections/dropdown/styled-dropdown.py deleted file mode 100644 index 6be3b285..00000000 --- a/python/controls/input-and-selections/dropdown/styled-dropdown.py +++ /dev/null @@ -1,23 +0,0 @@ -import flet -from flet import Dropdown, Page, colors, dropdown - - -def main(page: Page): - page.padding = 50 - page.add( - Dropdown( - options=[ - dropdown.Option("a", "Item A"), - dropdown.Option("b", "Item B"), - dropdown.Option("c", "Item C"), - ], - border_radius=30, - filled=True, - border_color=colors.TRANSPARENT, - bgcolor=colors.BLACK12, - focused_bgcolor=colors.BLUE_100, - ) - ) - - -flet.app(target=main) diff --git a/python/controls/input-and-selections/dropdown/styled-dropdowns.py b/python/controls/input-and-selections/dropdown/styled-dropdowns.py index 339d37d4..30b3888b 100644 --- a/python/controls/input-and-selections/dropdown/styled-dropdowns.py +++ b/python/controls/input-and-selections/dropdown/styled-dropdowns.py @@ -10,14 +10,13 @@ def main(page): ], text_size=20, content_padding=20, - color=ft.colors.PINK, - bgcolor=ft.colors.BLUE_200, + bgcolor=ft.Colors.BLUE_200, filled=True, - focused_color=ft.colors.GREEN, - focused_bgcolor=ft.colors.CYAN_200, + focused_color=ft.Colors.GREEN, + focused_bgcolor=ft.Colors.CYAN_200, border_radius=30, - border_color=ft.colors.GREEN_800, - focused_border_color=ft.colors.GREEN_ACCENT_400, + border_color=ft.Colors.GREEN_800, + focused_border_color=ft.Colors.GREEN_ACCENT_400, focused_border_width=5, alignment=ft.alignment.center, ) @@ -30,9 +29,10 @@ def main(page): ], border_radius=30, filled=True, - border_color=ft.colors.TRANSPARENT, - bgcolor=ft.colors.BLACK12, - focused_bgcolor=ft.colors.BLUE_100, + border_color=ft.Colors.TRANSPARENT, + bgcolor=ft.Colors.BLACK12, + focused_border_color=ft.Colors.BLUE_100, + focused_border_width=20, alignment=ft.alignment.center_right, ) @@ -42,7 +42,11 @@ def main(page): ft.dropdown.Option("b", "Item B"), ft.dropdown.Option("c", "Item C"), ], + border_color=ft.Colors.PINK_ACCENT, + focused_border_color=ft.Colors.GREEN_ACCENT_400, + focused_border_width=25, border_radius=30, + width=150, ) dd2 = ft.Dropdown( @@ -55,12 +59,63 @@ def main(page): border_radius=20, filled=True, border_width=0, - focused_bgcolor=ft.colors.GREEN_100, + focused_border_color=ft.Colors.GREEN_100, + focused_border_width=10, content_padding=20, - height=50, + width=200, + # height=50, ) - page.add(dd, dd1, dd1_5, dd2) + dd3 = ft.Dropdown( + options=[ + ft.dropdown.Option( + "a", + "Item A", + style=ft.ButtonStyle( + color={ + ft.ControlState.HOVERED: ft.Colors.WHITE, + ft.ControlState.FOCUSED: ft.Colors.BLUE, + ft.ControlState.DEFAULT: ft.Colors.BLACK, + }, + shape=ft.BeveledRectangleBorder(15), + ), + ), + ft.dropdown.Option( + "b", + "Item B", + style=ft.ButtonStyle( + color={ + ft.ControlState.HOVERED: ft.Colors.WHITE, + ft.ControlState.FOCUSED: ft.Colors.BLUE, + ft.ControlState.DEFAULT: ft.Colors.BLACK, + }, + shape=ft.BeveledRectangleBorder(15), + ), + ), + ft.dropdown.Option( + "c", + "Item C", + style=ft.ButtonStyle( + color={ + ft.ControlState.HOVERED: ft.Colors.WHITE, + ft.ControlState.FOCUSED: ft.Colors.BLUE, + ft.ControlState.DEFAULT: ft.Colors.BLACK, + }, + shape=ft.BeveledRectangleBorder(15), + ), + ), + ], + text_size=30, + border_radius=20, + filled=True, + border_width=0, + focused_border_color=ft.Colors.GREEN_100, + focused_border_width=10, + content_padding=20, + width=200, + ) + + page.add(dd, dd1, dd1_5, dd2, dd3) ft.app(target=main) diff --git a/python/controls/input-and-selections/dropdownM2/basic-dropdown.py b/python/controls/input-and-selections/dropdownM2/basic-dropdown.py new file mode 100644 index 00000000..bf85a756 --- /dev/null +++ b/python/controls/input-and-selections/dropdownM2/basic-dropdown.py @@ -0,0 +1,22 @@ +import flet as ft + + +def main(page: ft.Page): + def button_clicked(e): + t.value = f"Dropdown value is: {dd.value}" + page.update() + + t = ft.Text() + b = ft.ElevatedButton(text="Submit", on_click=button_clicked) + dd = ft.DropdownM2( + width=100, + options=[ + ft.dropdownm2.Option("Red"), + ft.dropdownm2.Option("Green"), + ft.dropdownm2.Option("Blue"), + ], + ) + page.add(dd, b, t) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdownM2/dropdown-change-items.py b/python/controls/input-and-selections/dropdownM2/dropdown-change-items.py new file mode 100644 index 00000000..db8e5c5e --- /dev/null +++ b/python/controls/input-and-selections/dropdownM2/dropdown-change-items.py @@ -0,0 +1,35 @@ +import flet as ft + + +def main(page: ft.Page): + def find_option(option_name): + for option in d.options: + if option_name == option.key: + return option + return None + + def add_clicked(e): + d.options.append(ft.dropdown.Option(option_textbox.value)) + d.value = option_textbox.value + option_textbox.value = "" + page.update() + + def delete_clicked(e): + option = find_option(d.value) + if option != None: + d.options.remove(option) + # d.value = None + page.update() + + d = ft.DropdownM2() + option_textbox = ft.TextField(hint_text="Enter item name") + add = ft.ElevatedButton("Add", on_click=add_clicked) + delete = ft.OutlinedButton( + "Delete selected", + on_click=delete_clicked, + style=ft.ButtonStyle(bgcolor=ft.Colors.RED), + ) + page.add(d, ft.Row(controls=[option_textbox, add, delete])) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdownM2/dropdown-label-and-hint.py b/python/controls/input-and-selections/dropdownM2/dropdown-label-and-hint.py new file mode 100644 index 00000000..2a4236b9 --- /dev/null +++ b/python/controls/input-and-selections/dropdownM2/dropdown-label-and-hint.py @@ -0,0 +1,19 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.DropdownM2( + label="Color", + hint_text="Choose your favourite color?", + options=[ + ft.dropdownm2.Option("Red"), + ft.dropdownm2.Option("Green"), + ft.dropdownm2.Option("Blue"), + ], + autofocus=True, + ) + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdownM2/dropdown-on-change-event.py b/python/controls/input-and-selections/dropdownM2/dropdown-on-change-event.py new file mode 100644 index 00000000..2a880af0 --- /dev/null +++ b/python/controls/input-and-selections/dropdownM2/dropdown-on-change-event.py @@ -0,0 +1,22 @@ +import flet as ft + + +def main(page: ft.Page): + def dropdown_changed(e): + t.value = f"Dropdown changed to {dd.value}" + page.update() + + t = ft.Text() + dd = ft.DropdownM2( + on_change=dropdown_changed, + options=[ + ft.dropdownm2.Option("Red"), + ft.dropdownm2.Option("Green"), + ft.dropdownm2.Option("Blue"), + ], + width=200, + ) + page.add(dd, t) + + +ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/dropdown-random-icon.py b/python/controls/input-and-selections/dropdownM2/dropdown-random-icon.py similarity index 67% rename from python/controls/input-and-selections/dropdown/dropdown-random-icon.py rename to python/controls/input-and-selections/dropdownM2/dropdown-random-icon.py index 0f65ab7c..21829f6a 100644 --- a/python/controls/input-and-selections/dropdown/dropdown-random-icon.py +++ b/python/controls/input-and-selections/dropdownM2/dropdown-random-icon.py @@ -1,12 +1,9 @@ -import logging import random import flet as ft -logging.basicConfig(level=logging.INFO) - def main(page: ft.Page): - dd_options = [] + dd_options: list[ft.dropdownm2.Option] = [] def dd_choice(e): t.value = f"{dd.value} chosen" @@ -14,8 +11,8 @@ def dd_choice(e): def btn1_click(e): icon = ft.Icon(ft.Icons.random()) - dd.options.append( - ft.dropdown.Option(text=f"{str(icon.name)[6:]}", content=icon) + dd_options.append( + ft.dropdownm2.Option(text=f"{str(icon.name)[6:]}", content=icon) ) page.update() @@ -25,7 +22,9 @@ def btn2_click(e): btn1 = ft.ElevatedButton("Add random item to dropdown!", on_click=btn1_click) btn2 = ft.ElevatedButton("Shuffle Dropdown items", on_click=btn2_click) - dd = ft.Dropdown(options=dd_options, on_change=dd_choice) + dd = ft.DropdownM2( + options=dd_options, options_fill_horizontally=True, on_change=dd_choice + ) t = ft.Text() page.add(dd, btn1, btn2, t) diff --git a/python/controls/input-and-selections/radio/radiogroup-basic.py b/python/controls/input-and-selections/radio/radiogroup-basic.py index c6a5be65..151a0c72 100644 --- a/python/controls/input-and-selections/radio/radiogroup-basic.py +++ b/python/controls/input-and-selections/radio/radiogroup-basic.py @@ -1,5 +1,4 @@ -import flet -from flet import Column, ElevatedButton, Radio, RadioGroup, Text +import flet as ft def main(page): @@ -7,19 +6,19 @@ def button_clicked(e): t.value = f"Your favorite color is: {cg.value}" page.update() - t = Text() - b = ElevatedButton(text="Submit", on_click=button_clicked) - cg = RadioGroup( - content=Column( + t = ft.Text() + b = ft.ElevatedButton(text="Submit", on_click=button_clicked) + cg = ft.RadioGroup( + content=ft.Column( [ - Radio(value="red", label="Red"), - Radio(value="green", label="Green"), - Radio(value="blue", label="Blue"), + ft.Radio(value="red", label="Red"), + ft.Radio(value="green", label="Green"), + ft.Radio(value="blue", label="Blue"), ] ) ) - page.add(Text("Select your favorite color:"), cg, b, t) + page.add(ft.Text("Select your favorite color:"), cg, b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/radio/radiogroup-with-event.py b/python/controls/input-and-selections/radio/radiogroup-with-event.py index b870b538..758f0692 100644 --- a/python/controls/input-and-selections/radio/radiogroup-with-event.py +++ b/python/controls/input-and-selections/radio/radiogroup-with-event.py @@ -1,5 +1,4 @@ -import flet -from flet import Column, Radio, RadioGroup, Text +import flet as ft def main(page): @@ -7,19 +6,19 @@ def radiogroup_changed(e): t.value = f"Your favorite color is: {e.control.value}" page.update() - t = Text() - cg = RadioGroup( - content=Column( + t = ft.Text() + cg = ft.RadioGroup( + content=ft.Column( [ - Radio(value="red", label="Red"), - Radio(value="green", label="Green"), - Radio(value="blue", label="Blue"), + ft.Radio(value="red", label="Red"), + ft.Radio(value="green", label="Green"), + ft.Radio(value="blue", label="Blue"), ] ), on_change=radiogroup_changed, ) - page.add(Text("Select your favorite color:"), cg, t) + page.add(ft.Text("Select your favorite color:"), cg, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/radio/styled-radio.py b/python/controls/input-and-selections/radio/styled-radio.py index 74d84312..4b048416 100644 --- a/python/controls/input-and-selections/radio/styled-radio.py +++ b/python/controls/input-and-selections/radio/styled-radio.py @@ -1,22 +1,25 @@ -import flet -from flet import Column, Page, Radio, RadioGroup +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - RadioGroup( - Column( + ft.RadioGroup( + ft.Column( [ - Radio(label="Radio with default style", value="1"), - Radio( + ft.Radio(label="Radio with default style", value="1"), + ft.Radio( label="Radio with constant fill color", value="2", - fill_color="red", + fill_color=ft.Colors.RED, ), - Radio( + ft.Radio( label="Radio with dynamic fill color", value="3", - fill_color={"hovered": "blue", "selected": "green", "": "red"}, + fill_color={ + ft.ControlState.HOVERED: ft.Colors.BLUE, + ft.ControlState.SELECTED: ft.Colors.GREEN, + ft.ControlState.DEFAULT: ft.Colors.RED, + }, ), ] ) @@ -24,4 +27,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/input-and-selections/range-slider/range-slider-example.py b/python/controls/input-and-selections/range-slider/range-slider-example.py new file mode 100644 index 00000000..af66b40c --- /dev/null +++ b/python/controls/input-and-selections/range-slider/range-slider-example.py @@ -0,0 +1,33 @@ +import flet as ft + + +def main(page: ft.Page): + range_slider = ft.RangeSlider( + min=0, + max=50, + start_value=10, + divisions=10, + end_value=20, + inactive_color=ft.Colors.GREEN_300, + active_color=ft.Colors.GREEN_700, + overlay_color=ft.Colors.GREEN_100, + label="{value}%", + ) + + page.add( + ft.Column( + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + ft.Text( + "Range slider with divisions and labels", + size=20, + weight=ft.FontWeight.BOLD, + ), + ft.Container(height=30), + range_slider, + ], + ) + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/range-slider/range-slider-with-event.py b/python/controls/input-and-selections/range-slider/range-slider-with-event.py new file mode 100644 index 00000000..b3dc23cb --- /dev/null +++ b/python/controls/input-and-selections/range-slider/range-slider-with-event.py @@ -0,0 +1,47 @@ +import flet as ft + + +def main(page: ft.Page): + page.scroll = ft.ScrollMode.AUTO + + def slider_change_start(e): + print(f"on_change_start: {e.control.start_value}, {e.control.end_value}") + + def slider_is_changing(e): + print(f"on_change: {e.control.start_value}, {e.control.end_value}") + + def slider_change_end(e): + print(f"on_change_end: {e.control.start_value}, {e.control.end_value}") + t.value = f"on_change_end: {e.control.start_value}, {e.control.end_value}" + page.update() + + t = ft.Text("") + + range_slider = ft.RangeSlider( + min=0, + max=50, + start_value=10, + end_value=20, + on_change_start=slider_change_start, + on_change=slider_is_changing, + on_change_end=slider_change_end, + ) + + page.add( + ft.Column( + horizontal_alignment=ft.CrossAxisAlignment.CENTER, + controls=[ + ft.Text( + "Range slider with events", + size=20, + weight=ft.FontWeight.BOLD, + ), + ft.Container(height=30), + range_slider, + t, + ], + ) + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/search-bar/search-bar-example.py b/python/controls/input-and-selections/search-bar/search-bar-example.py new file mode 100644 index 00000000..b0a01841 --- /dev/null +++ b/python/controls/input-and-selections/search-bar/search-bar-example.py @@ -0,0 +1,49 @@ +import flet as ft + + +def main(page): + + def close_anchor(e): + text = f"Color {e.control.data}" + print(f"closing view from {text}") + anchor.close_view(text) + + def handle_change(e): + print(f"handle_change e.data: {e.data}") + + def handle_submit(e): + print(f"handle_submit e.data: {e.data}") + + def handle_tap(e): + print(f"handle_tap") + anchor.open_view() + + anchor = ft.SearchBar( + view_elevation=4, + divider_color=ft.Colors.AMBER, + bar_hint_text="Search colors...", + view_hint_text="Choose a color from the suggestions...", + on_change=handle_change, + on_submit=handle_submit, + on_tap=handle_tap, + controls=[ + ft.ListTile(title=ft.Text(f"Color {i}"), on_click=close_anchor, data=i) + for i in range(10) + ], + ) + + page.add( + ft.Row( + alignment=ft.MainAxisAlignment.CENTER, + controls=[ + ft.OutlinedButton( + "Open Search View", + on_click=lambda _: anchor.open_view(), + ), + ], + ), + anchor, + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/search-bar/search-bar-toggle.py b/python/controls/input-and-selections/search-bar/search-bar-toggle.py new file mode 100644 index 00000000..591e47bb --- /dev/null +++ b/python/controls/input-and-selections/search-bar/search-bar-toggle.py @@ -0,0 +1,68 @@ +import flet as ft + + +def main(page): + + def close_anchor(e): + text = f"Color {e.control.data}" + print(f"closing view from {text}") + anchor.close_view(text) + ob.focus() + + def handle_change(e): + print(f"handle_change e.data: {e.data}") + + def handle_submit(e): + print(f"handle_submit e.data: {e.data}") + page.add(ft.Text(f"Search submitted for: {e.data}")) + page.update() + + def handle_tap(e): + print(f"handle_tap") + anchor.open_view() + + def toggle_open_view(e): + if ob.text == "Open Search View": + ob.text = "Close Search View" + anchor.open_view() + else: + ob.text = "Open Search View" + anchor.close_view(e.data) + page.update() + + def handle_tap_outside_bar(e): + print("handle_tap_outside_bar") + if ob.text == "Open Search View": + ob.text = "Close Search View" + anchor.open_view() + else: + ob.text = "Open Search View" + anchor.close_view(e.data) + page.update() + + anchor = ft.SearchBar( + view_elevation=4, + divider_color=ft.Colors.AMBER, + bar_hint_text="Search colors...", + view_hint_text="Choose a color from the suggestions...", + on_change=handle_change, + on_submit=handle_submit, + on_tap=handle_tap, + # on_tap_outside_bar=handle_tap_outside_bar, + controls=[ + ft.ListTile(title=ft.Text(f"Color {i}"), on_click=close_anchor, data=i) + for i in range(10) + ], + ) + ob = ft.OutlinedButton("Open Search View", on_click=toggle_open_view) + + page.add( + ft.Row( + alignment=ft.MainAxisAlignment.CENTER, + controls=[ob], + ), + anchor, + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/basic-textfields.py b/python/controls/input-and-selections/text-field/basic-textfields.py index 3b7488cc..bbb42638 100644 --- a/python/controls/input-and-selections/text-field/basic-textfields.py +++ b/python/controls/input-and-selections/text-field/basic-textfields.py @@ -1,20 +1,19 @@ -import flet -from flet import ElevatedButton, Page, Text, TextField, icons +import flet as ft -def main(page: Page): +def main(page: ft.Page): def button_clicked(e): t.value = f"Textboxes values are: '{tb1.value}', '{tb2.value}', '{tb3.value}', '{tb4.value}', '{tb5.value}'." page.update() - t = Text() - tb1 = TextField(label="Standard") - tb2 = TextField(label="Disabled", disabled=True, value="First name") - tb3 = TextField(label="Read-only", read_only=True, value="Last name") - tb4 = TextField(label="With placeholder", hint_text="Please enter text here") - tb5 = TextField(label="With an icon", icon=icons.EMOJI_EMOTIONS) - b = ElevatedButton(text="Submit", on_click=button_clicked) + t = ft.Text() + tb1 = ft.TextField(label="Standard") + tb2 = ft.TextField(label="Disabled", disabled=True, value="First name") + tb3 = ft.TextField(label="Read-only", read_only=True, value="Last name") + tb4 = ft.TextField(label="With placeholder", hint_text="Please enter text here") + tb5 = ft.TextField(label="With an icon", icon=ft.Icons.EMOJI_EMOTIONS) + b = ft.ElevatedButton(text="Submit", on_click=button_clicked) page.add(tb1, tb2, tb3, tb4, tb5, b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/multiline.py b/python/controls/input-and-selections/text-field/multiline-example.py similarity index 64% rename from python/controls/input-and-selections/text-field/multiline.py rename to python/controls/input-and-selections/text-field/multiline-example.py index 28927881..481c07db 100644 --- a/python/controls/input-and-selections/text-field/multiline.py +++ b/python/controls/input-and-selections/text-field/multiline-example.py @@ -1,17 +1,16 @@ -import flet -from flet import Page, TextField +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - TextField(label="standard", multiline=True), - TextField( + ft.TextField(label="standard", multiline=True), + ft.TextField( label="disabled", multiline=True, disabled=True, value="line1\nline2\nline3\nline4\nline5", ), - TextField( + ft.TextField( label="Auto adjusted height with max lines", multiline=True, min_lines=1, @@ -20,4 +19,4 @@ def main(page: Page): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/password.py b/python/controls/input-and-selections/text-field/password.py index c43356e0..f9b2febe 100644 --- a/python/controls/input-and-selections/text-field/password.py +++ b/python/controls/input-and-selections/text-field/password.py @@ -1,13 +1,12 @@ -import flet -from flet import Page, TextField +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - TextField( + ft.TextField( label="Password with reveal button", password=True, can_reveal_password=True ) ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/prefix-suffix.py b/python/controls/input-and-selections/text-field/prefix-suffix.py index cd8bb531..fea3a4b5 100644 --- a/python/controls/input-and-selections/text-field/prefix-suffix.py +++ b/python/controls/input-and-selections/text-field/prefix-suffix.py @@ -1,24 +1,28 @@ -import flet -from flet import Page, TextField, icons +import flet as ft -def main(page: Page): - page.add( - TextField(label="With prefix", prefix_text="https://"), - TextField(label="With suffix", suffix_text=".com"), - TextField( - label="With prefix and suffix", prefix_text="https://", suffix_text=".com" - ), - TextField( - label="My favorite color", - icon=icons.FORMAT_SIZE, - hint_text="Type your favorite color", - helper_text="You can type only one color", - counter_text="0 symbols typed", - prefix_icon=icons.COLOR_LENS, - suffix_text="...is your color", - ), +def main(page: ft.Page): + def button_clicked(e): + t.value = f"Textboxes values are: '{pr.value}', '{sf.value}', '{ps.value}', '{icon.value}'." + page.update() + + t = ft.Text() + b = ft.ElevatedButton(text="Submit", on_click=button_clicked) + pr = ft.TextField(label="With prefix", prefix_text="https://") + sf = ft.TextField(label="With suffix", suffix_text=".com") + ps = ft.TextField( + label="With prefix and suffix", prefix_text="https://", suffix_text=".com" + ) + icon = ft.TextField( + label="My favorite color", + icon=ft.Icons.FORMAT_SIZE, + hint_text="Type your favorite color", + helper_text="You can type only one color", + counter_text="0 symbols typed", + prefix_icon=ft.Icons.COLOR_LENS, + suffix_text="...is your color", ) + page.add(pr, sf, ps, icon, b, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/styled-textfield.py b/python/controls/input-and-selections/text-field/styled-textfield.py index 119062a5..67348b26 100644 --- a/python/controls/input-and-selections/text-field/styled-textfield.py +++ b/python/controls/input-and-selections/text-field/styled-textfield.py @@ -1,26 +1,25 @@ -import flet -from flet import Page, TextField, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.padding = 50 page.add( - TextField( + ft.TextField( text_size=30, - cursor_color=colors.RED, - selection_color=colors.YELLOW, - color=colors.PINK, - bgcolor=colors.BLACK26, + cursor_color=ft.Colors.RED, + selection_color=ft.Colors.YELLOW, + color=ft.Colors.PINK, + bgcolor=ft.Colors.BLACK26, filled=True, - focused_color=colors.GREEN, - focused_bgcolor=colors.CYAN_200, + focused_color=ft.Colors.GREEN, + focused_bgcolor=ft.Colors.CYAN_200, border_radius=30, - border_color=colors.GREEN_800, - focused_border_color=colors.GREEN_ACCENT_400, + border_color=ft.Colors.GREEN_800, + focused_border_color=ft.Colors.GREEN_ACCENT_400, max_length=20, - capitalization="characters", + capitalization=ft.TextCapitalization.CHARACTERS, ) ) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/input-and-selections/text-field/on-change.py b/python/controls/input-and-selections/text-field/textfield-with-on-change.py similarity index 57% rename from python/controls/input-and-selections/text-field/on-change.py rename to python/controls/input-and-selections/text-field/textfield-with-on-change.py index 7ad6063d..e426ba98 100644 --- a/python/controls/input-and-selections/text-field/on-change.py +++ b/python/controls/input-and-selections/text-field/textfield-with-on-change.py @@ -1,14 +1,13 @@ -import flet -from flet import ElevatedButton, Page, Text, TextField +import flet as ft -def main(page: Page): +def main(page: ft.Page): def textbox_changed(e): t.value = e.control.value page.update() - t = Text() - tb = TextField( + t = ft.Text() + tb = ft.TextField( label="Textbox with 'change' event:", on_change=textbox_changed, ) @@ -16,4 +15,4 @@ def textbox_changed(e): page.add(tb, t) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/underlined-borderless-example.py b/python/controls/input-and-selections/text-field/underlined-borderless-example.py new file mode 100644 index 00000000..4c022191 --- /dev/null +++ b/python/controls/input-and-selections/text-field/underlined-borderless-example.py @@ -0,0 +1,29 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.TextField( + label="Underlined", + border=ft.InputBorder.UNDERLINE, + hint_text="Enter text here", + ), + ft.TextField( + label="Underlined filled", + border=ft.InputBorder.UNDERLINE, + filled=True, + hint_text="Enter text here", + ), + ft.TextField( + label="Borderless", border=ft.InputBorder.NONE, hint_text="Enter text here" + ), + ft.TextField( + label="Borderless filled", + border=ft.InputBorder.NONE, + filled=True, + hint_text="Enter text here", + ), + ) + + +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/underlined.py b/python/controls/input-and-selections/text-field/underlined.py deleted file mode 100644 index 6265179c..00000000 --- a/python/controls/input-and-selections/text-field/underlined.py +++ /dev/null @@ -1,24 +0,0 @@ -import flet -from flet import Page, TextField - - -def main(page: Page): - page.add( - TextField(label="Underlined", border="underline", hint_text="Enter text here"), - TextField( - label="Underlined filled", - border="underline", - filled=True, - hint_text="Enter text here", - ), - TextField(label="Borderless", border="none", hint_text="Enter text here"), - TextField( - label="Borderless filled", - border="none", - filled=True, - hint_text="Enter text here", - ), - ) - - -flet.app(target=main) From 87391786d16ef976614173516ae6212d3b5cf497 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 17 Mar 2025 23:24:57 -0700 Subject: [PATCH 60/81] update chip examples --- .../chip/chip-filter-example.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 python/controls/input-and-selections/chip/chip-filter-example.py diff --git a/python/controls/input-and-selections/chip/chip-filter-example.py b/python/controls/input-and-selections/chip/chip-filter-example.py new file mode 100644 index 00000000..50b0ecb3 --- /dev/null +++ b/python/controls/input-and-selections/chip/chip-filter-example.py @@ -0,0 +1,26 @@ +import flet as ft + + +def main(page: ft.Page): + def amenity_selected(e): + page.update() + + title = ft.Row([ft.Icon(ft.Icons.HOTEL_CLASS), ft.Text("Amenities")]) + amenities = ["Washer / Dryer", "Ramp access", "Dogs OK", "Cats OK", "Smoke-free"] + amenity_chips = [] + + for amenity in amenities: + amenity_chips.append( + ft.Chip( + label=ft.Text(amenity), + bgcolor=ft.Colors.GREEN_200, + disabled_color=ft.Colors.GREEN_100, + autofocus=True, + on_select=amenity_selected, + ) + ) + + page.add(title, ft.Row(amenity_chips)) + + +ft.app(main) From 5f0b105e27f2f5cfccd659571a63c19f6ef8f69b Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 18 Mar 2025 17:22:16 -0700 Subject: [PATCH 61/81] add date-picker and time-picker examples --- .../date-picker/date-picker-basic.py | 30 ++++++++++++++++ .../time-picker/time-picker-basic.py | 34 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 python/controls/dialogs-alerts-panels/date-picker/date-picker-basic.py create mode 100644 python/controls/dialogs-alerts-panels/time-picker/time-picker-basic.py diff --git a/python/controls/dialogs-alerts-panels/date-picker/date-picker-basic.py b/python/controls/dialogs-alerts-panels/date-picker/date-picker-basic.py new file mode 100644 index 00000000..8cbfb56b --- /dev/null +++ b/python/controls/dialogs-alerts-panels/date-picker/date-picker-basic.py @@ -0,0 +1,30 @@ +import datetime +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + def handle_change(e): + page.add(ft.Text(f"Date changed: {e.control.value.strftime('%m/%d/%Y')}")) + + def handle_dismissal(e): + page.add(ft.Text(f"DatePicker dismissed")) + + page.add( + ft.ElevatedButton( + "Pick date", + icon=ft.Icons.CALENDAR_MONTH, + on_click=lambda e: page.open( + ft.DatePicker( + first_date=datetime.datetime(year=2000, month=10, day=1), + last_date=datetime.datetime(year=2025, month=10, day=1), + on_change=handle_change, + on_dismiss=handle_dismissal, + ) + ), + ) + ) + + +ft.app(main) diff --git a/python/controls/dialogs-alerts-panels/time-picker/time-picker-basic.py b/python/controls/dialogs-alerts-panels/time-picker/time-picker-basic.py new file mode 100644 index 00000000..42d5946f --- /dev/null +++ b/python/controls/dialogs-alerts-panels/time-picker/time-picker-basic.py @@ -0,0 +1,34 @@ +import flet as ft + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + def handle_change(e): + page.add(ft.Text(f"TimePicker change: {time_picker.value}")) + + def handle_dismissal(e): + page.add(ft.Text(f"TimePicker dismissed: {time_picker.value}")) + + def handle_entry_mode_change(e): + page.add(ft.Text(f"TimePicker Entry mode changed to {e.entry_mode}")) + + time_picker = ft.TimePicker( + confirm_text="Confirm", + error_invalid_text="Time out of range", + help_text="Pick your time slot", + on_change=handle_change, + on_dismiss=handle_dismissal, + on_entry_mode_change=handle_entry_mode_change, + ) + + page.add( + ft.ElevatedButton( + "Pick time", + icon=ft.Icons.TIME_TO_LEAVE, + on_click=lambda _: page.open(time_picker), + ) + ) + + +ft.app(main) From d1ca95c1db14f0551d29fa054f2bdfd0732a4931 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sun, 23 Mar 2025 21:55:47 -0600 Subject: [PATCH 62/81] add snack bar example --- .../snack-bar/simple-snack.py | 36 ++++--------------- python/controls/snack-bar/simple-snack.py | 16 --------- 2 files changed, 6 insertions(+), 46 deletions(-) delete mode 100644 python/controls/snack-bar/simple-snack.py diff --git a/python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py b/python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py index f77d02ca..e8e6cdfc 100644 --- a/python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py +++ b/python/controls/dialogs-alerts-panels/snack-bar/simple-snack.py @@ -1,40 +1,16 @@ -import logging import flet as ft -logging.basicConfig(level=logging.DEBUG) - - -class Data: - def __init__(self) -> None: - self.counter = 0 - - def increment(self): - self.counter += 1 - - def decrement(self): - self.counter -= 1 - - -d = Data() - - -def main(page): - page.title = "SnackBar examples" - - sb = ft.SnackBar( - content=ft.Text(f"You did it!"), - action="Undo it!", - on_action=lambda e: d.decrement(), - ) +def main(page: ft.Page): + counter = 0 def on_click(e): - d.increment() - sb.content.value = f"You did it x {d.counter}" - page.open(sb) + nonlocal counter + page.open(ft.SnackBar(ft.Text(f"Counter value at {counter}"))) + counter += 1 page.update() page.add(ft.ElevatedButton("Open SnackBar", on_click=on_click)) -ft.app(main) +ft.app(target=main) diff --git a/python/controls/snack-bar/simple-snack.py b/python/controls/snack-bar/simple-snack.py deleted file mode 100644 index e8e6cdfc..00000000 --- a/python/controls/snack-bar/simple-snack.py +++ /dev/null @@ -1,16 +0,0 @@ -import flet as ft - - -def main(page: ft.Page): - counter = 0 - - def on_click(e): - nonlocal counter - page.open(ft.SnackBar(ft.Text(f"Counter value at {counter}"))) - counter += 1 - page.update() - - page.add(ft.ElevatedButton("Open SnackBar", on_click=on_click)) - - -ft.app(target=main) From bc64c6a79f236a2d7222c1276fd7857165f33058 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sun, 23 Mar 2025 21:56:47 -0600 Subject: [PATCH 63/81] add snack bar example --- .../snack-bar/snack-counter-example.py | 36 ++++++++++ .../ads/ads-basic-example.py | 69 +++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 python/controls/dialogs-alerts-panels/snack-bar/snack-counter-example.py create mode 100644 python/controls/information-displays/ads/ads-basic-example.py diff --git a/python/controls/dialogs-alerts-panels/snack-bar/snack-counter-example.py b/python/controls/dialogs-alerts-panels/snack-bar/snack-counter-example.py new file mode 100644 index 00000000..0b9d9b77 --- /dev/null +++ b/python/controls/dialogs-alerts-panels/snack-bar/snack-counter-example.py @@ -0,0 +1,36 @@ +import flet as ft + + +class Data: + def __init__(self) -> None: + self.counter = 0 + + def increment(self): + self.counter += 1 + + def decrement(self): + self.counter -= 1 + + +d = Data() + + +def main(page): + page.title = "SnackBar examples" + + sb = ft.SnackBar( + content=ft.Text(f"You did it!"), + action="Undo it!", + on_action=lambda e: d.decrement(), + ) + + def on_click(e): + d.increment() + sb.content.value = f"You did it x {d.counter}" + page.open(sb) + page.update() + + page.add(ft.ElevatedButton("Open SnackBar", on_click=on_click)) + + +ft.app(main) diff --git a/python/controls/information-displays/ads/ads-basic-example.py b/python/controls/information-displays/ads/ads-basic-example.py new file mode 100644 index 00000000..a475699b --- /dev/null +++ b/python/controls/information-displays/ads/ads-basic-example.py @@ -0,0 +1,69 @@ +import flet as ft +import flet.ads as ads + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + id_interstitial = ( + "ca-app-pub-3940256099942544/1033173712" + if page.platform == ft.PagePlatform.ANDROID + else "ca-app-pub-3940256099942544/4411468910" + ) + + id_banner = ( + "ca-app-pub-3940256099942544/6300978111" + if page.platform == ft.PagePlatform.ANDROID + else "ca-app-pub-3940256099942544/2934735716" + ) + + def handle_interstitial_close(e): + nonlocal iad + print("InterstitialAd closed") + page.overlay.remove(e.control) + page.overlay.append(iad := get_new_interstitial_ad()) + page.update() + + def get_new_interstitial_ad(): + return ads.InterstitialAd( + unit_id=id_interstitial, + on_load=lambda e: print("InterstitialAd loaded"), + on_error=lambda e: print("InterstitialAd error", e.data), + on_open=lambda e: print("InterstitialAd opened"), + on_close=handle_interstitial_close, + on_impression=lambda e: print("InterstitialAd impression"), + on_click=lambda e: print("InterstitialAd clicked"), + ) + + def display_new_banner_ad(): + page.add( + ft.Container( + content=ads.BannerAd( + unit_id=id_banner, + on_click=lambda e: print("BannerAd clicked"), + on_load=lambda e: print("BannerAd loaded"), + on_error=lambda e: print("BannerAd error", e.data), + on_open=lambda e: print("BannerAd opened"), + on_close=lambda e: print("BannerAd closed"), + on_impression=lambda e: print("BannerAd impression"), + on_will_dismiss=lambda e: print("BannerAd will dismiss"), + ), + width=320, + height=50, + bgcolor=ft.colors.TRANSPARENT, + ) + ) + + page.overlay.append(iad := get_new_interstitial_ad()) + page.appbar = ft.AppBar( + adaptive=True, + title=ft.Text("Mobile Ads Playground"), + bgcolor=ft.colors.LIGHT_BLUE_300, + ) + page.add( + ft.OutlinedButton("Show InterstitialAd", on_click=lambda e: iad.show()), + ft.OutlinedButton("Show BannerAd", on_click=lambda e: display_new_banner_ad()), + ) + + +ft.app(main) From 20763e93c8ccefc77a4f1fd8519f65630a16608c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 26 Mar 2025 14:42:57 -0600 Subject: [PATCH 64/81] update drag and drop examples --- .../audio-recorder/audio-recorder-example.py | 72 +++++ .../drag-drop-nesting.py | 0 .../drag-drop-ordering.py | 257 ++++++++++++++++++ .../dragabble-target-example.py} | 61 ++--- .../utility/drag-target/drag-drop-ordering.py | 255 ----------------- 5 files changed, 354 insertions(+), 291 deletions(-) create mode 100644 python/controls/utility/audio-recorder/audio-recorder-example.py rename python/controls/utility/{drag-target => drag-target-draggable}/drag-drop-nesting.py (100%) create mode 100644 python/controls/utility/drag-target-draggable/drag-drop-ordering.py rename python/controls/utility/{drag-target/drag-drop-colors.py => drag-target-draggable/dragabble-target-example.py} (57%) delete mode 100644 python/controls/utility/drag-target/drag-drop-ordering.py diff --git a/python/controls/utility/audio-recorder/audio-recorder-example.py b/python/controls/utility/audio-recorder/audio-recorder-example.py new file mode 100644 index 00000000..60b72045 --- /dev/null +++ b/python/controls/utility/audio-recorder/audio-recorder-example.py @@ -0,0 +1,72 @@ +# Not working with version 0.27.6 +# "Control not found" error + + +import flet as ft + +# import flet_audio_recorder as ftar + + +def main(page: ft.Page): + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + page.appbar = ft.AppBar(title=ft.Text("Audio Recorder"), center_title=True) + + path = "test-audio-file.wav" + + def handle_start_recording(e): + print(f"StartRecording: {path}") + audio_rec.start_recording(path) + + def handle_stop_recording(e): + output_path = audio_rec.stop_recording() + print(f"StopRecording: {output_path}") + if page.web and output_path is not None: + page.launch_url(output_path) + + def handle_list_devices(e): + devices = audio_rec.get_input_devices() + print(devices) + + def handle_has_permission(e): + try: + print(f"HasPermission: {audio_rec.has_permission()}") + except Exception as e: + print(e) + + def handle_pause(e): + print(f"isRecording: {audio_rec.is_recording()}") + if audio_rec.is_recording(): + audio_rec.pause_recording() + + def handle_resume(e): + print(f"isPaused: {audio_rec.is_paused()}") + if audio_rec.is_paused(): + audio_rec.resume_recording() + + def handle_audio_encoding_test(e): + for i in list(ft.AudioEncoder): + print(f"{i}: {audio_rec.is_supported_encoder(i)}") + + def handle_state_change(e): + print(f"State Changed: {e.data}") + + audio_rec = ft.AudioRecorder( + audio_encoder=ft.AudioEncoder.WAV, + on_state_changed=handle_state_change, + ) + print(f"audio recorder: {audio_rec}") + page.overlay.append(audio_rec) + page.update() + + page.add( + ft.ElevatedButton("Start Audio Recorder", on_click=handle_start_recording), + ft.ElevatedButton("Stop Audio Recorder", on_click=handle_stop_recording), + ft.ElevatedButton("List Devices", on_click=handle_list_devices), + ft.ElevatedButton("Pause Recording", on_click=handle_pause), + ft.ElevatedButton("Resume Recording", on_click=handle_resume), + ft.ElevatedButton("Test AudioEncodings", on_click=handle_audio_encoding_test), + ft.ElevatedButton("Has Permission", on_click=handle_has_permission), + ) + + +ft.app(main) diff --git a/python/controls/utility/drag-target/drag-drop-nesting.py b/python/controls/utility/drag-target-draggable/drag-drop-nesting.py similarity index 100% rename from python/controls/utility/drag-target/drag-drop-nesting.py rename to python/controls/utility/drag-target-draggable/drag-drop-nesting.py diff --git a/python/controls/utility/drag-target-draggable/drag-drop-ordering.py b/python/controls/utility/drag-target-draggable/drag-drop-ordering.py new file mode 100644 index 00000000..4faba535 --- /dev/null +++ b/python/controls/utility/drag-target-draggable/drag-drop-ordering.py @@ -0,0 +1,257 @@ +import logging +import flet as ft + +# logging.basicConfig(level=logging.INFO) +# print("flet version: ", flet.version.version) + + +class ItemList(ft.Draggable): + + def __init__(self, page: ft.Page, list_row, list_name, color): + self.page: ft.Page = page + self.list_row = list_row + self.list_name: str = list_name + self.list_color = color + self.items = ft.Column([], tight=True, spacing=5) + self.end_indicator = ft.Container( + bgcolor=ft.Colors.BLACK26, + border_radius=ft.border_radius.all(30), + height=3, + width=200, + opacity=0.0, + ) + self.item_name = ft.TextField( + label="New Item Name", + width=200, + height=50, + bgcolor=ft.Colors.WHITE, + on_submit=self.add_item_handler, + ) + self.target = ft.DragTarget( + group="items", + content=ft.DragTarget( + group="lists", + content=ft.Container( + content=ft.Column( + [ + self.item_name, + ft.TextButton( + "Add Item", + icon=ft.icons.ADD, + on_click=self.add_item_handler, + ), + self.items, + self.end_indicator, + ], + spacing=4, + tight=True, + expand=True, + ), + border=ft.border.all(2, ft.Colors.BLACK12), + border_radius=ft.border_radius.all(15), + bgcolor=self.list_color, + padding=ft.padding.all(20), + ), + data=self, + on_accept=self.drag_accept, + on_will_accept=self.drag_will_accept, + on_leave=self.drag_leave, + ), + data=self, + on_accept=self.item_drag_accept, + on_will_accept=self.item_drag_will_accept, + on_leave=self.item_drag_leave, + ) + super().__init__(group="lists", content=self.target, data=self) + + def add_item_handler(self, e): + self.add_item() + + def add_item( + self, + item: str = None, + chosen_control: ft.Draggable = None, + swap_control: ft.Draggable = None, + ): + + controls_list = [x.controls[1] for x in self.items.controls] + to_index = ( + controls_list.index(swap_control) if swap_control in controls_list else None + ) + from_index = ( + controls_list.index(chosen_control) + if chosen_control in controls_list + else None + ) + control_to_add = ft.Column( + [ + ft.Container( + bgcolor=ft.Colors.BLACK26, + border_radius=ft.border_radius.all(30), + height=3, + alignment=ft.alignment.center_right, + width=200, + opacity=0.0, + ) + ] + ) + + # rearrange (i.e. drag drop from same list) + if (from_index is not None) and (to_index is not None): + print("rearrange: ", to_index, from_index) + self.items.controls.insert(to_index, self.items.controls.pop(from_index)) + self.set_indicator_opacity(swap_control, 0.0) + + # insert (drag from other list to middle of this list) + elif to_index is not None: + print("insert: ", to_index) + new_item = Item(self, item) + control_to_add.controls.append(new_item) + self.items.controls.insert(to_index, control_to_add) + + # add new (drag from other list to end of this list, or use add item button) + else: + print("add new: ", item) + new_item = new_item = ( + Item(self, item) if item else Item(self, self.item_name.value) + ) + control_to_add.controls.append(new_item) + self.items.controls.append(control_to_add) + self.item_name.value = "" + + print("self.items: ", self.items.controls) + self.update() + self.page.update() + + def set_indicator_opacity(self, item, opacity): + controls_list = [x.controls[1] for x in self.items.controls] + self.items.controls[controls_list.index(item)].controls[0].opacity = opacity + self.update() + + def remove_item(self, item): + controls_list = [x.controls[1] for x in self.items.controls] + del self.items.controls[controls_list.index(item)] + self.update() + + def drag_accept(self, e): + src = self.page.get_control(e.src_id) + + l = self.list_row.current.controls + to_index = l.index(e.control.data) + from_index = l.index(src.content.data) + l[to_index], l[from_index] = l[from_index], l[to_index] + self.end_indicator.opacity = 0.0 + self.page.update() + + def drag_will_accept(self, e): + self.end_indicator.opacity = 0.0 + self.page.update() + + def drag_leave(self, e): + self.end_indicator.opacity = 0.0 + self.page.update() + + def item_drag_accept(self, e): + src = self.page.get_control(e.src_id) + self.add_item(src.data.item_text) + src.data.list.remove_item(src) + self.end_indicator.opacity = 0.0 + self.page.update() + + def item_drag_will_accept(self, e): + self.end_indicator.opacity = 1.0 + self.page.update() + + def item_drag_leave(self, e): + self.end_indicator.opacity = 0.0 + self.page.update() + + +class Item(ft.Draggable): + + def __init__(self, list: ItemList, item_text: str): + self.list = list + self.item_text = item_text + self.card_item = ft.Card( + content=ft.Container( + content=ft.Row( + [ + ft.Icon(name=ft.icons.CIRCLE_OUTLINED), + ft.Text(value=f"{self.item_text}"), + ], + alignment=ft.MainAxisAlignment.START, + ), + width=200, + padding=7, + ), + elevation=1, + data=self.list, + ) + self.target = ft.DragTarget( + group="items", + content=self.card_item, + on_accept=self.drag_accept, + on_leave=self.drag_leave, + on_will_accept=self.drag_will_accept, + ) + super().__init__(group="items", content=self.target, data=self) + + def drag_accept(self, e: ft.DragTargetEvent): + # this is the item picked up (Draggable control) + src = self.list.page.get_control(f"{e.src_id}") + + # e.control is the DragTarget, i.e. This (self) Item in the list + # skip if item is dropped on itself + if src.content.content == e.control.content: + e.control.content.elevation = 1 + self.list.set_indicator_opacity(self, 0.0) + e.control.update() + return + + # item dropped within same list but not on self + if src.data.list == self.list: + self.list.add_item(chosen_control=src, swap_control=self) + self.list.set_indicator_opacity(self, 0.0) + e.control.content.elevation = 1 + e.control.update() + return + + # item added to different list + self.list.add_item(src.data.item_text, swap_control=self) + # remove from the list to which draggable belongs + src.data.list.remove_item(src) + self.list.set_indicator_opacity(self, 0.0) + e.control.content.elevation = 1 + e.control.update() + + def drag_will_accept(self, e): + self.list.set_indicator_opacity(self, 1.0) + e.control.content.elevation = 20 if e.data == "true" else 1 + e.control.update() + + def drag_leave(self, e): + self.list.set_indicator_opacity(self, 0.0) + e.control.content.elevation = 1 + e.control.update() + + +def main(page: ft.Page): + + page.title = "Drag and drop ordering" + list_row = ft.Ref[ft.Row]() + + page.add( + ft.Row( + [ + ItemList(page, list_row, "List 1", ft.Colors.DEEP_ORANGE_400), + ItemList(page, list_row, "List 2", ft.Colors.PINK_400), + ItemList(page, list_row, "List 3", ft.Colors.CYAN_400), + ], + vertical_alignment=ft.CrossAxisAlignment.START, + ref=list_row, + ) + ) + page.update() + + +ft.app(target=main) diff --git a/python/controls/utility/drag-target/drag-drop-colors.py b/python/controls/utility/drag-target-draggable/dragabble-target-example.py similarity index 57% rename from python/controls/utility/drag-target/drag-drop-colors.py rename to python/controls/utility/drag-target-draggable/dragabble-target-example.py index 1863dee0..12ad0b2f 100644 --- a/python/controls/utility/drag-target/drag-drop-colors.py +++ b/python/controls/utility/drag-target-draggable/dragabble-target-example.py @@ -1,28 +1,17 @@ -import flet -from flet import ( - Column, - Container, - Draggable, - DragTarget, - DragTargetAcceptEvent, - Page, - Row, - border, - colors, -) +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Drag and Drop example" def drag_will_accept(e): - e.control.content.border = border.all( - 2, colors.BLACK45 if e.data == "true" else colors.RED + e.control.content.border = ft.border.all( + 2, ft.Colors.BLACK45 if e.data == "true" else ft.Colors.RED ) e.control.update() - def drag_accept(e: DragTargetAcceptEvent): - src = page.get_control(e.src_id) + def drag_accept(e: ft.DragTargetEvent): + src = page.get_control(f"{e.src_id}") e.control.content.bgcolor = src.content.bgcolor e.control.content.border = None e.control.update() @@ -32,52 +21,52 @@ def drag_leave(e): e.control.update() page.add( - Row( + ft.Row( [ - Column( + ft.Column( [ - Draggable( + ft.Draggable( group="color", - content=Container( + content=ft.Container( width=50, height=50, - bgcolor=colors.CYAN, + bgcolor=ft.Colors.CYAN, border_radius=5, ), - content_feedback=Container( + content_feedback=ft.Container( width=20, height=20, - bgcolor=colors.CYAN, + bgcolor=ft.Colors.CYAN, border_radius=3, ), ), - Draggable( + ft.Draggable( group="color", - content=Container( + content=ft.Container( width=50, height=50, - bgcolor=colors.YELLOW, + bgcolor=ft.Colors.YELLOW, border_radius=5, ), ), - Draggable( - group="color1", - content=Container( + ft.Draggable( + group="color", + content=ft.Container( width=50, height=50, - bgcolor=colors.GREEN, + bgcolor=ft.Colors.GREEN, border_radius=5, ), ), ] ), - Container(width=100), - DragTarget( + ft.Container(width=100), + ft.DragTarget( group="color", - content=Container( + content=ft.Container( width=50, height=50, - bgcolor=colors.BLUE_GREY_100, + bgcolor=ft.Colors.BLUE_GREY_100, border_radius=5, ), on_will_accept=drag_will_accept, @@ -89,4 +78,4 @@ def drag_leave(e): ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/utility/drag-target/drag-drop-ordering.py b/python/controls/utility/drag-target/drag-drop-ordering.py deleted file mode 100644 index fd42a105..00000000 --- a/python/controls/utility/drag-target/drag-drop-ordering.py +++ /dev/null @@ -1,255 +0,0 @@ -import logging -import flet -from flet import ( - Page, - DragTarget, - Draggable, - Container, - Column, - Row, - Text, - TextButton, - Icon, - TextField, - UserControl, - Card, - icons, - border_radius, - border, - alignment, - colors, - padding, -) - -# logging.basicConfig(level=logging.INFO) -# print("flet version: ", flet.version.version) - - -class ItemList(UserControl): - - def __init__(self, page, list_name, color): - super().__init__() - self.page = page - self.list_name: str = list_name - self.list_color = color - self.items = Column([], tight=True, spacing=5) - self.end_indicator = Container( - bgcolor=colors.BLACK26, - border_radius=border_radius.all(30), - height=3, - width=200, - opacity=0.0 - ) - self.item_name = TextField( - label="New Item Name", width=200, height=50, bgcolor=colors.WHITE, on_submit=self.add_item_handler) - - def build(self): - self.view = Draggable( - group="lists", - content=DragTarget( - group="items", - content=DragTarget( - group="lists", - content=Container( - content=Column([ - self.item_name, - TextButton( - "Add Item", icon=icons.ADD, on_click=self.add_item_handler), - self.items, - self.end_indicator - ], spacing=4, tight=True, expand=True), - border=border.all(2, colors.BLACK12), - border_radius=border_radius.all(15), - bgcolor=self.list_color, - padding=padding.all(20), - ), - data=self, - on_accept=self.drag_accept, - on_will_accept=self.drag_will_accept, - on_leave=self.drag_leave - ), - data=self, - on_accept=self.item_drag_accept, - on_will_accept=self.item_drag_will_accept, - on_leave=self.item_drag_leave - ) - ) - return self.view - - def add_item_handler(self, e): - self.add_item() - - def add_item(self, item: str = None, chosen_control: Draggable = None, swap_control: Draggable = None): - - controls_list = [x.controls[1] for x in self.items.controls] - to_index = controls_list.index( - swap_control) if swap_control in controls_list else None - from_index = controls_list.index( - chosen_control) if chosen_control in controls_list else None - control_to_add = Column([ - Container( - bgcolor=colors.BLACK26, - border_radius=border_radius.all(30), - height=3, - alignment=alignment.center_right, - width=200, - opacity=0.0 - ) - ]) - - # rearrange (i.e. drag drop from same list) - if ((from_index is not None) and (to_index is not None)): - print("rearrange: ", to_index, from_index) - self.items.controls.insert( - to_index, self.items.controls.pop(from_index)) - self.set_indicator_opacity(swap_control, 0.0) - - # insert (drag from other list to middle of this list) - elif (to_index is not None): - print("insert: ", to_index) - new_item = Item(self, item) - control_to_add.controls.append(new_item.view) - self.items.controls.insert(to_index, control_to_add) - - # add new (drag from other list to end of this list, or use add item button) - else: - print("add new: ", item) - new_item = new_item = Item(self, item) if item else Item( - self, self.item_name.value) - control_to_add.controls.append(new_item.view) - self.items.controls.append(control_to_add) - self.item_name.value = "" - - print("self.items: ", self.items.controls) - self.view.update() - self.page.update() - - def set_indicator_opacity(self, item, opacity): - controls_list = [x.controls[1] for x in self.items.controls] - self.items.controls[controls_list.index( - item)].controls[0].opacity = opacity - self.view.update() - - def remove_item(self, item): - controls_list = [x.controls[1] for x in self.items.controls] - del self.items.controls[controls_list.index(item)] - self.view.update() - - def drag_accept(self, e): - src = self.page.get_control(e.src_id) - l = self.page.item_lists.controls - to_index = l.index(e.control.data) - from_index = l.index(src.content.data) - l[to_index], l[from_index] = l[from_index], l[to_index] - self.end_indicator.opacity = 0.0 - # self.update() - self.page.update() - - def drag_will_accept(self, e): - self.end_indicator.opacity = 0.0 - self.page.update() - - def drag_leave(self, e): - self.end_indicator.opacity = 0.0 - self.page.update() - - def item_drag_accept(self, e): - src = self.page.get_control(e.src_id) - self.add_item(src.data.item_text) - src.data.list.remove_item(src) - self.end_indicator.opacity = 0.0 - self.update() - - def item_drag_will_accept(self, e): - self.end_indicator.opacity = 1.0 - self.update() - - def item_drag_leave(self, e): - self.end_indicator.opacity = 0.0 - self.update() - - -class Item(): - - def __init__(self, list: ItemList, item_text: str): - self.list = list - self.item_text = item_text - self.card_item = Card( - content=Container( - content=Row([ - Icon(name=icons.CIRCLE_OUTLINED), - Text(value=f"{self.item_text}") - ], - alignment="start", - ), - width=200, - padding=7 - ), - elevation=1, - data=self.list - ) - self.view = Draggable( - group="items", - content=DragTarget( - group="items", - content=self.card_item, - on_accept=self.drag_accept, - on_leave=self.drag_leave, - on_will_accept=self.drag_will_accept, - ), - data=self - - ) - - def drag_accept(self, e): - # this is the item picked up (Draggable control) - src = self.list.page.get_control(e.src_id) - - # e.control is the DragTarget, i.e. This (self) Item in the list - # skip if item is dropped on itself - if (src.content.content == e.control.content): - e.control.content.elevation = 1 - self.list.set_indicator_opacity(self.view, 0.0) - e.control.update() - return - - # item dropped within same list but not on self - if (src.data.list == self.list): - self.list.add_item(chosen_control=src, - swap_control=self.view) - self.list.set_indicator_opacity(self.view, 0.0) - e.control.content.elevation = 1 - e.control.update() - return - - # item added to different list - self.list.add_item(src.data.item_text, swap_control=self.view) - # remove from the list to which draggable belongs - src.data.list.remove_item(src) - self.list.set_indicator_opacity(self.view, 0.0) - e.control.content.elevation = 1 - e.control.update() - - def drag_will_accept(self, e): - self.list.set_indicator_opacity(self.view, 1.0) - e.control.content.elevation = 20 if e.data == "true" else 1 - e.control.update() - - def drag_leave(self, e): - self.list.set_indicator_opacity(self.view, 0.0) - e.control.content.elevation = 1 - e.control.update() - - -def main(page: Page): - - page.title = "Drag and drop ordering" - page.item_lists = Row([ - ItemList(page, "List 1", colors.DEEP_ORANGE_400), - ItemList(page, "List 2", colors.PINK_400), - ItemList(page, "List 3", colors.CYAN_400), - ], vertical_alignment="start") - page.add(page.item_lists) - - -flet.app(target=main) From 1090b40be4322be8cb15ef5296e087dea45beedc Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 26 Mar 2025 17:09:41 -0600 Subject: [PATCH 65/81] update drag-drop nesting example --- .../drag-drop-nesting.py | 165 +++++++++--------- 1 file changed, 80 insertions(+), 85 deletions(-) diff --git a/python/controls/utility/drag-target-draggable/drag-drop-nesting.py b/python/controls/utility/drag-target-draggable/drag-drop-nesting.py index 43ee6992..cab53252 100644 --- a/python/controls/utility/drag-target-draggable/drag-drop-nesting.py +++ b/python/controls/utility/drag-target-draggable/drag-drop-nesting.py @@ -1,80 +1,70 @@ -import logging -import flet -from flet import ( - Page, - DragTarget, - Draggable, - Container, - Column, - Row, - Icon, - UserControl, - icons, - border, - alignment, - colors, -) - - -class OuterContainer(UserControl): - - def __init__(self, page, color): - super().__init__() +import flet as ft + + +class OuterContainer(ft.Draggable): + + def __init__(self, page, list_ref, color): + self.page = page + self.list_ref = list_ref self.container_color = color + # inner_container is a draggable self.inner_container = InnerContainer(self) - self.outer_container = Container( - content=self.inner_container.view, + self.outer_container = ft.Container( + content=self.inner_container, width=200, height=200, bgcolor=self.container_color, border_radius=5, - alignment=alignment.center, - border=border.all(4, colors.BLACK12), + alignment=ft.alignment.center, + border=ft.border.all(4, ft.Colors.BLACK12), ) - def build(self): - self.view = Draggable( - group="outer", - content=DragTarget( - group="inner", - content=DragTarget( - group="outer", - content=self.outer_container, - data=self, - on_accept=self.drag_accept, - on_will_accept=self.drag_will_accept, - on_leave=self.drag_leave - ), + self.target = ft.DragTarget( + group="inner", + content=ft.DragTarget( + group="outer", + content=self.outer_container, data=self, - on_accept=self.inner_drag_accept, - on_will_accept=self.inner_drag_will_accept, - on_leave=self.inner_drag_leave - ) + on_accept=self.drag_accept, + on_will_accept=self.drag_will_accept, + on_leave=self.drag_leave, + ), + data=self, + on_accept=self.inner_drag_accept, + on_will_accept=self.inner_drag_will_accept, + on_leave=self.inner_drag_leave, ) - return self.view + super().__init__(content=self.target, group="outer", data=self) def drag_accept(self, e): - if e.data == 'true': - self.outer_container.border = border.all(4, colors.BLACK12) - self.view.update() + print(f"e: {e}") + if e.data == "true": + print("drag_accept outer") + self.outer_container.border = ft.border.all(4, ft.Colors.BLACK12) + self.update() def drag_will_accept(self, e): - if e.data == 'true': - self.outer_container.border = border.all(4, colors.BLACK54) - self.view.update() + print(f"e: {e}") + if e.data == "true": + print("drag_will_accept outer") + self.outer_container.border = ft.border.all(4, ft.Colors.BLACK54) + self.update() def drag_leave(self, e): - self.outer_container.border = border.all(4, colors.BLACK12) - self.view.update() + print(f"e: {e}") + self.outer_container.border = ft.border.all(4, ft.Colors.BLACK12) + self.update() def inner_drag_accept(self, e): - if e.data == 'true': + if e.data == "true": + print("drag_accept inner") self.outer_container.border_radius = 5 self.update() def inner_drag_will_accept(self, e): - if e.data == 'true': + if e.data == "true": + print("drag_will_accept inner") self.outer_container.border_radius = 25 self.update() @@ -83,61 +73,66 @@ def inner_drag_leave(self, e): self.update() -class InnerContainer(): +class InnerContainer(ft.Draggable): def __init__(self, outer: OuterContainer): self.outer = outer - self.inner_icon = Icon( - icons.CIRCLE, - color=colors.WHITE54, - size=100, - tooltip="drag me!" + self.inner_icon = ft.Icon( + ft.Icons.CIRCLE, color=ft.Colors.WHITE54, size=100, tooltip="drag me!" ) + # self.data = self - self.view = Draggable( + self.target = ft.DragTarget( group="inner", - content=DragTarget( - group="inner", - content=self.inner_icon, - - on_accept=self.drag_accept, - on_leave=self.drag_leave, - on_will_accept=self.drag_will_accept, - ), - data=self + content=self.inner_icon, + on_accept=self.drag_accept, + on_leave=self.drag_leave, + on_will_accept=self.drag_will_accept, ) + super().__init__(content=self.target, group="outer", data=self) def change_color(self, color: str): self.inner_icon.color = color - self.view.update() + self.update() def drag_accept(self, e): - if e.data == 'true': - self.change_color(colors.WHITE54) + if e.data == "true": + print("drag_accept from inner") + self.change_color(ft.Colors.WHITE54) print("inner_drag_accept") def drag_will_accept(self, e): if e.data == "true": - self.change_color(colors.BLUE_GREY) - self.view.update() + print("drag_will_accept from inner") + self.change_color(ft.Colors.BLUE_GREY) + self.update() def drag_leave(self, e): - self.change_color(colors.WHITE54) - self.view.update() + self.change_color(ft.Colors.WHITE54) + self.update() -def main(page: Page): +def main(page: ft.Page): page.title = "Drag and drop ordering" - page.bgcolor = colors.BLUE_GREY_100 - page.containers = Row([ - OuterContainer(page, colors.DEEP_ORANGE_400), - OuterContainer(page, colors.BLUE_400), - ], alignment="spaceAround", vertical_alignment="center", expand=True) - page.add(page.containers) + list_ref = ft.Ref[ft.Row]() + page.bgcolor = ft.Colors.BLUE_GREY_100 + page.add( + ft.Row( + [ + OuterContainer(page, list_ref, ft.Colors.DEEP_ORANGE_400), + OuterContainer(page, list_ref, ft.Colors.BLUE_400), + ], + alignment=ft.MainAxisAlignment.SPACE_AROUND, + vertical_alignment=ft.CrossAxisAlignment.CENTER, + expand=True, + ref=list_ref, + ) + ) + page.update() # print("flet path: ", flet.__file__) # logging.basicConfig(level=logging.DEBUG, # format='%(asctime)s.%(msecs)03d %(message)s', datefmt='%H:%M:%S') -flet.app(target=main) +ft.app(target=main) From 8048c8769e88ed72ac7d6e3854a43d2d5a887c8c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 27 Mar 2025 07:11:27 -0600 Subject: [PATCH 66/81] update file-picker, flashlight, geolocator, gesture-detector examples --- .../file-picker/file-picker-all-modes.py | 71 ++---------- .../file-picker-upload-progress.py | 52 ++++----- .../utility/flashlight/flashlight-example.py | 10 ++ .../utility/geolocator/geolocator-example.py | 104 ++++++++++++++++++ ...draggable-container_change_mouse_cursor.py | 52 ++++----- .../gesture-detector/gestures-tester.py | 11 +- 6 files changed, 172 insertions(+), 128 deletions(-) create mode 100644 python/controls/utility/flashlight/flashlight-example.py create mode 100644 python/controls/utility/geolocator/geolocator-example.py diff --git a/python/controls/utility/file-picker/file-picker-all-modes.py b/python/controls/utility/file-picker/file-picker-all-modes.py index cb8d889a..36b96d63 100644 --- a/python/controls/utility/file-picker/file-picker-all-modes.py +++ b/python/controls/utility/file-picker/file-picker-all-modes.py @@ -1,81 +1,32 @@ -import flet -from flet import ( - ElevatedButton, - FilePicker, - FilePickerResultEvent, - Page, - Row, - Text, - icons, -) +import flet as ft -def main(page: Page): - # Pick files dialog - def pick_files_result(e: FilePickerResultEvent): +def main(page: ft.Page): + def pick_files_result(e: ft.FilePickerResultEvent): selected_files.value = ( ", ".join(map(lambda f: f.name, e.files)) if e.files else "Cancelled!" ) selected_files.update() - pick_files_dialog = FilePicker(on_result=pick_files_result) - selected_files = Text() + pick_files_dialog = ft.FilePicker(on_result=pick_files_result) + selected_files = ft.Text() - # Save file dialog - def save_file_result(e: FilePickerResultEvent): - save_file_path.value = e.path if e.path else "Cancelled!" - save_file_path.update() - - save_file_dialog = FilePicker(on_result=save_file_result) - save_file_path = Text() - - # Open directory dialog - def get_directory_result(e: FilePickerResultEvent): - directory_path.value = e.path if e.path else "Cancelled!" - directory_path.update() - - get_directory_dialog = FilePicker(on_result=get_directory_result) - directory_path = Text() - - # hide all dialogs in overlay - page.overlay.extend([pick_files_dialog, save_file_dialog, get_directory_dialog]) + page.overlay.append(pick_files_dialog) page.add( - Row( + ft.Row( [ - ElevatedButton( + ft.ElevatedButton( "Pick files", - icon=icons.UPLOAD_FILE, + icon=ft.Icons.UPLOAD_FILE, on_click=lambda _: pick_files_dialog.pick_files( allow_multiple=True ), ), selected_files, ] - ), - Row( - [ - ElevatedButton( - "Save file", - icon=icons.SAVE, - on_click=lambda _: save_file_dialog.save_file(), - disabled=page.web, - ), - save_file_path, - ] - ), - Row( - [ - ElevatedButton( - "Open directory", - icon=icons.FOLDER_OPEN, - on_click=lambda _: get_directory_dialog.get_directory_path(), - disabled=page.web, - ), - directory_path, - ] - ), + ) ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/utility/file-picker/file-picker-upload-progress.py b/python/controls/utility/file-picker/file-picker-upload-progress.py index cf7403f1..2fb142eb 100644 --- a/python/controls/utility/file-picker/file-picker-upload-progress.py +++ b/python/controls/utility/file-picker/file-picker-upload-progress.py @@ -1,52 +1,40 @@ from typing import Dict -import flet -from flet import ( - Column, - ElevatedButton, - FilePicker, - FilePickerResultEvent, - FilePickerUploadEvent, - FilePickerUploadFile, - Page, - ProgressRing, - Ref, - Row, - Text, - icons, -) +import flet as ft -def main(page: Page): - prog_bars: Dict[str, ProgressRing] = {} - files = Ref[Column]() - upload_button = Ref[ElevatedButton]() +def main(page: ft.Page): + prog_bars: Dict[str, ft.ProgressRing] = {} + files = ft.Ref[ft.Column]() + upload_button = ft.Ref[ft.ElevatedButton]() - def file_picker_result(e: FilePickerResultEvent): + def file_picker_result(e: ft.FilePickerResultEvent): upload_button.current.disabled = True if e.files is None else False prog_bars.clear() files.current.controls.clear() if e.files is not None: for f in e.files: - prog = ProgressRing(value=0, bgcolor="#eeeeee", width=20, height=20) + prog = ft.ProgressRing(value=0, bgcolor="#eeeeee", width=20, height=20) prog_bars[f.name] = prog - files.current.controls.append(Row([prog, Text(f.name)])) + files.current.controls.append(ft.Row([prog, ft.Text(f.name)])) page.update() - def on_upload_progress(e: FilePickerUploadEvent): + def on_upload_progress(e: ft.FilePickerUploadEvent): prog_bars[e.file_name].value = e.progress prog_bars[e.file_name].update() - file_picker = FilePicker(on_result=file_picker_result, on_upload=on_upload_progress) + file_picker = ft.FilePicker( + on_result=file_picker_result, on_upload=on_upload_progress + ) def upload_files(e): uf = [] if file_picker.result is not None and file_picker.result.files is not None: for f in file_picker.result.files: uf.append( - FilePickerUploadFile( + ft.FilePickerUploadFile( f.name, - upload_url=page.get_upload_url(f.name, 600), + upload_url=page.get_upload_url(f"dir/{f.name}", 60), ) ) file_picker.upload(uf) @@ -55,20 +43,20 @@ def upload_files(e): page.overlay.append(file_picker) page.add( - ElevatedButton( + ft.ElevatedButton( "Select files...", - icon=icons.FOLDER_OPEN, + icon=ft.Icons.FOLDER_OPEN, on_click=lambda _: file_picker.pick_files(allow_multiple=True), ), - Column(ref=files), - ElevatedButton( + ft.Column(ref=files), + ft.ElevatedButton( "Upload", ref=upload_button, - icon=icons.UPLOAD, + icon=ft.Icons.UPLOAD, on_click=upload_files, disabled=True, ), ) -flet.app(target=main, upload_dir="uploads", view=flet.WEB_BROWSER) +ft.app(target=main, upload_dir="uploads") diff --git a/python/controls/utility/flashlight/flashlight-example.py b/python/controls/utility/flashlight/flashlight-example.py new file mode 100644 index 00000000..27a91719 --- /dev/null +++ b/python/controls/utility/flashlight/flashlight-example.py @@ -0,0 +1,10 @@ +import flet as ft + + +def main(page: ft.Page): + flashlight = ft.Flashlight() + page.overlay.append(flashlight) + page.add(ft.TextButton("toggle", on_click=lambda _: flashlight.toggle())) + + +ft.app(main) diff --git a/python/controls/utility/geolocator/geolocator-example.py b/python/controls/utility/geolocator/geolocator-example.py new file mode 100644 index 00000000..3513e89b --- /dev/null +++ b/python/controls/utility/geolocator/geolocator-example.py @@ -0,0 +1,104 @@ +import flet as ft + + +async def main(page: ft.Page): + page.scroll = ft.ScrollMode.ADAPTIVE + page.appbar = ft.AppBar(title=ft.Text("Geolocator Tests")) + + def handle_position_change(e): + page.add(ft.Text(f"New position: {e.latitude} {e.longitude}")) + + gl = ft.Geolocator( + location_settings=ft.GeolocatorSettings( + accuracy=ft.GeolocatorPositionAccuracy.LOW + ), + on_position_change=handle_position_change, + on_error=lambda e: page.add(ft.Text(f"Error: {e.data}")), + ) + page.overlay.append(gl) + + settings_dlg = lambda handler: ft.AlertDialog( + adaptive=True, + title=ft.Text("Opening Location Settings..."), + content=ft.Text( + "You are about to be redirected to the location/app settings. " + "Please locate this app and grant it location permissions." + ), + actions=[ft.TextButton(text="Take me there", on_click=handler)], + actions_alignment=ft.MainAxisAlignment.CENTER, + ) + + async def handle_permission_request(e): + p = await gl.request_permission_async(wait_timeout=60) + page.add(ft.Text(f"request_permission: {p}")) + + async def handle_get_permission_status(e): + p = await gl.get_permission_status_async() + page.add(ft.Text(f"get_permission_status: {p}")) + + async def handle_get_current_position(e): + p = await gl.get_current_position_async() + page.add(ft.Text(f"get_current_position: ({p.latitude}, {p.longitude})")) + + async def handle_get_last_known_position(e): + p = await gl.get_last_known_position_async() + page.add(ft.Text(f"get_last_known_position: ({p.latitude}, {p.longitude})")) + + async def handle_location_service_enabled(e): + p = await gl.is_location_service_enabled_async() + page.add(ft.Text(f"is_location_service_enabled: {p}")) + + async def handle_open_location_settings(e): + p = await gl.open_location_settings_async() + page.close(location_settings_dlg) + page.add(ft.Text(f"open_location_settings: {p}")) + + async def handle_open_app_settings(e): + p = await gl.open_app_settings_async() + page.close(app_settings_dlg) + page.add(ft.Text(f"open_app_settings: {p}")) + + location_settings_dlg = settings_dlg(handle_open_location_settings) + app_settings_dlg = settings_dlg(handle_open_app_settings) + + page.add( + ft.Row( + wrap=True, + controls=[ + ft.OutlinedButton( + "Request Permission", + on_click=handle_permission_request, + ), + ft.OutlinedButton( + "Get Permission Status", + on_click=handle_get_permission_status, + ), + ft.OutlinedButton( + "Get Current Position", + on_click=handle_get_current_position, + ), + ft.OutlinedButton( + "Get Last Known Position", + visible=False if page.web else True, + on_click=handle_get_last_known_position, + ), + ft.OutlinedButton( + "Is Location Service Enabled", + on_click=handle_location_service_enabled, + ), + ft.OutlinedButton( + "Open Location Settings", + visible=False if page.web else True, + on_click=lambda e: page.open(location_settings_dlg), + ), + ft.OutlinedButton( + "Open App Settings", + visible=False if page.web else True, + on_click=lambda e: page.open(app_settings_dlg), + ), + ], + ) + ) + + +ft.app(main) diff --git a/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py b/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py index 1adc7760..fda26aca 100644 --- a/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py +++ b/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py @@ -1,45 +1,37 @@ -import flet -from flet import ( - Container, - DragUpdateEvent, - GestureDetector, - MouseCursor, - Page, - Stack, - colors, - ElevatedButton, - Text, -) - -def main(page: Page): - def on_pan_update(event: DragUpdateEvent): - container.top = max(0, container.top + event.delta_y) - container.left = max(0, container.left + event.delta_x) - container.update() - - gesture_detector = GestureDetector( - mouse_cursor=MouseCursor.BASIC, +import flet as ft + + +def main(page: ft.Page): + def on_pan_update(event: ft.DragUpdateEvent): + c.top = max(0, c.top + event.delta_y) + c.left = max(0, c.left + event.delta_x) + c.update() + + gd = ft.GestureDetector( + mouse_cursor=ft.MouseCursor.BASIC, drag_interval=50, on_pan_update=on_pan_update, ) - container = Container(gesture_detector, bgcolor=colors.AMBER, width=50, height=50, left=0, top=0) + c = ft.Container(gd, bgcolor=ft.Colors.AMBER, width=50, height=50, left=0, top=0) def change_icon(event): mouse_cursor = next(mouse_cursors) - gesture_detector.mouse_cursor = mouse_cursor - gesture_detector.update() - text.value = f"Mouse Cursor: {gesture_detector.mouse_cursor}" + gd.mouse_cursor = mouse_cursor + gd.update() + text.value = f"Mouse Cursor: {gd.mouse_cursor}" text.update() def mouse_cursor_generator(m_list): while True: for i in m_list: yield i - mouse_cursors = mouse_cursor_generator(list(MouseCursor)) - page.add(Stack([container], width=1000, height=500)) - page.add(ElevatedButton("Change mouse Cursor", on_click=change_icon)) - text = Text(f"Mouse Cursor: {gesture_detector.mouse_cursor}") + mouse_cursors = mouse_cursor_generator(list(ft.MouseCursor)) + + page.add(ft.Stack([c], width=1000, height=500)) + page.add(ft.ElevatedButton("Change mouse Cursor", on_click=change_icon)) + text = ft.Text(f"Mouse Cursor: {gd.mouse_cursor}") page.add(text) -flet.app(target=main) \ No newline at end of file + +ft.app(target=main) diff --git a/python/controls/utility/gesture-detector/gestures-tester.py b/python/controls/utility/gesture-detector/gestures-tester.py index 89af6c3c..b644f029 100644 --- a/python/controls/utility/gesture-detector/gestures-tester.py +++ b/python/controls/utility/gesture-detector/gestures-tester.py @@ -1,11 +1,10 @@ -import flet -from flet import Container, GestureDetector, Page, TapEvent, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): - gd = GestureDetector( - Container(bgcolor=colors.GREEN, width=200, height=200), + gd = ft.GestureDetector( + ft.Container(bgcolor=ft.colors.GREEN, width=200, height=200), hover_interval=50, on_tap=lambda e: print("TAP"), on_tap_down=lambda e: print( @@ -60,4 +59,4 @@ def main(page: Page): page.add(gd) -flet.app(target=main) +ft.app(target=main) From 088df89c7ba6e073066ba19ed1468afa39b742a4 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 27 Mar 2025 07:16:21 -0600 Subject: [PATCH 67/81] gesture-detector examples update --- ...y => draggable-container-change-cursor.py} | 0 .../gesture-detector/draggable-containers.py | 37 +++++++------------ 2 files changed, 14 insertions(+), 23 deletions(-) rename python/controls/utility/gesture-detector/{draggable-container_change_mouse_cursor.py => draggable-container-change-cursor.py} (100%) diff --git a/python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py b/python/controls/utility/gesture-detector/draggable-container-change-cursor.py similarity index 100% rename from python/controls/utility/gesture-detector/draggable-container_change_mouse_cursor.py rename to python/controls/utility/gesture-detector/draggable-container-change-cursor.py diff --git a/python/controls/utility/gesture-detector/draggable-containers.py b/python/controls/utility/gesture-detector/draggable-containers.py index 1c95cb1b..7128ab45 100644 --- a/python/controls/utility/gesture-detector/draggable-containers.py +++ b/python/controls/utility/gesture-detector/draggable-containers.py @@ -1,44 +1,35 @@ -import flet -from flet import ( - Container, - DragUpdateEvent, - GestureDetector, - MouseCursor, - Page, - Stack, - colors, -) - - -def main(page: Page): - def on_pan_update1(e: DragUpdateEvent): +import flet as ft + + +def main(page: ft.Page): + def on_pan_update1(e: ft.DragUpdateEvent): c.top = max(0, c.top + e.delta_y) c.left = max(0, c.left + e.delta_x) c.update() - def on_pan_update2(e: DragUpdateEvent): + def on_pan_update2(e: ft.DragUpdateEvent): e.control.top = max(0, e.control.top + e.delta_y) e.control.left = max(0, e.control.left + e.delta_x) e.control.update() - gd = GestureDetector( - mouse_cursor=MouseCursor.MOVE, + gd = ft.GestureDetector( + mouse_cursor=ft.MouseCursor.MOVE, drag_interval=50, on_pan_update=on_pan_update1, ) - c = Container(gd, bgcolor=colors.AMBER, width=50, height=50, left=0, top=0) + c = ft.Container(gd, bgcolor=ft.Colors.AMBER, width=50, height=50, left=0, top=0) - gd1 = GestureDetector( - mouse_cursor=MouseCursor.MOVE, + gd1 = ft.GestureDetector( + mouse_cursor=ft.MouseCursor.MOVE, drag_interval=10, on_vertical_drag_update=on_pan_update2, left=100, top=100, - content=Container(bgcolor=colors.BLUE, width=50, height=50), + content=ft.Container(bgcolor=ft.Colors.BLUE, width=50, height=50), ) - page.add(Stack([c, gd1], width=1000, height=500)) + page.add(ft.Stack([c, gd1], width=1000, height=500)) -flet.app(target=main) +ft.app(main) From 1a0a07e311be6cb4e9043f128a761fa682e91d03 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 27 Mar 2025 07:21:52 -0600 Subject: [PATCH 68/81] update icon example --- .../information-displays/icon/icons-example.py | 17 +++++++++++++++++ .../information-displays/icon/icons-test.py | 18 ------------------ 2 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 python/controls/information-displays/icon/icons-example.py delete mode 100644 python/controls/information-displays/icon/icons-test.py diff --git a/python/controls/information-displays/icon/icons-example.py b/python/controls/information-displays/icon/icons-example.py new file mode 100644 index 00000000..31ed71ce --- /dev/null +++ b/python/controls/information-displays/icon/icons-example.py @@ -0,0 +1,17 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.Row( + [ + ft.Icon(name=ft.Icons.FAVORITE, color=ft.Colors.PINK), + ft.Icon(name=ft.Icons.AUDIOTRACK, color=ft.Colors.GREEN_400, size=30), + ft.Icon(name=ft.Icons.BEACH_ACCESS, color=ft.Colors.BLUE, size=50), + ft.Icon(name="settings", color="#c1c1c1"), + ] + ) + ) + + +ft.app(main) diff --git a/python/controls/information-displays/icon/icons-test.py b/python/controls/information-displays/icon/icons-test.py deleted file mode 100644 index b0cbdfe7..00000000 --- a/python/controls/information-displays/icon/icons-test.py +++ /dev/null @@ -1,18 +0,0 @@ -import flet -from flet import Icon, Page, Row, colors, icons - - -def main(page: Page): - page.add( - Row( - [ - Icon(name=icons.FAVORITE, color=colors.PINK), - Icon(name=icons.AUDIOTRACK, color=colors.GREEN_400, size=30), - Icon(name=icons.BEACH_ACCESS, color=colors.BLUE, size=50), - Icon(name="settings", color="#c1c1c1"), - ] - ) - ) - - -flet.app(target=main) From 41ec0ab8887f9fd385ae315ff0572eacfcf45ddf Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 29 Mar 2025 17:17:21 -0700 Subject: [PATCH 69/81] update utility control examples --- .../controls/animations/animate-rotation.py | 4 +- .../controls/animations/animate-scale-docs.py | 2 +- .../animations/animate-single-container.py | 4 +- .../animate-image-switch-buffered.py | 0 .../animate-image-switch.py | 0 .../animated-switcher.py | 0 python/controls/animations/image-slideshow.py | 5 +- .../animations/{ => lottie}/lottie-basic.py | 3 +- .../animations/{ => rive}/rive-basic.py | 0 python/controls/animations/rocket.py | 3 +- .../haptic-feedback-example.py | 16 ++ .../interactive-viewer-example.py | 20 +++ .../permission-handler-example.py | 40 +++++ .../selection-area/selection-area-example.py | 27 ++++ .../shader-mask/shader-mask-gradient.py | 7 +- .../utility/shader-mask/shader-mask-image.py | 50 +++--- .../shader-mask/shader-mask-single-image.py | 21 ++- .../shake-detector/shake-detector-example.py | 16 ++ .../transparent-pointer-example.py | 23 +++ .../controls/utility/video/video-example.py | 142 ++++++++++++++++++ .../window-drag-area/no-frame-window.py | 23 ++- 21 files changed, 343 insertions(+), 63 deletions(-) rename python/controls/animations/{ => animated-switcher}/animate-image-switch-buffered.py (100%) rename python/controls/animations/{ => animated-switcher}/animate-image-switch.py (100%) rename python/controls/animations/{ => animated-switcher}/animated-switcher.py (100%) rename python/controls/animations/{ => lottie}/lottie-basic.py (88%) rename python/controls/animations/{ => rive}/rive-basic.py (100%) create mode 100644 python/controls/utility/haptic-feedback/haptic-feedback-example.py create mode 100644 python/controls/utility/interactive-viewer/interactive-viewer-example.py create mode 100644 python/controls/utility/permission-handler/permission-handler-example.py create mode 100644 python/controls/utility/selection-area/selection-area-example.py create mode 100644 python/controls/utility/shake-detector/shake-detector-example.py create mode 100644 python/controls/utility/transparent-pointer/transparent-pointer-example.py create mode 100644 python/controls/utility/video/video-example.py diff --git a/python/controls/animations/animate-rotation.py b/python/controls/animations/animate-rotation.py index 231b2a7b..fbae5841 100644 --- a/python/controls/animations/animate-rotation.py +++ b/python/controls/animations/animate-rotation.py @@ -8,7 +8,7 @@ def main(page: ft.Page): height=100, left=200, top=100, - bgcolor="red", + bgcolor=ft.Colors.RED, border_radius=5, rotate=1, animate_rotation=1000, @@ -17,7 +17,7 @@ def main(page: ft.Page): c2 = ft.Container( width=100, height=70, - bgcolor="blue", + bgcolor=ft.Colors.BLUE, border_radius=5, rotate=ft.transform.Rotate(-1, alignment=ft.alignment.center_left), animate_rotation=ft.animation.Animation(duration=300), diff --git a/python/controls/animations/animate-scale-docs.py b/python/controls/animations/animate-scale-docs.py index 9fa8d297..65562120 100644 --- a/python/controls/animations/animate-scale-docs.py +++ b/python/controls/animations/animate-scale-docs.py @@ -6,7 +6,7 @@ def main(page: ft.Page): c = ft.Container( width=100, height=100, - bgcolor="blue", + bgcolor=ft.Colors.BLUE, border_radius=5, scale=1, animate_scale=ft.animation.Animation(600, ft.AnimationCurve.BOUNCE_OUT), diff --git a/python/controls/animations/animate-single-container.py b/python/controls/animations/animate-single-container.py index 7dc4fa8d..4c739785 100644 --- a/python/controls/animations/animate-single-container.py +++ b/python/controls/animations/animate-single-container.py @@ -6,14 +6,14 @@ def main(page: ft.Page): c = ft.Container( width=150, height=150, - bgcolor="red", + bgcolor=ft.Colors.RED, animate=ft.animation.Animation(1000, ft.AnimationCurve.BOUNCE_OUT), ) def animate_container(e): c.width = 100 if c.width == 150 else 150 c.height = 50 if c.height == 150 else 150 - c.bgcolor = "blue" if c.bgcolor == "red" else "red" + c.bgcolor = ft.Colors.BLUE if c.bgcolor == ft.Colors.RED else ft.Colors.RED c.update() page.add(c, ft.ElevatedButton("Animate container", on_click=animate_container)) diff --git a/python/controls/animations/animate-image-switch-buffered.py b/python/controls/animations/animated-switcher/animate-image-switch-buffered.py similarity index 100% rename from python/controls/animations/animate-image-switch-buffered.py rename to python/controls/animations/animated-switcher/animate-image-switch-buffered.py diff --git a/python/controls/animations/animate-image-switch.py b/python/controls/animations/animated-switcher/animate-image-switch.py similarity index 100% rename from python/controls/animations/animate-image-switch.py rename to python/controls/animations/animated-switcher/animate-image-switch.py diff --git a/python/controls/animations/animated-switcher.py b/python/controls/animations/animated-switcher/animated-switcher.py similarity index 100% rename from python/controls/animations/animated-switcher.py rename to python/controls/animations/animated-switcher/animated-switcher.py diff --git a/python/controls/animations/image-slideshow.py b/python/controls/animations/image-slideshow.py index 8b6531ef..e71bf58a 100644 --- a/python/controls/animations/image-slideshow.py +++ b/python/controls/animations/image-slideshow.py @@ -21,10 +21,7 @@ def animate(e): page.add( ft.Stack( - [ - i1, - i2, - ], + [i1, i2], width=200, height=300, ), diff --git a/python/controls/animations/lottie-basic.py b/python/controls/animations/lottie/lottie-basic.py similarity index 88% rename from python/controls/animations/lottie-basic.py rename to python/controls/animations/lottie/lottie-basic.py index 5f0716a0..9711ffb6 100644 --- a/python/controls/animations/lottie-basic.py +++ b/python/controls/animations/lottie/lottie-basic.py @@ -1,8 +1,9 @@ import flet as ft +import flet_lottie as fl def main(page: ft.Page): - l = ft.Lottie( + l = fl.Lottie( src="https://raw.githubusercontent.com/xvrh/lottie-flutter/refs/heads/master/example/assets/Logo/LogoSmall.json", reverse=False, animate=True, diff --git a/python/controls/animations/rive-basic.py b/python/controls/animations/rive/rive-basic.py similarity index 100% rename from python/controls/animations/rive-basic.py rename to python/controls/animations/rive/rive-basic.py diff --git a/python/controls/animations/rocket.py b/python/controls/animations/rocket.py index bf72e682..56d64850 100644 --- a/python/controls/animations/rocket.py +++ b/python/controls/animations/rocket.py @@ -1,5 +1,4 @@ from math import pi - import flet as ft @@ -7,7 +6,7 @@ def main(page: ft.Page): c2 = ft.Container( content=ft.Container( - ft.Icon(ft.Icons.ROCKET, size=40, color="black"), + ft.Icon(ft.Icons.ROCKET, size=40, color=ft.Colors.BLACK), scale=1.0, animate_scale=1000, opacity=1.0, diff --git a/python/controls/utility/haptic-feedback/haptic-feedback-example.py b/python/controls/utility/haptic-feedback/haptic-feedback-example.py new file mode 100644 index 00000000..a0886c26 --- /dev/null +++ b/python/controls/utility/haptic-feedback/haptic-feedback-example.py @@ -0,0 +1,16 @@ +import flet as ft + + +def main(page: ft.Page): + hf = ft.HapticFeedback() + page.overlay.append(hf) + + page.add( + ft.ElevatedButton("Heavy impact", on_click=lambda _: hf.heavy_impact()), + ft.ElevatedButton("Medium impact", on_click=lambda _: hf.medium_impact()), + ft.ElevatedButton("Light impact", on_click=lambda _: hf.light_impact()), + ft.ElevatedButton("Vibrate", on_click=lambda _: hf.vibrate()), + ) + + +ft.app(main) diff --git a/python/controls/utility/interactive-viewer/interactive-viewer-example.py b/python/controls/utility/interactive-viewer/interactive-viewer-example.py new file mode 100644 index 00000000..764b0db3 --- /dev/null +++ b/python/controls/utility/interactive-viewer/interactive-viewer-example.py @@ -0,0 +1,20 @@ +import flet as ft + + +def main(page: ft.Page): + page.add( + ft.InteractiveViewer( + min_scale=0.1, + max_scale=15, + boundary_margin=ft.margin.all(20), + on_interaction_start=lambda e: print(e), + on_interaction_end=lambda e: print(e), + on_interaction_update=lambda e: print(e), + content=ft.Image( + src="https://picsum.photos/500/500", + ), + ) + ) + + +ft.app(main) diff --git a/python/controls/utility/permission-handler/permission-handler-example.py b/python/controls/utility/permission-handler/permission-handler-example.py new file mode 100644 index 00000000..fdd7133e --- /dev/null +++ b/python/controls/utility/permission-handler/permission-handler-example.py @@ -0,0 +1,40 @@ +import flet as ft + + +def main(page: ft.Page): + page.scroll = ft.ScrollMode.ADAPTIVE + page.appbar = ft.AppBar(title=ft.Text("PermissionHandler Tests")) + ph = ft.PermissionHandler() + page.overlay.append(ph) + + def check_permission(e): + o = ph.check_permission(e.control.data) + page.add(ft.Text(f"Checked {e.control.data.name}: {o}")) + + def request_permission(e): + o = ph.request_permission(e.control.data) + page.add(ft.Text(f"Requested {e.control.data.name}: {o}")) + + def open_app_settings(e): + o = ph.open_app_settings() + page.add(ft.Text(f"App Settings: {o}")) + + page.add( + ft.OutlinedButton( + "Check Microphone Permission", + data=ft.PermissionType.MICROPHONE, + on_click=check_permission, + ), + ft.OutlinedButton( + "Request Microphone Permission", + data=ft.PermissionType.MICROPHONE, + on_click=request_permission, + ), + ft.OutlinedButton( + "Open App Settings", + on_click=open_app_settings, + ), + ) + + +ft.app(main) diff --git a/python/controls/utility/selection-area/selection-area-example.py b/python/controls/utility/selection-area/selection-area-example.py new file mode 100644 index 00000000..c11d8259 --- /dev/null +++ b/python/controls/utility/selection-area/selection-area-example.py @@ -0,0 +1,27 @@ +import flet as ft + + +def main(page: ft.Page): + ts = ft.TextStyle( + size=22, + weight=ft.FontWeight.W_600, + decoration=ft.TextDecoration( + ft.TextDecoration.UNDERLINE | ft.TextDecoration.OVERLINE + ), + decoration_style=ft.TextDecorationStyle(ft.TextDecorationStyle.WAVY), + ) + + page.add( + ft.SelectionArea( + content=ft.Column( + [ + ft.Text("Selectable text", color=ft.Colors.GREEN, style=ts), + ft.Text("Also selectable", color=ft.Colors.GREEN, style=ts), + ] + ) + ) + ) + page.add(ft.Text("Not selectable", color=ft.Colors.RED, style=ts)) + + +ft.app(main) diff --git a/python/controls/utility/shader-mask/shader-mask-gradient.py b/python/controls/utility/shader-mask/shader-mask-gradient.py index bb9676a2..b8e42841 100644 --- a/python/controls/utility/shader-mask/shader-mask-gradient.py +++ b/python/controls/utility/shader-mask/shader-mask-gradient.py @@ -1,16 +1,17 @@ import flet as ft + def main(page: ft.Page): page.add( ft.Row( [ ft.ShaderMask( - content=ft.Image(src="https://picsum.photos/100/200?2"), + content=ft.Image(src="https://picsum.photos/200/200?2"), blend_mode=ft.BlendMode.DST_IN, shader=ft.LinearGradient( begin=ft.alignment.top_center, end=ft.alignment.bottom_center, - colors=[ft.colors.BLACK, ft.colors.TRANSPARENT], + colors=[ft.Colors.BLACK, ft.Colors.TRANSPARENT], stops=[0.5, 1.0], ), border_radius=10, @@ -19,5 +20,5 @@ def main(page: ft.Page): ) ) -ft.app(target=main) +ft.app(main) diff --git a/python/controls/utility/shader-mask/shader-mask-image.py b/python/controls/utility/shader-mask/shader-mask-image.py index f9e164d4..d07fd06a 100644 --- a/python/controls/utility/shader-mask/shader-mask-image.py +++ b/python/controls/utility/shader-mask/shader-mask-image.py @@ -1,41 +1,32 @@ -import flet -from flet import ( - Image, - LinearGradient, - Page, - RadialGradient, - Row, - ShaderMask, - alignment, - colors, -) +import flet as ft -def main(page: Page): + +def main(page: ft.Page): page.add( - Row( + ft.Row( [ - ShaderMask( - content=Image( + ft.ShaderMask( + content=ft.Image( src="https://picsum.photos/200/300?1", width=400, height=400, - fit="fill", + fit=ft.ImageFit.FILL, ), - blend_mode="colorBurn", - shader=RadialGradient( - center=alignment.top_left, + blend_mode=ft.BlendMode.COLOR_BURN, + shader=ft.RadialGradient( + center=ft.alignment.top_left, radius=1.0, - colors=[colors.YELLOW, colors.DEEP_ORANGE_900], - tile_mode="clamp", + colors=[ft.Colors.YELLOW, ft.Colors.DEEP_ORANGE_900], + tile_mode=ft.GradientTileMode.CLAMP, ), ), - ShaderMask( - content=Image(src="https://picsum.photos/200/300?2"), - blend_mode="dstIn", - shader=LinearGradient( - begin=alignment.top_center, - end=alignment.bottom_center, - colors=[colors.BLACK, colors.TRANSPARENT], + ft.ShaderMask( + content=ft.Image(src="https://picsum.photos/200/300?2"), + blend_mode=ft.BlendMode.DST_IN, + shader=ft.LinearGradient( + begin=ft.alignment.top_center, + end=ft.alignment.bottom_center, + colors=[ft.Colors.BLACK, ft.Colors.TRANSPARENT], stops=[0.5, 1.0], ), ), @@ -43,4 +34,5 @@ def main(page: Page): ) ) -flet.app(target=main) + +ft.app(target=main) diff --git a/python/controls/utility/shader-mask/shader-mask-single-image.py b/python/controls/utility/shader-mask/shader-mask-single-image.py index 351dd4dc..111763a1 100644 --- a/python/controls/utility/shader-mask/shader-mask-single-image.py +++ b/python/controls/utility/shader-mask/shader-mask-single-image.py @@ -1,27 +1,34 @@ import flet as ft + def main(page: ft.Page): page.add( ft.Row( [ + ft.Image( + src="https://picsum.photos/300/300?1", + width=300, + height=300, + fit=ft.ImageFit.FILL, + ), ft.ShaderMask( content=ft.Image( - src="https://picsum.photos/200/200?1", - width=200, - height=200, + src="https://picsum.photos/300/300?1", + width=300, + height=300, fit=ft.ImageFit.FILL, ), blend_mode=ft.BlendMode.MULTIPLY, shader=ft.RadialGradient( center=ft.alignment.center, - radius=2.0, - colors=[ft.colors.WHITE, ft.colors.PINK], + radius=0.5, + colors=[ft.Colors.WHITE, ft.Colors.PINK], tile_mode=ft.GradientTileMode.CLAMP, ), - ) + ), ] ) ) -ft.app(target=main) +ft.app(target=main) diff --git a/python/controls/utility/shake-detector/shake-detector-example.py b/python/controls/utility/shake-detector/shake-detector-example.py new file mode 100644 index 00000000..5b97bdf4 --- /dev/null +++ b/python/controls/utility/shake-detector/shake-detector-example.py @@ -0,0 +1,16 @@ +import flet as ft + + +def main(page: ft.Page): + shd = ft.ShakeDetector( + minimum_shake_count=2, + shake_slop_time_ms=300, + shake_count_reset_time_ms=1000, + on_shake=lambda _: print("SHAKE DETECTED!"), + ) + page.overlay.append(shd) + + page.add(ft.Text("Program body")) + + +ft.app(main) diff --git a/python/controls/utility/transparent-pointer/transparent-pointer-example.py b/python/controls/utility/transparent-pointer/transparent-pointer-example.py new file mode 100644 index 00000000..e3855115 --- /dev/null +++ b/python/controls/utility/transparent-pointer/transparent-pointer-example.py @@ -0,0 +1,23 @@ +import flet as ft + + +def main(page): + page.add( + ft.Stack( + [ + ft.GestureDetector( + on_tap=lambda _: print("TAP!"), + multi_tap_touches=3, + on_multi_tap=lambda e: print("MULTI TAP:", e.correct_touches), + on_multi_long_press=lambda _: print("Multi tap long press"), + ), + ft.TransparentPointer( + ft.Container(ft.ElevatedButton("Test button"), padding=50) + ), + ], + expand=True, + ) + ) + + +ft.app(main) diff --git a/python/controls/utility/video/video-example.py b/python/controls/utility/video/video-example.py new file mode 100644 index 00000000..ffbcafd2 --- /dev/null +++ b/python/controls/utility/video/video-example.py @@ -0,0 +1,142 @@ +import random +import flet as ft +import flet_video as fv + + +def main(page: ft.Page): + page.theme_mode = ft.ThemeMode.LIGHT + page.title = "TheEthicalVideo" + page.window.always_on_top = True + page.spacing = 20 + page.horizontal_alignment = ft.CrossAxisAlignment.CENTER + + def handle_pause(e): + video.pause() + print("Video.pause()") + + def handle_play_or_pause(e): + video.play_or_pause() + print("Video.play_or_pause()") + + def handle_play(e): + video.play() + print("Video.play()") + + def handle_stop(e): + video.stop() + print("Video.stop()") + + def handle_next(e): + video.next() + print("Video.next()") + + def handle_previous(e): + video.previous() + print("Video.previous()") + + def handle_volume_change(e): + video.volume = e.control.value + page.update() + print(f"Video.volume = {e.control.value}") + + def handle_playback_rate_change(e): + video.playback_rate = e.control.value + page.update() + print(f"Video.playback_rate = {e.control.value}") + + def handle_seek(e): + video.seek(10000) + print(f"Video.seek(10000)") + + def handle_add_media(e): + video.playlist_add(random.choice(sample_media)) + print(f"Video.playlist_add(random.choice(sample_media))") + + def handle_remove_media(e): + r = random.randint(0, len(video.playlist) - 1) + video.playlist_remove(r) + print(f"Popped Item at index: {r} (position {r+1})") + + def handle_jump(e): + print(f"Video.jump_to(0)") + video.jump_to(0) + + sample_media = [ + fv.VideoMedia( + "https://user-images.githubusercontent.com/28951144/229373720-14d69157-1a56-4a78-a2f4-d7a134d7c3e9.mp4" + ), + fv.VideoMedia( + "https://user-images.githubusercontent.com/28951144/229373718-86ce5e1d-d195-45d5-baa6-ef94041d0b90.mp4" + ), + fv.VideoMedia( + "https://user-images.githubusercontent.com/28951144/229373716-76da0a4e-225a-44e4-9ee7-3e9006dbc3e3.mp4" + ), + fv.VideoMedia( + "https://user-images.githubusercontent.com/28951144/229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4" + ), + fv.VideoMedia( + "https://user-images.githubusercontent.com/28951144/229373709-603a7a89-2105-4e1b-a5a5-a6c3567c9a59.mp4", + extras={ + "artist": "Thousand Foot Krutch", + "album": "The End Is Where We Begin", + }, + http_headers={ + "Foo": "Bar", + "Accept": "*/*", + }, + ), + ] + + page.add( + video := fv.Video( + expand=True, + playlist=sample_media[0:2], + playlist_mode=fv.PlaylistMode.LOOP, + fill_color=ft.Colors.BLUE_400, + aspect_ratio=16 / 9, + volume=100, + autoplay=False, + filter_quality=ft.FilterQuality.HIGH, + muted=False, + on_loaded=lambda e: print("Video loaded successfully!"), + on_enter_fullscreen=lambda e: print("Video entered fullscreen!"), + on_exit_fullscreen=lambda e: print("Video exited fullscreen!"), + ), + ft.Row( + wrap=True, + alignment=ft.MainAxisAlignment.CENTER, + controls=[ + ft.ElevatedButton("Play", on_click=handle_play), + ft.ElevatedButton("Pause", on_click=handle_pause), + ft.ElevatedButton("Play Or Pause", on_click=handle_play_or_pause), + ft.ElevatedButton("Stop", on_click=handle_stop), + ft.ElevatedButton("Next", on_click=handle_next), + ft.ElevatedButton("Previous", on_click=handle_previous), + ft.ElevatedButton("Seek s=10", on_click=handle_seek), + ft.ElevatedButton("Jump to first Media", on_click=handle_jump), + ft.ElevatedButton("Add Random Media", on_click=handle_add_media), + ft.ElevatedButton("Remove Random Media", on_click=handle_remove_media), + ], + ), + ft.Slider( + min=0, + value=100, + max=100, + label="Volume = {value}%", + divisions=10, + width=400, + on_change=handle_volume_change, + ), + ft.Slider( + min=1, + value=1, + max=3, + label="PlaybackRate = {value}X", + divisions=6, + width=400, + on_change=handle_playback_rate_change, + ), + ) + + +ft.app(main) diff --git a/python/controls/utility/window-drag-area/no-frame-window.py b/python/controls/utility/window-drag-area/no-frame-window.py index c2b34323..c6f07595 100644 --- a/python/controls/utility/window-drag-area/no-frame-window.py +++ b/python/controls/utility/window-drag-area/no-frame-window.py @@ -1,28 +1,27 @@ -import flet -from flet import Container, IconButton, Page, Row, Text, WindowDragArea, colors, icons +import flet as ft -def main(page: Page): - page.window_title_bar_hidden = True - page.window_title_bar_buttons_hidden = True +def main(page: ft.Page): + page.window.title_bar_hidden = True + page.window.title_bar_buttons_hidden = True page.add( - Row( + ft.Row( [ - WindowDragArea( - Container( - Text( + ft.WindowDragArea( + ft.Container( + ft.Text( "Drag this area to move, maximize and restore application window." ), - bgcolor=colors.AMBER_300, + bgcolor=ft.Colors.AMBER_300, padding=10, ), expand=True, ), - IconButton(icons.CLOSE, on_click=lambda _: page.window_close()), + ft.IconButton(ft.Icons.CLOSE, on_click=lambda _: page.window.close()), ] ) ) -flet.app(target=main) +ft.app(main) From 0c1aae06e1cc2a6c6b585af7af03765571c876f3 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 29 Mar 2025 23:18:50 -0700 Subject: [PATCH 70/81] fix audio player example --- python/controls/utility/audio/audio-player.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/python/controls/utility/audio/audio-player.py b/python/controls/utility/audio/audio-player.py index a5c5642e..15f35e81 100644 --- a/python/controls/utility/audio/audio-player.py +++ b/python/controls/utility/audio/audio-player.py @@ -1,11 +1,8 @@ import flet as ft +import flet_audio as fa url = "https://github.com/mdn/webaudio-examples/blob/main/audio-basics/outfoxing.mp3?raw=true" -# url = "https://github.com/mdn/webaudio-examples/blob/main/audio-analyser/viper.mp3?raw=true" -# url = "https://luan.xyz/files/audio/ambient_c_motion.mp3" -# url = "https://luan.xyz/files/audio/coins.wav" -# url = "https://luan.xyz/files/audio/laser.wav" def main(page: ft.Page): @@ -46,7 +43,7 @@ def get_duration(_): def get_position(_): print("Current position:", audio1.get_current_position()) - audio1 = ft.Audio( + audio1 = fa.Audio( src=url, autoplay=False, volume=1, From ccf7af2ff0a4fec44a495577e4fa38ec514ebe11 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 29 Mar 2025 23:54:18 -0700 Subject: [PATCH 71/81] update image and circle-avatar examples --- .../circle-avatar/avatar-test.py | 43 +++++++++---------- .../image/custom-svg-animation.py | 10 ++--- .../image/image-base64.py | 9 ++-- .../information-displays/image/images.py | 35 --------------- .../information-displays/image/svg-image.py | 23 ++++------ .../information-displays/image/svg-lucide.py | 16 +++---- 6 files changed, 47 insertions(+), 89 deletions(-) delete mode 100644 python/controls/information-displays/image/images.py diff --git a/python/controls/information-displays/circle-avatar/avatar-test.py b/python/controls/information-displays/circle-avatar/avatar-test.py index 7460c859..6793e1a3 100644 --- a/python/controls/information-displays/circle-avatar/avatar-test.py +++ b/python/controls/information-displays/circle-avatar/avatar-test.py @@ -1,37 +1,36 @@ -import flet -from flet import CircleAvatar, Container, Icon, Stack, Text, alignment, colors, icons +import flet as ft def main(page): # a "normal" avatar with background image - a1 = CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/5041459?s=88&v=4", - content=Text("FF"), + a1 = ft.CircleAvatar( + foreground_image_src="https://avatars.githubusercontent.com/u/5041459?s=88&v=4", + content=ft.Text("FF"), ) - # avatar with failing foregroung image and fallback text - a2 = CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/_5041459?s=88&v=4", - content=Text("FF"), + # avatar with failing foreground image and fallback text + a2 = ft.CircleAvatar( + 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 - a3 = CircleAvatar( - content=Icon(icons.ABC), + a3 = ft.CircleAvatar( + content=ft.Icon(ft.Icons.ABC), ) # avatar with icon and custom colors - a4 = CircleAvatar( - content=Icon(icons.WARNING_ROUNDED), - color=colors.YELLOW_200, - bgcolor=colors.AMBER_700, + a4 = ft.CircleAvatar( + content=ft.Icon(ft.Icons.WARNING_ROUNDED), + color=ft.Colors.YELLOW_200, + bgcolor=ft.Colors.AMBER_700, ) # avatar with online status - a5 = Stack( + a5 = ft.Stack( [ - CircleAvatar( - foreground_image_url="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" + ft.CircleAvatar( + foreground_image_src="https://avatars.githubusercontent.com/u/5041459?s=88&v=4" ), - Container( - content=CircleAvatar(bgcolor=colors.GREEN, radius=5), - alignment=alignment.bottom_left, + ft.Container( + content=ft.CircleAvatar(bgcolor=ft.Colors.GREEN, radius=5), + alignment=ft.alignment.bottom_left, ), ], width=40, @@ -40,4 +39,4 @@ def main(page): page.add(a1, a2, a3, a4, a5) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/information-displays/image/custom-svg-animation.py b/python/controls/information-displays/image/custom-svg-animation.py index 61efe9cd..7f6a965a 100644 --- a/python/controls/information-displays/image/custom-svg-animation.py +++ b/python/controls/information-displays/image/custom-svg-animation.py @@ -1,9 +1,8 @@ from time import sleep +import flet as ft -import flet -from flet import Container, Image, Page, colors -def main(page: Page): +def main(page: ft.Page): svg_content = """ @@ -12,7 +11,7 @@ def main(page: Page): """ - img = Image(src=svg_content.format(0, 0)) + img = ft.Image(src=svg_content.format(0, 0)) page.add(img) for c in range(0, 10): @@ -21,4 +20,5 @@ def main(page: Page): img.update() sleep(0.1) -flet.app(target=main) + +ft.app(target=main) diff --git a/python/controls/information-displays/image/image-base64.py b/python/controls/information-displays/image/image-base64.py index d6405e75..6c1ba8a6 100644 --- a/python/controls/information-displays/image/image-base64.py +++ b/python/controls/information-displays/image/image-base64.py @@ -1,13 +1,12 @@ -import flet -from flet import Image, Page +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.add( - Image( + ft.Image( src_base64="iVBORw0KGgoAAAANSUhEUgAAABkAAAAgCAYAAADnnNMGAAAACXBIWXMAAAORAAADkQFnq8zdAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAA6dJREFUSImllltoHFUYx3/fzOzm0lt23ZrQ1AQbtBehNpvQohgkBYVo410RwQctNE3Sh0IfiiBoIAjqi6TYrKnFy4O3oiiRavDJFi3mXomIBmOxNZe63ay52GR3Zj4f2sTEzmx3m//TYf7/c35zvgPnO6KqrESXqpq3muocAikv6m+/zytj3ejik1VN21G31YA9CgJ6xC+bMyQZPVCuarciPAMYC99V6Vw5pLbFSibHmlVoRVj9P3cmPBM8tSJI/M6mzabpfoAQ9fIF7WK4bd5vvuFnLGgy2vi0abg94A0AcJGvMq3hDxGRyar9r4F+iLAm0yIiRk8m37tctS1WsrIhhrI30+Srmg+J87OXUf3lWGS1q89dC6ltsSanxk4Aj2QBABii96300g87P/rtlrWr8l+vyDMfdlXSyyEikqxsiOUAQJCBhfHdXRfCq1LSsSlcWG+KBAGStvvrMkgiuv8lUc2mREukPwLUfHG+uTQv8Eown7VL3XlbBxYhf1c17hbVF3MDwA9bts280TnaU1YYqPby07aeFlUlHt27wSQ4CLo+F8AvoTCvHmyKF+ZbEb/M77P2LgvAwmrTHAHflN3KZxVbMC2jMFNOpgPnrMSOhvvFkMezXdwV4ePbtvHtxnJAMQ0j4JtVnO+eLb5oiSlt5HDbv7t1O90lpYCCCKbhfzW5kAIwUAazR0BlfII8Ow0I6uoVmI9MyAMwbMs8CExmDbk4zgu931MyO4OI4KrYflkRjOoTI+uM9d1vjotwKPu9QMk/sxzuO8POiVFcdZ1M2YBVsMEAKOqLvaPIe7mACuw0z/80SMH58SMplxlfiDhVi7dw2pltRhjKBQTQdrSja2KKTfE551NHuaZ0QVPvWYQUn31/Vm2nDvgjF4grVJx6suSvrvrSJ/6cSW2Oz9mf264uNrB806xZ1k/CZ49dUKgDEtlCROX2hfHpx8pGuuo3PpqYulw8fjndOp1yhgtNKRevJ1FyR2Ola+jXAjdnwTkZ6o896GdWdxDw7IxFg+0DpmXchTKSBWQnIuJn9u4j7dt+13UfHXEkXQOcuQ4kMhVtqsgUyPiQiPQfHw1NB2sRjmXKuTg1NwwBYLhtPtQX26eqTwGXPDOqvmcC4Hnwfrrad94GrVsOYTqUTkQY+iTlNe/6O1miSP/x0VB/+wMIDwHn/vtV1iQC4Xv95uUEWVCoL9Y5Z+gdovoyMHUFJHv88jmVy0vTuw7cZNv2YaA61Bfb7ZX5F8SaUv2xwZevAAAAAElFTkSuQmCC" ) ) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/information-displays/image/images.py b/python/controls/information-displays/image/images.py deleted file mode 100644 index ae1d86f8..00000000 --- a/python/controls/information-displays/image/images.py +++ /dev/null @@ -1,35 +0,0 @@ -import flet -from flet import Image, Page, Row, border_radius - - -def main(page: Page): - page.title = "Images Example" - page.theme_mode = "light" - page.padding = 50 - page.update() - - img = Image( - src=f"/icons/icon-512.png", - width=100, - height=100, - fit="contain", - ) - images = Row(expand=1, wrap=False, scroll="always") - - page.add(img, images) - - for i in range(0, 30): - images.controls.append( - Image( - src=f"https://picsum.photos/200/200?{i}", - width=200, - height=200, - fit="none", - repeat="noRepeat", - border_radius=border_radius.all(10), - ) - ) - page.update() - - -flet.app(target=main) diff --git a/python/controls/information-displays/image/svg-image.py b/python/controls/information-displays/image/svg-image.py index fc61e3e0..2b85c6ce 100644 --- a/python/controls/information-displays/image/svg-image.py +++ b/python/controls/information-displays/image/svg-image.py @@ -1,8 +1,7 @@ -import flet -from flet import Container, Image, Page, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): svg_content = """ @@ -26,23 +25,19 @@ def main(page: Page): """ page.add( - Image( + ft.Image( src=f"https://raw.githubusercontent.com/dnfield/flutter_svg/master/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg", width=200, height=200, ), - Image( - src=svg_content, - width=100, - height=100, - ), - Image(src=svg_content, width=100, height=100, color="blue"), - Container( - Image(src=svg_content, width=100, height=100, color="white"), - bgcolor=colors.BLACK87, + ft.Image(src=svg_content, width=100, height=100, color=ft.Colors.RED), + ft.Image(src=svg_content, width=100, height=100, color=ft.Colors.BLUE), + ft.Container( + ft.Image(src=svg_content, width=100, height=100, color=ft.Colors.WHITE), + bgcolor=ft.Colors.BLACK87, border_radius=5, ), ) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/information-displays/image/svg-lucide.py b/python/controls/information-displays/image/svg-lucide.py index 52655cd1..756969fb 100644 --- a/python/controls/information-displays/image/svg-lucide.py +++ b/python/controls/information-displays/image/svg-lucide.py @@ -1,5 +1,4 @@ -import flet -from flet import Image, Page +import flet as ft # Browse icons: # https://lucide.dev/ @@ -7,17 +6,18 @@ # Copy selected icon -def main(page: Page): +def main(page: ft.Page): page.add( - Image( - src='' + ft.Image( + src='', + color=ft.Colors.PINK, ), - Image( + ft.Image( src='', - color="green", + color=ft.Colors.GREEN, ), ) -flet.app(target=main) +ft.app(target=main) From 7159b1442113b8856b9a37c3fcc63fc5aaa51f42 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Sat, 29 Mar 2025 23:55:01 -0700 Subject: [PATCH 72/81] renames image example --- .../image/images-example.py | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 python/controls/information-displays/image/images-example.py diff --git a/python/controls/information-displays/image/images-example.py b/python/controls/information-displays/image/images-example.py new file mode 100644 index 00000000..9f10ccd8 --- /dev/null +++ b/python/controls/information-displays/image/images-example.py @@ -0,0 +1,34 @@ +import flet as ft + + +def main(page: ft.Page): + page.title = "Images Example" + page.theme_mode = ft.ThemeMode.LIGHT + page.padding = 50 + page.update() + + img = ft.Image( + src=f"/icons/icon-512.png", + width=100, + height=100, + fit=ft.ImageFit.CONTAIN, + ) + images = ft.Row(expand=1, wrap=False, scroll=ft.ScrollMode.ALWAYS) + + page.add(img, images) + + for i in range(0, 30): + images.controls.append( + ft.Image( + src=f"https://picsum.photos/200/200?{i}", + width=200, + height=200, + fit=ft.ImageFit.NONE, + repeat=ft.ImageRepeat.NO_REPEAT, + border_radius=ft.border_radius.all(10), + ) + ) + page.update() + + +ft.app(main) From a8e5e9d1b44dde50e422feaf50e762567e075199 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Mon, 31 Mar 2025 16:47:19 -0700 Subject: [PATCH 73/81] update chart examples --- .../barchart-example.py} | 22 +++++++------- .../barchart-with-event.py} | 12 ++++---- .../line-chart-example.py} | 29 +++++++++---------- .../line-chart-single-toggle.py} | 18 ++++++------ ...pl-barchart.py => mpl-barchart-example.py} | 7 ++--- .../charts/matplotlib-chart/mpl-contour.py | 7 ++--- .../charts/matplotlib-chart/mpl-finance.py | 14 +++++---- ...-linechart.py => mpl-linechart-example.py} | 7 ++--- .../charts/matplotlib-chart/mpl-scatter.py | 7 ++--- .../piechart-example.py} | 0 .../piechart-with-icons.py} | 26 ++++++++--------- .../piechart-with-titles.py} | 14 ++++----- .../charts/plotly-chart/plotly-barchart.py | 7 ++--- .../charts/plotly-chart/plotly-boxchart.py | 7 ++--- .../charts/plotly-chart/plotly-linechart.py | 7 ++--- .../charts/plotly-chart/plotly-piechart.py | 7 ++--- .../dropdown/dropdown-example.py | 2 +- 17 files changed, 92 insertions(+), 101 deletions(-) rename python/controls/charts/{barchart_sample-1.py => bar-chart/barchart-example.py} (80%) rename python/controls/charts/{barchart_sample-2.py => bar-chart/barchart-with-event.py} (97%) rename python/controls/charts/{linechart-sample-1.py => line-chart/line-chart-example.py} (85%) rename python/controls/charts/{linechart-sample-2.py => line-chart/line-chart-single-toggle.py} (86%) rename python/controls/charts/matplotlib-chart/{mpl-barchart.py => mpl-barchart-example.py} (88%) rename python/controls/charts/matplotlib-chart/{mpl-linechart.py => mpl-linechart-example.py} (91%) rename python/controls/charts/{piechart-sample-1.py => pie-chart/piechart-example.py} (100%) rename python/controls/charts/{piechart-sample-3.py => pie-chart/piechart-with-icons.py} (74%) rename python/controls/charts/{piechart-sample-2.py => pie-chart/piechart-with-titles.py} (83%) diff --git a/python/controls/charts/barchart_sample-1.py b/python/controls/charts/bar-chart/barchart-example.py similarity index 80% rename from python/controls/charts/barchart_sample-1.py rename to python/controls/charts/bar-chart/barchart-example.py index 700ebefe..416eab94 100644 --- a/python/controls/charts/barchart_sample-1.py +++ b/python/controls/charts/bar-chart/barchart-example.py @@ -11,8 +11,8 @@ def main(page: ft.Page): from_y=0, to_y=40, width=40, - color=ft.colors.GREEN, - tooltip="Apple", + color=ft.Colors.GREEN, + # tooltip="Apple", border_radius=0, ), ], @@ -24,8 +24,8 @@ def main(page: ft.Page): from_y=0, to_y=100, width=40, - color=ft.colors.BLUE, - tooltip="Blueberry", + color=ft.Colors.BLUE, + # tooltip="Blueberry", border_radius=0, ), ], @@ -37,8 +37,8 @@ def main(page: ft.Page): from_y=0, to_y=30, width=40, - color=ft.colors.RED, - tooltip="Cherry", + color=ft.Colors.RED, + # tooltip="Cherry", border_radius=0, ), ], @@ -50,14 +50,14 @@ def main(page: ft.Page): from_y=0, to_y=60, width=40, - color=ft.colors.ORANGE, - tooltip="Orange", + color=ft.Colors.ORANGE, + # tooltip="Orange", border_radius=0, ), ], ), ], - border=ft.border.all(1, ft.colors.GREY_400), + border=ft.border.all(1, ft.Colors.GREY_400), left_axis=ft.ChartAxis( labels_size=40, title=ft.Text("Fruit supply"), title_size=40 ), @@ -79,9 +79,9 @@ def main(page: ft.Page): labels_size=40, ), horizontal_grid_lines=ft.ChartGridLines( - color=ft.colors.GREY_300, width=1, dash_pattern=[3, 3] + color=ft.Colors.GREY_300, width=1, dash_pattern=[3, 3] ), - tooltip_bgcolor=ft.colors.with_opacity(0.5, ft.colors.GREY_300), + tooltip_bgcolor=ft.Colors.with_opacity(0.5, ft.Colors.GREY_300), max_y=110, interactive=True, expand=True, diff --git a/python/controls/charts/barchart_sample-2.py b/python/controls/charts/bar-chart/barchart-with-event.py similarity index 97% rename from python/controls/charts/barchart_sample-2.py rename to python/controls/charts/bar-chart/barchart-with-event.py index f919e19a..0ec0757f 100644 --- a/python/controls/charts/barchart_sample-2.py +++ b/python/controls/charts/bar-chart/barchart-with-event.py @@ -6,6 +6,11 @@ def __init__(self, y: float, hovered: bool = False): super().__init__() self.hovered = hovered self.y = y + # self.tooltip = f"{self.y}" + self.width = 22 + self.color = ft.Colors.WHITE + self.bg_to_y = 20 + self.bg_color = ft.Colors.GREEN_300 def before_update(self): self.to_y = self.y + 0.5 if self.hovered else self.y @@ -17,13 +22,6 @@ def before_update(self): ) super().before_update() - def build(self): - self.tooltip = str(self.y) - self.width = 22 - self.color = ft.Colors.WHITE - self.bg_to_y = 20 - self.bg_color = ft.Colors.GREEN_300 - def main(page: ft.Page): def on_chart_event(e: ft.BarChartEvent): diff --git a/python/controls/charts/linechart-sample-1.py b/python/controls/charts/line-chart/line-chart-example.py similarity index 85% rename from python/controls/charts/linechart-sample-1.py rename to python/controls/charts/line-chart/line-chart-example.py index 467c14f4..da09aa44 100644 --- a/python/controls/charts/linechart-sample-1.py +++ b/python/controls/charts/line-chart/line-chart-example.py @@ -21,7 +21,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(13, 1.8), ], stroke_width=8, - color=ft.colors.LIGHT_GREEN, + color=ft.Colors.LIGHT_GREEN, curved=True, stroke_cap_round=True, ), @@ -34,8 +34,8 @@ def main(page: ft.Page): ft.LineChartDataPoint(12, 2.6), ft.LineChartDataPoint(13, 3.9), ], - color=ft.colors.PINK, - below_line_bgcolor=ft.colors.with_opacity(0, ft.colors.PINK), + color=ft.Colors.PINK, + below_line_bgcolor=ft.Colors.with_opacity(0, ft.Colors.PINK), stroke_width=8, curved=True, stroke_cap_round=True, @@ -48,7 +48,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(10, 1.3), ft.LineChartDataPoint(13, 2.5), ], - color=ft.colors.CYAN, + color=ft.Colors.CYAN, stroke_width=8, curved=True, stroke_cap_round=True, @@ -67,7 +67,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(13, 1.8), ], stroke_width=4, - color=ft.colors.with_opacity(0.5, ft.colors.LIGHT_GREEN), + color=ft.Colors.with_opacity(0.5, ft.Colors.LIGHT_GREEN), stroke_cap_round=True, ), ft.LineChartData( @@ -79,8 +79,8 @@ def main(page: ft.Page): ft.LineChartDataPoint(12, 2.6), ft.LineChartDataPoint(13, 3.9), ], - color=ft.colors.with_opacity(0.5, ft.colors.PINK), - below_line_bgcolor=ft.colors.with_opacity(0.2, ft.colors.PINK), + color=ft.Colors.with_opacity(0.5, ft.Colors.PINK), + below_line_bgcolor=ft.Colors.with_opacity(0.2, ft.Colors.PINK), stroke_width=4, curved=True, stroke_cap_round=True, @@ -93,7 +93,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(10, 3.3), ft.LineChartDataPoint(13, 4.5), ], - color=ft.colors.with_opacity(0.5, ft.colors.CYAN), + color=ft.Colors.with_opacity(0.5, ft.Colors.CYAN), stroke_width=4, stroke_cap_round=True, ), @@ -102,7 +102,7 @@ def main(page: ft.Page): chart = ft.LineChart( data_series=data_1, border=ft.Border( - bottom=ft.BorderSide(4, ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE)) + bottom=ft.BorderSide(4, ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE)) ), left_axis=ft.ChartAxis( labels=[ @@ -142,7 +142,7 @@ def main(page: ft.Page): "SEP", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -154,7 +154,7 @@ def main(page: ft.Page): "OCT", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -166,7 +166,7 @@ def main(page: ft.Page): "DEC", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -174,7 +174,7 @@ def main(page: ft.Page): ], labels_size=32, ), - tooltip_bgcolor=ft.colors.with_opacity(0.8, ft.colors.BLUE_GREY), + tooltip_bgcolor=ft.Colors.with_opacity(0.8, ft.Colors.BLUE_GREY), min_y=0, max_y=4, min_x=0, @@ -196,8 +196,7 @@ def toggle_data(e): s.toggle = not s.toggle chart.update() - # page.theme_mode = ft.ThemeMode.DARK - page.add(ft.IconButton(ft.icons.REFRESH, on_click=toggle_data), chart) + page.add(ft.IconButton(ft.Icons.REFRESH, on_click=toggle_data), chart) ft.app(main) diff --git a/python/controls/charts/linechart-sample-2.py b/python/controls/charts/line-chart/line-chart-single-toggle.py similarity index 86% rename from python/controls/charts/linechart-sample-2.py rename to python/controls/charts/line-chart/line-chart-single-toggle.py index 14a91d05..40d0c131 100644 --- a/python/controls/charts/linechart-sample-2.py +++ b/python/controls/charts/line-chart/line-chart-single-toggle.py @@ -21,7 +21,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(11, 4), ], stroke_width=5, - color=ft.colors.CYAN, + color=ft.Colors.CYAN, curved=True, stroke_cap_round=True, ) @@ -39,7 +39,7 @@ def main(page: ft.Page): ft.LineChartDataPoint(11, 3.44), ], stroke_width=5, - color=ft.colors.CYAN, + color=ft.Colors.CYAN, curved=True, stroke_cap_round=True, ) @@ -47,12 +47,12 @@ def main(page: ft.Page): chart = ft.LineChart( data_series=data_1, - border=ft.border.all(3, ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE)), + border=ft.border.all(3, ft.Colors.with_opacity(0.2, ft.Colors.ON_SURFACE)), horizontal_grid_lines=ft.ChartGridLines( - interval=1, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1 + interval=1, color=ft.Colors.with_opacity(0.2, ft.Colors.ON_SURFACE), width=1 ), vertical_grid_lines=ft.ChartGridLines( - interval=1, color=ft.colors.with_opacity(0.2, ft.colors.ON_SURFACE), width=1 + interval=1, color=ft.Colors.with_opacity(0.2, ft.Colors.ON_SURFACE), width=1 ), left_axis=ft.ChartAxis( labels=[ @@ -80,7 +80,7 @@ def main(page: ft.Page): "MAR", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -92,7 +92,7 @@ def main(page: ft.Page): "JUN", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -104,7 +104,7 @@ def main(page: ft.Page): "SEP", size=16, weight=ft.FontWeight.BOLD, - color=ft.colors.with_opacity(0.5, ft.colors.ON_SURFACE), + color=ft.Colors.with_opacity(0.5, ft.Colors.ON_SURFACE), ), margin=ft.margin.only(top=10), ), @@ -112,7 +112,7 @@ def main(page: ft.Page): ], labels_size=32, ), - tooltip_bgcolor=ft.colors.with_opacity(0.8, ft.colors.BLUE_GREY), + tooltip_bgcolor=ft.Colors.with_opacity(0.8, ft.Colors.BLUE_GREY), min_y=0, max_y=6, min_x=0, diff --git a/python/controls/charts/matplotlib-chart/mpl-barchart.py b/python/controls/charts/matplotlib-chart/mpl-barchart-example.py similarity index 88% rename from python/controls/charts/matplotlib-chart/mpl-barchart.py rename to python/controls/charts/matplotlib-chart/mpl-barchart-example.py index 7cbf94f1..273181f4 100644 --- a/python/controls/charts/matplotlib-chart/mpl-barchart.py +++ b/python/controls/charts/matplotlib-chart/mpl-barchart-example.py @@ -1,14 +1,13 @@ import matplotlib import matplotlib.pyplot as plt -import flet -from flet import Page +import flet as ft from flet.matplotlib_chart import MatplotlibChart matplotlib.use("svg") -def main(page: Page): +def main(page: ft.Page): fig, ax = plt.subplots() @@ -26,4 +25,4 @@ def main(page: Page): page.add(MatplotlibChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/charts/matplotlib-chart/mpl-contour.py b/python/controls/charts/matplotlib-chart/mpl-contour.py index df0c4878..099773af 100644 --- a/python/controls/charts/matplotlib-chart/mpl-contour.py +++ b/python/controls/charts/matplotlib-chart/mpl-contour.py @@ -3,14 +3,13 @@ import matplotlib.tri as tri import numpy as np -import flet -from flet import Page +import flet as ft from flet.matplotlib_chart import MatplotlibChart matplotlib.use("svg") -def main(page: Page): +def main(page: ft.Page): np.random.seed(19680801) npts = 200 @@ -72,4 +71,4 @@ def main(page: Page): page.add(MatplotlibChart(fig, expand=True)) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/charts/matplotlib-chart/mpl-finance.py b/python/controls/charts/matplotlib-chart/mpl-finance.py index be9e89ef..d5ea7841 100644 --- a/python/controls/charts/matplotlib-chart/mpl-finance.py +++ b/python/controls/charts/matplotlib-chart/mpl-finance.py @@ -1,19 +1,21 @@ +import os import matplotlib import mplfinance as mpf import pandas as pd -import flet -from flet import Page +import flet as ft from flet.matplotlib_chart import MatplotlibChart matplotlib.use("svg") -def main(page: Page): +def main(page: ft.Page): - daily = pd.read_csv( - ".\\playground\\data\\SP500_NOV2019_Hist.csv", index_col=0, parse_dates=True + csv_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), "assets/SP500_NOV2019_Hist.csv" ) + print(csv_path) + daily = pd.read_csv(csv_path, index_col=0, parse_dates=True) daily.index.name = "Date" daily.shape daily.head(3) @@ -24,4 +26,4 @@ def main(page: Page): page.add(MatplotlibChart(fig, expand=True)) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/charts/matplotlib-chart/mpl-linechart.py b/python/controls/charts/matplotlib-chart/mpl-linechart-example.py similarity index 91% rename from python/controls/charts/matplotlib-chart/mpl-linechart.py rename to python/controls/charts/matplotlib-chart/mpl-linechart-example.py index 4423c188..227337a5 100644 --- a/python/controls/charts/matplotlib-chart/mpl-linechart.py +++ b/python/controls/charts/matplotlib-chart/mpl-linechart-example.py @@ -2,14 +2,13 @@ import matplotlib.pyplot as plt import numpy as np -import flet -from flet import Page +import flet as ft from flet.matplotlib_chart import MatplotlibChart matplotlib.use("svg") -def main(page: Page): +def main(page: ft.Page): # Fixing random state for reproducibility np.random.seed(19680801) @@ -38,4 +37,4 @@ def main(page: Page): page.add(MatplotlibChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/charts/matplotlib-chart/mpl-scatter.py b/python/controls/charts/matplotlib-chart/mpl-scatter.py index 0c46e147..98f53f21 100644 --- a/python/controls/charts/matplotlib-chart/mpl-scatter.py +++ b/python/controls/charts/matplotlib-chart/mpl-scatter.py @@ -2,14 +2,13 @@ import matplotlib.pyplot as plt import numpy as np -import flet -from flet import Page +import flet as ft from flet.matplotlib_chart import MatplotlibChart matplotlib.use("svg") -def main(page: Page): +def main(page: ft.Page): N = 45 x, y = np.random.rand(2, N) @@ -31,4 +30,4 @@ def main(page: Page): page.add(MatplotlibChart(fig, expand=True)) -flet.app(target=main) +ft.app(target=main) diff --git a/python/controls/charts/piechart-sample-1.py b/python/controls/charts/pie-chart/piechart-example.py similarity index 100% rename from python/controls/charts/piechart-sample-1.py rename to python/controls/charts/pie-chart/piechart-example.py diff --git a/python/controls/charts/piechart-sample-3.py b/python/controls/charts/pie-chart/piechart-with-icons.py similarity index 74% rename from python/controls/charts/piechart-sample-3.py rename to python/controls/charts/pie-chart/piechart-with-icons.py index 78740952..ce20d693 100644 --- a/python/controls/charts/piechart-sample-3.py +++ b/python/controls/charts/pie-chart/piechart-with-icons.py @@ -5,13 +5,13 @@ def main(page: ft.Page): normal_radius = 100 hover_radius = 110 normal_title_style = ft.TextStyle( - size=12, color=ft.colors.WHITE, weight=ft.FontWeight.BOLD + size=12, color=ft.Colors.WHITE, weight=ft.FontWeight.BOLD ) hover_title_style = ft.TextStyle( size=16, - color=ft.colors.WHITE, + color=ft.Colors.WHITE, weight=ft.FontWeight.BOLD, - shadow=ft.BoxShadow(blur_radius=2, color=ft.colors.BLACK54), + shadow=ft.BoxShadow(blur_radius=2, color=ft.Colors.BLACK54), ) normal_badge_size = 40 hover_badge_size = 50 @@ -21,9 +21,9 @@ def badge(icon, size): ft.Icon(icon), width=size, height=size, - border=ft.border.all(1, ft.colors.BROWN), + border=ft.border.all(1, ft.Colors.BROWN), border_radius=size / 2, - bgcolor=ft.colors.WHITE, + bgcolor=ft.Colors.WHITE, ) def on_chart_event(e: ft.PieChartEvent): @@ -42,36 +42,36 @@ def on_chart_event(e: ft.PieChartEvent): 40, title="40%", title_style=normal_title_style, - color=ft.colors.BLUE, + color=ft.Colors.BLUE, radius=normal_radius, - badge=badge(ft.icons.AC_UNIT, normal_badge_size), + badge=badge(ft.Icons.AC_UNIT, normal_badge_size), badge_position=0.98, ), ft.PieChartSection( 30, title="30%", title_style=normal_title_style, - color=ft.colors.YELLOW, + color=ft.Colors.YELLOW, radius=normal_radius, - badge=badge(ft.icons.ACCESS_ALARM, normal_badge_size), + badge=badge(ft.Icons.ACCESS_ALARM, normal_badge_size), badge_position=0.98, ), ft.PieChartSection( 15, title="15%", title_style=normal_title_style, - color=ft.colors.PURPLE, + color=ft.Colors.PURPLE, radius=normal_radius, - badge=badge(ft.icons.APPLE, normal_badge_size), + badge=badge(ft.Icons.APPLE, normal_badge_size), badge_position=0.98, ), ft.PieChartSection( 15, title="15%", title_style=normal_title_style, - color=ft.colors.GREEN, + color=ft.Colors.GREEN, radius=normal_radius, - badge=badge(ft.icons.PEDAL_BIKE, normal_badge_size), + badge=badge(ft.Icons.PEDAL_BIKE, normal_badge_size), badge_position=0.98, ), ], diff --git a/python/controls/charts/piechart-sample-2.py b/python/controls/charts/pie-chart/piechart-with-titles.py similarity index 83% rename from python/controls/charts/piechart-sample-2.py rename to python/controls/charts/pie-chart/piechart-with-titles.py index f94afc14..10752e0b 100644 --- a/python/controls/charts/piechart-sample-2.py +++ b/python/controls/charts/pie-chart/piechart-with-titles.py @@ -5,13 +5,13 @@ def main(page: ft.Page): normal_radius = 50 hover_radius = 60 normal_title_style = ft.TextStyle( - size=16, color=ft.colors.WHITE, weight=ft.FontWeight.BOLD + size=16, color=ft.Colors.WHITE, weight=ft.FontWeight.BOLD ) hover_title_style = ft.TextStyle( size=22, - color=ft.colors.WHITE, + color=ft.Colors.WHITE, weight=ft.FontWeight.BOLD, - shadow=ft.BoxShadow(blur_radius=2, color=ft.colors.BLACK54), + shadow=ft.BoxShadow(blur_radius=2, color=ft.Colors.BLACK54), ) def on_chart_event(e: ft.PieChartEvent): @@ -30,28 +30,28 @@ def on_chart_event(e: ft.PieChartEvent): 40, title="40%", title_style=normal_title_style, - color=ft.colors.BLUE, + color=ft.Colors.BLUE, radius=normal_radius, ), ft.PieChartSection( 30, title="30%", title_style=normal_title_style, - color=ft.colors.YELLOW, + color=ft.Colors.YELLOW, radius=normal_radius, ), ft.PieChartSection( 15, title="15%", title_style=normal_title_style, - color=ft.colors.PURPLE, + color=ft.Colors.PURPLE, radius=normal_radius, ), ft.PieChartSection( 15, title="15%", title_style=normal_title_style, - color=ft.colors.GREEN, + color=ft.Colors.GREEN, radius=normal_radius, ), ], diff --git a/python/controls/charts/plotly-chart/plotly-barchart.py b/python/controls/charts/plotly-chart/plotly-barchart.py index 3ae84dc4..02f1dfaf 100644 --- a/python/controls/charts/plotly-chart/plotly-barchart.py +++ b/python/controls/charts/plotly-chart/plotly-barchart.py @@ -1,11 +1,10 @@ import plotly.express as px -import flet -from flet import Page +import flet as ft from flet.plotly_chart import PlotlyChart -def main(page: Page): +def main(page: ft.Page): df = px.data.gapminder().query("continent == 'Oceania'") fig = px.bar( @@ -21,4 +20,4 @@ def main(page: Page): page.add(PlotlyChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/charts/plotly-chart/plotly-boxchart.py b/python/controls/charts/plotly-chart/plotly-boxchart.py index 5b7a2dbe..195e9cdb 100644 --- a/python/controls/charts/plotly-chart/plotly-boxchart.py +++ b/python/controls/charts/plotly-chart/plotly-boxchart.py @@ -1,11 +1,10 @@ import plotly.graph_objects as go -import flet -from flet import Page +import flet as ft from flet.plotly_chart import PlotlyChart -def main(page: Page): +def main(page: ft.Page): x = [ "day 1", @@ -57,4 +56,4 @@ def main(page: Page): page.add(PlotlyChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/charts/plotly-chart/plotly-linechart.py b/python/controls/charts/plotly-chart/plotly-linechart.py index 3124397f..b5b49324 100644 --- a/python/controls/charts/plotly-chart/plotly-linechart.py +++ b/python/controls/charts/plotly-chart/plotly-linechart.py @@ -1,11 +1,10 @@ import plotly.express as px -import flet -from flet import Page +import flet as ft from flet.plotly_chart import PlotlyChart -def main(page: Page): +def main(page: ft.Page): df = px.data.gapminder().query("continent=='Oceania'") fig = px.line(df, x="year", y="lifeExp", color="country") @@ -13,4 +12,4 @@ def main(page: Page): page.add(PlotlyChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/charts/plotly-chart/plotly-piechart.py b/python/controls/charts/plotly-chart/plotly-piechart.py index b0b62e59..ba120b3e 100644 --- a/python/controls/charts/plotly-chart/plotly-piechart.py +++ b/python/controls/charts/plotly-chart/plotly-piechart.py @@ -1,11 +1,10 @@ import plotly.graph_objects as go -import flet -from flet import Page +import flet as ft from flet.plotly_chart import PlotlyChart -def main(page: Page): +def main(page: ft.Page): labels = ["Oxygen", "Hydrogen", "Carbon_Dioxide", "Nitrogen"] values = [4500, 2500, 1053, 500] @@ -15,4 +14,4 @@ def main(page: Page): page.add(PlotlyChart(fig, expand=True)) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/dropdown/dropdown-example.py b/python/controls/input-and-selections/dropdown/dropdown-example.py index c4831e25..b246a024 100644 --- a/python/controls/input-and-selections/dropdown/dropdown-example.py +++ b/python/controls/input-and-selections/dropdown/dropdown-example.py @@ -4,7 +4,7 @@ def main(page: ft.Page): colors = [ ft.Colors.RED, - ft.colors.BLUE, + ft.Colors.BLUE, ft.Colors.YELLOW, ft.Colors.PURPLE, ft.Colors.LIME, From bd9e629425e229e3838baf81420c5943ce2cd22c Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 8 Apr 2025 11:37:21 -0700 Subject: [PATCH 74/81] update markdown examples --- .../markdown/markdown-basic.py | 64 +++---------------- .../markdown/markdown-code-highlight.py | 10 +-- .../markdown/markdown-custom-theme.py | 6 +- .../markdown/markdown-listviews.py | 20 +++--- 4 files changed, 29 insertions(+), 71 deletions(-) diff --git a/python/controls/information-displays/markdown/markdown-basic.py b/python/controls/information-displays/markdown/markdown-basic.py index a137598b..9b476ee5 100644 --- a/python/controls/information-displays/markdown/markdown-basic.py +++ b/python/controls/information-displays/markdown/markdown-basic.py @@ -1,5 +1,4 @@ -import flet -from flet import Divider, ListView, Markdown, Page +import flet as ft md1 = """ # Markdown Example @@ -9,23 +8,19 @@ Setext-style -``` This is an H1 ============= This is an H2 ------------- -``` Atx-style -``` # This is an H1 ## This is an H2 ###### This is an H6 -``` Select the valid headers: @@ -34,17 +29,11 @@ ## Links -[Google's Homepage][Google] - -``` [inline-style](https://www.google.com) -[reference-style][Google] -``` - ## Images -![Flutter logo](/icons/icon-192.png) +![Image from Flet assets](/icons/icon-192.png) ![Test image](https://picsum.photos/200/300) @@ -63,6 +52,7 @@ |`~~***italic bold strikethrough 2***~~`|~~***italic bold strikethrough 2***~~| ## Styling + Style text as _italic_, __bold__, ~~strikethrough~~, or `inline code`. - Use bulleted lists @@ -70,65 +60,31 @@ - Your points ## Code blocks + Formatted Dart code looks really pretty too: ``` void main() { runApp(MaterialApp( home: Scaffold( - body: Markdown(data: markdownData), + body: ft.Markdown(data: markdownData), ), )); } ``` - -## Center Title - -###### ※ ※ ※ - -_* How to implement it see main.dart#L129 in example._ - -## Custom Syntax - -NaOH + Al_2O_3 = NaAlO_2 + H_2O - -C_4H_10 = C_2H_6 + C_2H_4 - -## Markdown widget - -This is an example of how to create your own Markdown widget: - - Markdown(data: 'Hello _world_!'); - -Enjoy! - -[Google]: https://www.google.com/ - -## Line Breaks - -This is an example of how to create line breaks (tab or two whitespaces): - -line 1 - - -line 2 - - - -line 3 """ -def main(page: Page): - page.scroll = "auto" +def main(page: ft.Page): + page.scroll = ft.ScrollMode.AUTO page.add( - Markdown( + ft.Markdown( md1, selectable=True, - extension_set="gitHubWeb", + extension_set=ft.MarkdownExtensionSet.GITHUB_WEB, on_tap_link=lambda e: page.launch_url(e.data), ) ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/information-displays/markdown/markdown-code-highlight.py b/python/controls/information-displays/markdown/markdown-code-highlight.py index 78606631..dc5e1601 100644 --- a/python/controls/information-displays/markdown/markdown-code-highlight.py +++ b/python/controls/information-displays/markdown/markdown-code-highlight.py @@ -153,7 +153,7 @@ class MyApp extends StatelessWidget { def main(page: ft.Page): - page.scroll = "auto" + page.scroll = ft.ScrollMode.AUTO page.fonts = { "Roboto Mono": "RobotoMono-VariableFont_wght.ttf", @@ -163,9 +163,11 @@ def main(page: ft.Page): ft.Markdown( table, selectable=True, - extension_set="gitHubWeb", - code_theme="atom-one-dark", - code_style=ft.TextStyle(font_family="Roboto Mono"), + extension_set=ft.MarkdownExtensionSet.GITHUB_WEB, + code_theme=ft.MarkdownCodeTheme.ATOM_ONE_DARK, + code_style_sheet=ft.MarkdownStyleSheet( + code_text_style=ft.TextStyle(font_family="Roboto Mono") + ), on_tap_link=lambda e: page.launch_url(e.data), ) ) diff --git a/python/controls/information-displays/markdown/markdown-custom-theme.py b/python/controls/information-displays/markdown/markdown-custom-theme.py index 741adac9..69d53d8c 100644 --- a/python/controls/information-displays/markdown/markdown-custom-theme.py +++ b/python/controls/information-displays/markdown/markdown-custom-theme.py @@ -11,9 +11,9 @@ def main(page: ft.Page): padding=20, theme=ft.Theme( text_theme=ft.TextTheme( - body_medium=ft.TextStyle(color=ft.colors.WHITE), - body_large=ft.TextStyle(color=ft.colors.WHITE), - body_small=ft.TextStyle(color=ft.colors.WHITE), + body_medium=ft.TextStyle(color=ft.Colors.WHITE), + body_large=ft.TextStyle(color=ft.Colors.WHITE), + body_small=ft.TextStyle(color=ft.Colors.WHITE), ) ), ) diff --git a/python/controls/information-displays/markdown/markdown-listviews.py b/python/controls/information-displays/markdown/markdown-listviews.py index 0469ac88..6dddc545 100644 --- a/python/controls/information-displays/markdown/markdown-listviews.py +++ b/python/controls/information-displays/markdown/markdown-listviews.py @@ -1,5 +1,4 @@ -import flet -from flet import Divider, ListView, Markdown, Page +import flet as ft md1 = """ # Markdown Example @@ -119,22 +118,23 @@ """ -def main(page: Page): +def main(page: ft.Page): def goto_url(e): print("GOTO:", e.data) page.launch_url(e.data) page.add( - ListView( - [Markdown(md1, on_tap_link=lambda e: page.launch_url(e.data))], expand=True + ft.ListView( + [ft.Markdown(md1, on_tap_link=lambda e: page.launch_url(e.data))], + expand=True, ), - Divider(), - ListView( + ft.Divider(), + ft.ListView( [ - Markdown( + ft.Markdown( md1, selectable=True, - extension_set="gitHubWeb", + extension_set=ft.MarkdownExtensionSet.GITHUB_WEB, on_tap_link=goto_url, ) ], @@ -143,4 +143,4 @@ def goto_url(e): ) -flet.app(target=main) +ft.app(target=main) From f06188e67fd4814a4c4fc44ade6e954d4d42ae5b Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 8 Apr 2025 11:41:53 -0700 Subject: [PATCH 75/81] add markdown event example --- .../markdown/markdown-event-example.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 python/controls/information-displays/markdown/markdown-event-example.py diff --git a/python/controls/information-displays/markdown/markdown-event-example.py b/python/controls/information-displays/markdown/markdown-event-example.py new file mode 100644 index 00000000..4af93942 --- /dev/null +++ b/python/controls/information-displays/markdown/markdown-event-example.py @@ -0,0 +1,18 @@ +import flet as ft + + +def main(page: ft.Page): + def open_url(e): + page.launch_url(e.data) + + page.add( + ft.Markdown( + "[inline-style](https://www.google.com)", + extension_set=ft.MarkdownExtensionSet.GITHUB_WEB, + on_tap_link=open_url, + expand=True, + ), + ) + + +ft.app(main) From b92675a3c936cef52178db3dca4b928d989506e4 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 10 Apr 2025 13:27:45 -0700 Subject: [PATCH 76/81] update progressbar and progressring examples --- .../map/map-layers-example.py | 141 ++++++++++++++++++ .../progress-bar/progress-bar.py | 21 +-- .../progress-ring/gauge-with-progress.py | 15 +- .../progress-ring/progress-ring.py | 28 ++-- 4 files changed, 176 insertions(+), 29 deletions(-) create mode 100644 python/controls/information-displays/map/map-layers-example.py diff --git a/python/controls/information-displays/map/map-layers-example.py b/python/controls/information-displays/map/map-layers-example.py new file mode 100644 index 00000000..c4d5e7d4 --- /dev/null +++ b/python/controls/information-displays/map/map-layers-example.py @@ -0,0 +1,141 @@ +import random +import flet as ft +import flet_map as map + + +def main(page: ft.Page): + marker_layer_ref = ft.Ref[map.MarkerLayer]() + circle_layer_ref = ft.Ref[map.CircleLayer]() + + def handle_tap(e: map.MapTapEvent): + # print(e) + if e.name == "tap": + marker_layer_ref.current.markers.append( + map.Marker( + content=ft.Icon( + ft.Icons.LOCATION_ON, color=ft.CupertinoColors.DESTRUCTIVE_RED + ), + coordinates=e.coordinates, + ) + ) + elif e.name == "long_press": + circle_layer_ref.current.circles.append( + map.CircleMarker( + radius=random.randint(5, 10), + coordinates=e.coordinates, + color=ft.Colors.random(), + border_color=ft.Colors.random(), + border_stroke_width=4, + ) + ) + page.update() + + # def handle_event(e: map.MapEvent): + # print(e) + + page.add( + ft.Text("Click anywhere to add a Marker, long-click to add a CircleMarker."), + map.Map( + expand=True, + initial_center=map.MapLatitudeLongitude(15, 10), + initial_zoom=4.2, + interaction_configuration=map.MapInteractionConfiguration( + flags=map.MapInteractiveFlag.ALL + ), + on_init=lambda e: print(f"Initialized Map"), + on_tap=handle_tap, + on_secondary_tap=handle_tap, + on_long_press=handle_tap, + # on_event=lambda e: print(e), + layers=[ + map.TileLayer( + url_template="https://tile.openstreetmap.org/{z}/{x}/{y}.png", + on_image_error=lambda e: print("TileLayer Error"), + ), + map.RichAttribution( + attributions=[ + map.TextSourceAttribution( + text="OpenStreetMap Contributors", + on_click=lambda e: e.page.launch_url( + "https://openstreetmap.org/copyright" + ), + ), + map.TextSourceAttribution( + text="Flet", + on_click=lambda e: e.page.launch_url("https://flet.dev"), + ), + ] + ), + map.SimpleAttribution( + text="Flet", + alignment=ft.alignment.top_right, + on_click=lambda e: print("Clicked SimpleAttribution"), + ), + map.MarkerLayer( + ref=marker_layer_ref, + markers=[ + map.Marker( + content=ft.Icon(ft.Icons.LOCATION_ON), + coordinates=map.MapLatitudeLongitude(30, 15), + ), + map.Marker( + content=ft.Icon(ft.Icons.LOCATION_ON), + coordinates=map.MapLatitudeLongitude(10, 10), + ), + map.Marker( + content=ft.Icon(ft.Icons.LOCATION_ON), + coordinates=map.MapLatitudeLongitude(25, 45), + ), + ], + ), + map.CircleLayer( + ref=circle_layer_ref, + circles=[ + map.CircleMarker( + radius=10, + coordinates=map.MapLatitudeLongitude(30.05, 31.25), + color=ft.Colors.RED, + border_color=ft.Colors.BLUE, + border_stroke_width=4, + ), + ], + ), + map.PolygonLayer( + polygons=[ + map.PolygonMarker( + label="Popular Touristic Area", + label_text_style=ft.TextStyle( + color=ft.Colors.BLACK, + size=15, + weight=ft.FontWeight.BOLD, + ), + color=ft.Colors.with_opacity(0.3, ft.Colors.BLUE), + coordinates=[ + map.MapLatitudeLongitude(10, 10), + map.MapLatitudeLongitude(30, 15), + map.MapLatitudeLongitude(25, 45), + ], + ), + ], + ), + map.PolylineLayer( + polylines=[ + map.PolylineMarker( + border_stroke_width=3, + border_color=ft.Colors.RED, + gradient_colors=[ft.Colors.BLACK, ft.Colors.BLACK], + color=ft.Colors.with_opacity(0.6, ft.Colors.GREEN), + coordinates=[ + map.MapLatitudeLongitude(10, 10), + map.MapLatitudeLongitude(30, 15), + map.MapLatitudeLongitude(25, 45), + ], + ), + ], + ), + ], + ), + ) + + +ft.app(main) diff --git a/python/controls/information-displays/progress-bar/progress-bar.py b/python/controls/information-displays/progress-bar/progress-bar.py index 778b6751..6ccbb721 100644 --- a/python/controls/information-displays/progress-bar/progress-bar.py +++ b/python/controls/information-displays/progress-bar/progress-bar.py @@ -1,23 +1,26 @@ from time import sleep -import flet -from flet import Column, Page, ProgressBar, Text +import flet as ft -def main(page: Page): - pb = ProgressBar(width=400) +def main(page: ft.Page): + pb = ft.ProgressBar(width=400) + pbl = ft.Text("Doing something...") page.add( - Text("Linear progress indicator", style="headlineSmall"), - Column([Text("Doing something..."), pb]), - Text("Indeterminate progress bar", style="headlineSmall"), - ProgressBar(width=400, color="amber", bgcolor="#eeeeee"), + ft.Text("Linear progress indicator", style=ft.TextThemeStyle.HEADLINE_SMALL), + ft.Column([pbl, pb]), + ft.Text("Indeterminate progress bar", style=ft.TextThemeStyle.HEADLINE_SMALL), + ft.ProgressBar(width=400, color=ft.Colors.AMBER, bgcolor="#eeeeee"), ) for i in range(0, 101): + pb.value = i * 0.01 sleep(0.1) + if i == 100: + pbl.value = "Finished!" page.update() -flet.app(target=main) +ft.app(main) diff --git a/python/controls/information-displays/progress-ring/gauge-with-progress.py b/python/controls/information-displays/progress-ring/gauge-with-progress.py index d6e6c9a1..740ee46a 100644 --- a/python/controls/information-displays/progress-ring/gauge-with-progress.py +++ b/python/controls/information-displays/progress-ring/gauge-with-progress.py @@ -1,13 +1,13 @@ -import flet -from flet import Container, Page, ProgressRing, Stack, Text, alignment +import flet as ft -def main(page: Page): + +def main(page: ft.Page): page.add( - Stack( + ft.Stack( [ - Container(Text("60%"), alignment=alignment.center), - ProgressRing( + ft.Container(ft.Text("60%"), alignment=ft.alignment.center), + ft.ProgressRing( value=0.6, width=100, height=100, @@ -18,4 +18,5 @@ def main(page: Page): ) ) -flet.app(target=main) + +ft.app(target=main) diff --git a/python/controls/information-displays/progress-ring/progress-ring.py b/python/controls/information-displays/progress-ring/progress-ring.py index a7dc93f9..21f3549a 100644 --- a/python/controls/information-displays/progress-ring/progress-ring.py +++ b/python/controls/information-displays/progress-ring/progress-ring.py @@ -1,26 +1,28 @@ from time import sleep +import flet as ft -import flet -from flet import Column, Page, ProgressRing, Row, Text - - -def main(page: Page): - pr = ProgressRing(width=16, height=16, stroke_width=2) +def main(page: ft.Page): + pr = ft.ProgressRing(width=16, height=16, stroke_width=2) + prl = ft.Text("Wait for the completion...") page.add( - Text("Circular progress indicator", style="headlineSmall"), - Row([pr, Text("Wait for the completion...")]), - Text("Indeterminate circular progress", style="headlineSmall"), - Column( - [ProgressRing(), Text("I'm going to run for ages...")], - horizontal_alignment="center", + ft.Text("Circular progress indicator", style=ft.TextThemeStyle.HEADLINE_SMALL), + ft.Row([pr, prl]), + ft.Text( + "Indeterminate cicrular progress", style=ft.TextThemeStyle.HEADLINE_SMALL + ), + ft.Column( + [ft.ProgressRing(), ft.Text("I'm going to run for ages...")], + horizontal_alignment=ft.CrossAxisAlignment.CENTER, ), ) for i in range(0, 101): pr.value = i * 0.01 sleep(0.1) + if i == 100: + prl.value = "Finished!" page.update() -flet.app(target=main) +ft.app(main) From 975480a2e433b248e9e870803b2a8bb1d59fed07 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 10 Apr 2025 15:43:48 -0700 Subject: [PATCH 77/81] update textfield examples --- .../text/richtext-borders-stroke.py | 5 +- .../text/richtext-gradient.py | 2 +- .../information-displays/text/richtext.py | 11 +-- .../text/text-custom-styles.py | 75 +++++++++------- .../text/text-theme-styles.py | 39 ++++---- .../text-field/prefix-suffix.py | 3 +- .../text-field/textfields.py | 90 ------------------- 7 files changed, 71 insertions(+), 154 deletions(-) delete mode 100644 python/controls/input-and-selections/text-field/textfields.py diff --git a/python/controls/information-displays/text/richtext-borders-stroke.py b/python/controls/information-displays/text/richtext-borders-stroke.py index d2c1f44b..f03f0099 100644 --- a/python/controls/information-displays/text/richtext-borders-stroke.py +++ b/python/controls/information-displays/text/richtext-borders-stroke.py @@ -13,9 +13,8 @@ def main(page: ft.Page): size=40, weight=ft.FontWeight.BOLD, foreground=ft.Paint( - color=ft.colors.BLUE_700, + color=ft.Colors.BLUE_700, stroke_width=6, - stroke_join=ft.StrokeJoin.ROUND, style=ft.PaintingStyle.STROKE, ), ), @@ -29,7 +28,7 @@ def main(page: ft.Page): ft.TextStyle( size=40, weight=ft.FontWeight.BOLD, - color=ft.colors.GREY_300, + color=ft.Colors.GREY_300, ), ), ], diff --git a/python/controls/information-displays/text/richtext-gradient.py b/python/controls/information-displays/text/richtext-gradient.py index e221736a..82083431 100644 --- a/python/controls/information-displays/text/richtext-gradient.py +++ b/python/controls/information-displays/text/richtext-gradient.py @@ -12,7 +12,7 @@ def main(page: ft.Page): weight=ft.FontWeight.BOLD, foreground=ft.Paint( gradient=ft.PaintLinearGradient( - (0, 20), (150, 20), [ft.colors.RED, ft.colors.YELLOW] + (0, 20), (150, 20), [ft.Colors.RED, ft.Colors.YELLOW] ) ), ), diff --git a/python/controls/information-displays/text/richtext.py b/python/controls/information-displays/text/richtext.py index 3acb6920..543d6afc 100644 --- a/python/controls/information-displays/text/richtext.py +++ b/python/controls/information-displays/text/richtext.py @@ -1,9 +1,5 @@ -import logging - import flet as ft -logging.basicConfig(level=logging.DEBUG) - def main(page: ft.Page): page.add( @@ -16,7 +12,7 @@ def main(page: ft.Page): spans=[ ft.TextSpan( "here goes italic", - ft.TextStyle(italic=True, size=20, color=ft.colors.GREEN), + ft.TextStyle(italic=True, size=20, color=ft.Colors.GREEN), spans=[ ft.TextSpan( "bold and italic", @@ -47,7 +43,7 @@ def main(page: ft.Page): "underlined red wavy", ft.TextStyle( decoration=ft.TextDecoration.UNDERLINE, - decoration_color=ft.colors.RED, + decoration_color=ft.Colors.RED, decoration_style=ft.TextDecorationStyle.WAVY, ), on_enter=lambda e: print(f"Entered span: {e.control.uid}"), @@ -81,7 +77,7 @@ def main(page: ft.Page): ) def highlight_link(e): - e.control.style.color = ft.colors.BLUE + e.control.style.color = ft.Colors.BLUE e.control.update() def unhighlight_link(e): @@ -105,4 +101,3 @@ def unhighlight_link(e): ft.app(main) -# ft.app(main, port=8550, view=ft.WEB_BROWSER) diff --git a/python/controls/information-displays/text/text-custom-styles.py b/python/controls/information-displays/text/text-custom-styles.py index 632266ad..7b76dac3 100644 --- a/python/controls/information-displays/text/text-custom-styles.py +++ b/python/controls/information-displays/text/text-custom-styles.py @@ -1,55 +1,68 @@ -import flet -from flet import Page, Text, colors +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Text custom styles" - page.scroll = "adaptive" + page.scroll = ft.ScrollMode.ADAPTIVE page.add( - Text("Size 10", size=10), - Text("Size 30, Italic", size=20, color="pink600", italic=True), - Text( + ft.Text("Size 10", size=10), + ft.Text("Size 30, Italic", size=30, color=ft.Colors.PINK_600, italic=True), + ft.Text( "Size 40, w100", size=40, - color=colors.WHITE, - bgcolor=colors.BLUE_600, - weight="w100", + color=ft.Colors.WHITE, + bgcolor=ft.Colors.BLUE_600, + weight=ft.FontWeight.W_100, ), - Text( + ft.Text( "Size 50, Normal", size=50, - color=colors.WHITE, - bgcolor=colors.ORANGE_800, - weight="normal", + color=ft.Colors.WHITE, + bgcolor=ft.Colors.ORANGE_800, + weight=ft.FontWeight.NORMAL, ), - Text( + ft.Text( "Size 60, Bold, Italic", - size=60, - color=colors.WHITE, - bgcolor=colors.GREEN_700, - weight="bold", + size=50, + color=ft.Colors.WHITE, + bgcolor=ft.Colors.GREEN_700, + weight=ft.FontWeight.BOLD, italic=True, ), - Text("Size 70, w900, selectable", size=70, weight="w900", selectable=True), - Text("Limit long text to 1 line with ellipsis", style="headlineSmall"), - Text( - "Proin rutrum, purus sit amet elementum volutpat, nunc lacus vulputate orci, cursus ultrices neque dui quis purus. Ut ultricies purus nec nibh bibendum, eget vestibulum metus varius. Duis convallis maximus justo, eu rutrum libero maximus id. Donec ullamcorper arcu in sapien molestie, non pellentesque tellus pellentesque. Nulla nec tristique ex. Maecenas euismod nisl enim, a convallis arcu laoreet at. Ut at tortor finibus, rutrum massa sit amet, pulvinar velit. Phasellus diam lorem, viverra vitae leo vitae, consequat suscipit lorem.", + ft.Text( + "Size 70, w900, selectable", + size=70, + weight=ft.FontWeight.W_900, + selectable=True, + ), + ft.Text( + "Limit long text to 1 line with ellipsis", + theme_style=ft.TextThemeStyle.HEADLINE_SMALL, + ), + ft.Text( + "Proin rutrum, purus sit amet elementum volutpat, nunc lacus vulputate orci, cursus ultrices neque dui quis purus. Ut ultricies purus nec nibh bibendum, eget vestibulum metus various. Duis convallis maximus justo, eu rutrum libero maximus id. Donec ullamcorper arcu in sapien molestie, non pellentesque tellus pellentesque. Nulla nec tristique ex. Maecenas euismod nisl enim, a convallis arcu laoreet at. Ut at tortor finibus, rutrum massa sit amet, pulvinar velit. Phasellus diam lorem, viverra vitae leo vitae, consequat suscipit lorem.", max_lines=1, - overflow="ellipsis", + overflow=ft.TextOverflow.ELLIPSIS, ), - Text("Limit long text to 2 lines and fading", style="headlineSmall"), - Text( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Nam varius at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.", + ft.Text( + "Limit long text to 2 lines and fading", + theme_style=ft.TextThemeStyle.HEADLINE_SMALL, + ), + ft.Text( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Name various at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.", max_lines=2, ), - Text("Limit the width and height of long text", style="headlineSmall"), - Text( - "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Nam varius at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.", + ft.Text( + "Limit the width and height of long text", + theme_style=ft.TextThemeStyle.HEADLINE_SMALL, + ), + ft.Text( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur quis nibh vitae purus consectetur facilisis sed vitae ipsum. Quisque faucibus sed nulla placerat sagittis. Phasellus condimentum risus vitae nulla vestibulum auctor. Curabitur scelerisque, nibh eget imperdiet consequat, odio ante tempus diam, sed volutpat nisl erat eget turpis. Sed viverra, diam sit amet blandit vulputate, mi tellus dapibus lorem, vitae vehicula diam mauris placerat diam. Morbi sit amet pretium turpis, et consequat ligula. Nulla velit sem, suscipit sit amet dictum non, tincidunt sed nulla. Aenean pellentesque odio porttitor sagittis aliquam. Name various at metus vitae vulputate. Praesent faucibus nibh lorem, eu pretium dolor dictum nec. Phasellus eget dui laoreet, viverra magna vitae, pellentesque diam.", width=700, height=100, ), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/information-displays/text/text-theme-styles.py b/python/controls/information-displays/text/text-theme-styles.py index adaaea4b..673cb019 100644 --- a/python/controls/information-displays/text/text-theme-styles.py +++ b/python/controls/information-displays/text/text-theme-styles.py @@ -1,28 +1,27 @@ -import flet -from flet import ListView, Page, Text +import flet as ft -def main(page: Page): +def main(page: ft.Page): page.title = "Text theme styles" - page.scroll = "adaptive" + page.scroll = ft.ScrollMode.ADAPTIVE page.add( - Text("Display Large", style="displayLarge"), - Text("Display Medium", style="displayMedium"), - Text("Display Small", style="displaySmall"), - Text("Headline Large", style="headlineLarge"), - Text("Headline Medium", style="headlineMedium"), - Text("Headline Small", style="headlineMedium"), - Text("Title Large", style="titleLarge"), - Text("Title Medium", style="titleMedium"), - Text("Title Small", style="titleSmall"), - Text("Label Large", style="labelLarge"), - Text("Label Medium", style="labelMedium"), - Text("Label Small", style="labelSmall"), - Text("Body Large", style="bodylLarge"), - Text("Body Medium", style="bodyMedium"), - Text("Body Small", style="bodySmall"), + ft.Text("Display Large", theme_style=ft.TextThemeStyle.DISPLAY_LARGE), + ft.Text("Display Medium", theme_style=ft.TextThemeStyle.DISPLAY_MEDIUM), + ft.Text("Display Small", theme_style=ft.TextThemeStyle.DISPLAY_SMALL), + ft.Text("Headline Large", theme_style=ft.TextThemeStyle.HEADLINE_LARGE), + ft.Text("Headline Medium", theme_style=ft.TextThemeStyle.HEADLINE_MEDIUM), + ft.Text("Headline Small", theme_style=ft.TextThemeStyle.HEADLINE_SMALL), + ft.Text("Title Large", theme_style=ft.TextThemeStyle.TITLE_LARGE), + ft.Text("Title Medium", theme_style=ft.TextThemeStyle.TITLE_MEDIUM), + ft.Text("Title Small", theme_style=ft.TextThemeStyle.TITLE_SMALL), + ft.Text("Label Large", theme_style=ft.TextThemeStyle.LABEL_LARGE), + ft.Text("Label Medium", theme_style=ft.TextThemeStyle.LABEL_MEDIUM), + ft.Text("Label Small", theme_style=ft.TextThemeStyle.LABEL_SMALL), + ft.Text("Body Large", theme_style=ft.TextThemeStyle.BODY_LARGE), + ft.Text("Body Medium", theme_style=ft.TextThemeStyle.BODY_MEDIUM), + ft.Text("Body Small", theme_style=ft.TextThemeStyle.BODY_SMALL), ) -flet.app(target=main) +ft.app(main) diff --git a/python/controls/input-and-selections/text-field/prefix-suffix.py b/python/controls/input-and-selections/text-field/prefix-suffix.py index fea3a4b5..4dcfa743 100644 --- a/python/controls/input-and-selections/text-field/prefix-suffix.py +++ b/python/controls/input-and-selections/text-field/prefix-suffix.py @@ -18,9 +18,10 @@ def button_clicked(e): icon=ft.Icons.FORMAT_SIZE, hint_text="Type your favorite color", helper_text="You can type only one color", - counter_text="0 symbols typed", + counter_text="{value_length}/{max_length} chars used", prefix_icon=ft.Icons.COLOR_LENS, suffix_text="...is your color", + max_length=20, ) page.add(pr, sf, ps, icon, b, t) diff --git a/python/controls/input-and-selections/text-field/textfields.py b/python/controls/input-and-selections/text-field/textfields.py deleted file mode 100644 index 4a780acb..00000000 --- a/python/controls/input-and-selections/text-field/textfields.py +++ /dev/null @@ -1,90 +0,0 @@ -from time import sleep - -import flet -from flet import Column, Page, ProgressBar, Text, TextField, icons, padding - - -def main(page: Page): - page.title = "TextField Examples" - page.theme_mode = "light" - page.padding = padding.all(20) - - page.splash = ProgressBar(visible=False) - - def chat_submit(e): - print(f"Submit FieldText: {e.control.value}") - e.control.value = "" - form.disabled = True - page.splash.visible = True - page.update() - sleep(2) - form.disabled = False - page.splash.visible = False - page.update() - - chat_input = TextField( - hint_text="Say something...", - shift_enter=True, - min_lines=1, - on_submit=chat_submit, - max_lines=5, - ) - - form = Column( - [ - Text("Outlined TextField", style="headlineMedium"), - TextField(), - Text( - "Outlined TextField with Label, Hint and Helper text", - style="headlineSmall", - ), - TextField( - label="Full name", - hint_text="Enter your full name", - helper_text="Hint text is visible when TextField is empty and focused", - ), - Text( - "Underlined, filled and multiline TextField", - style="headlineSmall", - ), - TextField( - label="Comments", - helper_text="Tell something about us", - border="underline", - filled=True, - multiline=True, - ), - Text( - "New line - Shift + Enter and submit on Enter", - style="headlineSmall", - ), - chat_input, - Text( - "Login with email/password", - style="headlineSmall", - ), - TextField( - label="Email", - prefix_icon=icons.EMAIL, - border="underline", - keyboard_type="email", - filled=True, - ), - TextField( - label="Password", - prefix_icon=icons.PASSWORD_SHARP, - border="underline", - password=True, - can_reveal_password=True, - filled=True, - ), - ], - scroll="adaptive", - expand=1, - width=600, - ) - - page.add(form) - - -flet.app(target=main) From c4d9cd2842fe12f308fa49990ebcec4d63b393d7 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 10 Apr 2025 23:39:55 -0700 Subject: [PATCH 78/81] fix ads example --- .../information-displays/ads/ads-basic-example.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/python/controls/information-displays/ads/ads-basic-example.py b/python/controls/information-displays/ads/ads-basic-example.py index a475699b..553f0329 100644 --- a/python/controls/information-displays/ads/ads-basic-example.py +++ b/python/controls/information-displays/ads/ads-basic-example.py @@ -1,5 +1,5 @@ import flet as ft -import flet.ads as ads +import flet_ads as ads def main(page: ft.Page): @@ -50,15 +50,16 @@ def display_new_banner_ad(): ), width=320, height=50, - bgcolor=ft.colors.TRANSPARENT, + bgcolor=ft.Colors.TRANSPARENT, ) ) - page.overlay.append(iad := get_new_interstitial_ad()) + iad = get_new_interstitial_ad() + page.overlay.append(iad) page.appbar = ft.AppBar( adaptive=True, title=ft.Text("Mobile Ads Playground"), - bgcolor=ft.colors.LIGHT_BLUE_300, + bgcolor=ft.Colors.LIGHT_BLUE_300, ) page.add( ft.OutlinedButton("Show InterstitialAd", on_click=lambda e: iad.show()), From 3702e2f515c48604f8cd4702df844e65c0eccba2 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Tue, 15 Apr 2025 23:27:59 -0700 Subject: [PATCH 79/81] update audio-recorder/player examples --- .../ads/ads-basic-example.py | 2 +- .../audio-recorder/audio-recorder-example.py | 33 +++++++++++++++---- .../utility/audio/audio-player-slider.py | 6 ++-- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/python/controls/information-displays/ads/ads-basic-example.py b/python/controls/information-displays/ads/ads-basic-example.py index 553f0329..a85c17cb 100644 --- a/python/controls/information-displays/ads/ads-basic-example.py +++ b/python/controls/information-displays/ads/ads-basic-example.py @@ -59,7 +59,7 @@ def display_new_banner_ad(): page.appbar = ft.AppBar( adaptive=True, title=ft.Text("Mobile Ads Playground"), - bgcolor=ft.Colors.LIGHT_BLUE_300, + bgcolor=Colors.LIGHT_BLUE_300, ) page.add( ft.OutlinedButton("Show InterstitialAd", on_click=lambda e: iad.show()), diff --git a/python/controls/utility/audio-recorder/audio-recorder-example.py b/python/controls/utility/audio-recorder/audio-recorder-example.py index 60b72045..cd24b135 100644 --- a/python/controls/utility/audio-recorder/audio-recorder-example.py +++ b/python/controls/utility/audio-recorder/audio-recorder-example.py @@ -1,10 +1,7 @@ -# Not working with version 0.27.6 -# "Control not found" error - - import flet as ft -# import flet_audio_recorder as ftar +import flet_audio_recorder as ftar +import flet_audio as fta def main(page: ft.Page): @@ -20,8 +17,10 @@ def handle_start_recording(e): def handle_stop_recording(e): output_path = audio_rec.stop_recording() print(f"StopRecording: {output_path}") + log.value = f"StopRecording: {output_path}" if page.web and output_path is not None: page.launch_url(output_path) + page.update() def handle_list_devices(e): devices = audio_rec.get_input_devices() @@ -30,8 +29,10 @@ def handle_list_devices(e): def handle_has_permission(e): try: print(f"HasPermission: {audio_rec.has_permission()}") + log.value = f"HasPermission: {audio_rec.has_permission()}" except Exception as e: print(e) + page.update() def handle_pause(e): print(f"isRecording: {audio_rec.is_recording()}") @@ -46,17 +47,29 @@ def handle_resume(e): def handle_audio_encoding_test(e): for i in list(ft.AudioEncoder): print(f"{i}: {audio_rec.is_supported_encoder(i)}") + page.add(ft.Text(f"audio encoder: {i.name}")) def handle_state_change(e): print(f"State Changed: {e.data}") - audio_rec = ft.AudioRecorder( - audio_encoder=ft.AudioEncoder.WAV, + audio_rec = ftar.AudioRecorder( + # audio_encoder=ft.AudioEncoder.WAV, on_state_changed=handle_state_change, ) + audio_play = fta.Audio("non-existent", autoplay=False, volume=6) + + page.overlay.append(audio_play) + + def handle_start_play(e): + page.add(ft.Text(f"play audio file: {audio_play.src}")) + audio_play.src = "test-audio-file.wav" + audio_play.update() + audio_play.play() + print(f"audio recorder: {audio_rec}") page.overlay.append(audio_rec) page.update() + log = ft.Text(":") page.add( ft.ElevatedButton("Start Audio Recorder", on_click=handle_start_recording), @@ -66,6 +79,12 @@ def handle_state_change(e): ft.ElevatedButton("Resume Recording", on_click=handle_resume), ft.ElevatedButton("Test AudioEncodings", on_click=handle_audio_encoding_test), ft.ElevatedButton("Has Permission", on_click=handle_has_permission), + ft.ElevatedButton("Play", on_click=handle_start_play), + ft.ElevatedButton("Pause", on_click=lambda _: audio_play.pause()), + ft.ElevatedButton("Resume", on_click=lambda _: audio_play.resume()), + ft.ElevatedButton("Release", on_click=lambda _: audio_play.release()), + ft.ElevatedButton("Seek 2s", on_click=lambda _: audio_play.seek(2000)), + log, ) diff --git a/python/controls/utility/audio/audio-player-slider.py b/python/controls/utility/audio/audio-player-slider.py index 81662b07..b2663f3c 100644 --- a/python/controls/utility/audio/audio-player-slider.py +++ b/python/controls/utility/audio/audio-player-slider.py @@ -45,9 +45,11 @@ def get_duration(_): def get_position(_): print("Current position:", audio1.get_current_position()) - + def position_changed(e): - s.value=??? + print(f"e: {e}") + print(f"e.data: {e.data}") + # s.value=??? audio1 = ft.Audio( src=url, From a4fe8ae175f603290552e6fdfccb59770eb03022 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Wed, 16 Apr 2025 08:37:56 -0700 Subject: [PATCH 80/81] fix ads example --- python/controls/information-displays/ads/ads-basic-example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/controls/information-displays/ads/ads-basic-example.py b/python/controls/information-displays/ads/ads-basic-example.py index a85c17cb..553f0329 100644 --- a/python/controls/information-displays/ads/ads-basic-example.py +++ b/python/controls/information-displays/ads/ads-basic-example.py @@ -59,7 +59,7 @@ def display_new_banner_ad(): page.appbar = ft.AppBar( adaptive=True, title=ft.Text("Mobile Ads Playground"), - bgcolor=Colors.LIGHT_BLUE_300, + bgcolor=ft.Colors.LIGHT_BLUE_300, ) page.add( ft.OutlinedButton("Show InterstitialAd", on_click=lambda e: iad.show()), From 0c4f7ce4b3ce6a7128647593a42ef9fdf3191f41 Mon Sep 17 00:00:00 2001 From: Owen McDonnell Date: Thu, 17 Apr 2025 16:04:12 -0700 Subject: [PATCH 81/81] add webview example --- .../web-view/web-view-example.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 python/controls/information-displays/web-view/web-view-example.py diff --git a/python/controls/information-displays/web-view/web-view-example.py b/python/controls/information-displays/web-view/web-view-example.py new file mode 100644 index 00000000..050b85a4 --- /dev/null +++ b/python/controls/information-displays/web-view/web-view-example.py @@ -0,0 +1,16 @@ +import flet as ft +import flet_webview as ftwv + + +def main(page: ft.Page): + wv = ftwv.WebView( + url="https://flet.dev", + on_page_started=lambda _: print("Page started"), + on_page_ended=lambda _: print("Page ended"), + on_web_resource_error=lambda e: print("Page error:", e.data), + expand=True, + ) + page.add(wv) + + +ft.app(main)