66 lines
1.6 KiB
Python
66 lines
1.6 KiB
Python
|
|
"""Общие UI-хелперы (Flet ≥ 0.80: show_dialog/pop_dialog, SnackBar через show_dialog)."""
|
||
|
|
import asyncio
|
||
|
|
|
||
|
|
import flet as ft
|
||
|
|
|
||
|
|
|
||
|
|
def confirm_dialog(page: ft.Page, title: str, text: str, on_confirm, danger: bool = True):
|
||
|
|
"""Модальный диалог подтверждения."""
|
||
|
|
def close(e=None):
|
||
|
|
page.pop_dialog()
|
||
|
|
|
||
|
|
def yes(e):
|
||
|
|
page.pop_dialog()
|
||
|
|
on_confirm()
|
||
|
|
|
||
|
|
dlg = ft.AlertDialog(
|
||
|
|
modal=True,
|
||
|
|
title=ft.Text(title),
|
||
|
|
content=ft.Text(text),
|
||
|
|
actions=[
|
||
|
|
ft.TextButton("Отмена", on_click=close),
|
||
|
|
ft.FilledButton(
|
||
|
|
"Подтвердить", on_click=yes,
|
||
|
|
style=ft.ButtonStyle(bgcolor=ft.Colors.RED_700 if danger else None),
|
||
|
|
),
|
||
|
|
],
|
||
|
|
)
|
||
|
|
page.show_dialog(dlg)
|
||
|
|
|
||
|
|
|
||
|
|
def snack(page: ft.Page, text: str, error: bool = False):
|
||
|
|
page.show_dialog(ft.SnackBar(
|
||
|
|
ft.Text(text),
|
||
|
|
bgcolor=ft.Colors.RED_700 if error else ft.Colors.GREEN_700,
|
||
|
|
open=True,
|
||
|
|
))
|
||
|
|
|
||
|
|
|
||
|
|
def log_view(initial: str = "") -> ft.ListView:
|
||
|
|
"""Скроллящаяся панель лога."""
|
||
|
|
return ft.ListView(expand=True, spacing=2, auto_scroll=True)
|
||
|
|
|
||
|
|
|
||
|
|
def append_log(lv: ft.ListView, line: str):
|
||
|
|
lv.controls.append(
|
||
|
|
ft.Text(line, size=12, font_family="Consolas", selectable=True)
|
||
|
|
)
|
||
|
|
try:
|
||
|
|
lv.update()
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
def open_dialog(page: ft.Page, dlg: ft.AlertDialog):
|
||
|
|
page.show_dialog(dlg)
|
||
|
|
|
||
|
|
|
||
|
|
def close_dialog(page: ft.Page):
|
||
|
|
page.pop_dialog()
|
||
|
|
|
||
|
|
|
||
|
|
def fmt_mb(v: float) -> str:
|
||
|
|
if v >= 1024:
|
||
|
|
return f"{v/1024:.1f} ГБ"
|
||
|
|
return f"{v:.0f} МБ"
|