Alpha4 polish griglie e login

This commit is contained in:
2026-06-16 15:51:50 +02:00
parent 29900b8b09
commit be7ce700d1
10 changed files with 273 additions and 97 deletions

View File

@@ -70,6 +70,14 @@ from busy_overlay import InlineBusyOverlay
from gestione_aree import AsyncRunner
from locale_text import load_locale_catalog, text as loc_text
from ui_theme import theme_color, theme_font, theme_section, theme_value
from ui_tables import (
TABLE_HEADER_BG,
TABLE_HEADER_FG,
TABLE_ROW_EVEN,
TABLE_ROW_ODD,
apply_tksheet_visual_style,
apply_tksheet_zebra,
)
from user_session import UserSession
from version_info import module_version, versioned_title
from window_placement import place_window_fullsize_below_parent_later
@@ -391,13 +399,14 @@ class ScrollTable(ctk.CTkFrame):
self._sort_key: Optional[str] = None
self._sort_reverse = False
self.total_w = sum(c.width for c in self.columns)
self._vbar_visible = False
self.grid_rowconfigure(1, weight=1)
self.grid_columnconfigure(0, weight=1)
# header
self.h_canvas = tk.Canvas(self, height=ROW_H, highlightthickness=0, bd=0)
self.h_inner = ctk.CTkFrame(self.h_canvas, fg_color="#f3f3f3",
self.h_canvas = tk.Canvas(self, height=ROW_H, highlightthickness=0, bd=0, bg=TABLE_HEADER_BG)
self.h_inner = ctk.CTkFrame(self.h_canvas, fg_color=TABLE_HEADER_BG,
height=ROW_H, width=self.total_w)
self.h_canvas.create_window((0,0), window=self.h_inner, anchor="nw",
width=self.total_w, height=ROW_H)
@@ -414,7 +423,6 @@ class ScrollTable(ctk.CTkFrame):
# scrollbars
self.vbar = tk.Scrollbar(self, orient="vertical", command=self.b_canvas.yview)
self.xbar = tk.Scrollbar(self, orient="horizontal", command=self._xscroll_both)
self.vbar.grid(row=1, column=1, sticky="ns")
self.xbar.grid(row=2, column=0, sticky="ew")
# link scroll
@@ -436,14 +444,14 @@ class ScrollTable(ctk.CTkFrame):
for w in self.h_inner.winfo_children():
w.destroy()
row = ctk.CTkFrame(self.h_inner, fg_color="#f3f3f3",
row = ctk.CTkFrame(self.h_inner, fg_color=TABLE_HEADER_BG,
height=ROW_H, width=self.total_w)
row.pack(fill="x", expand=False)
row.pack_propagate(False)
for col in self.columns:
holder = ctk.CTkFrame(
row, fg_color="#f3f3f3",
row, fg_color=TABLE_HEADER_BG,
width=col.width, height=ROW_H,
border_width=1, border_color=self.GRID_COLOR
)
@@ -454,7 +462,7 @@ class ScrollTable(ctk.CTkFrame):
if col.key == self._sort_key:
header_text = f"{col.title} {'' if self._sort_reverse else ''}"
lbl = ctk.CTkLabel(holder, text=header_text, anchor="w")
lbl = ctk.CTkLabel(holder, text=header_text, anchor="w", text_color=TABLE_HEADER_FG)
lbl.pack(fill="both", padx=(self.PADX_L, self.PADX_R), pady=self.PADY)
if self.on_header_click and col.key != "__check__":
@@ -475,10 +483,27 @@ class ScrollTable(ctk.CTkFrame):
"""Keep the scroll region aligned with the current body content width."""
self.b_canvas.itemconfigure(self.body_window, width=self.total_w)
sr = self.b_canvas.bbox("all")
content_height = int(sr[3]) if sr else 0
if sr:
self.b_canvas.configure(scrollregion=(0,0,max(self.total_w, sr[2]), sr[3]))
else:
self.b_canvas.configure(scrollregion=(0,0,self.total_w,0))
self._update_vertical_scrollbar(content_height)
def _update_vertical_scrollbar(self, content_height: int):
"""Show the vertical scrollbar only when body rows exceed the visible area."""
try:
visible_height = max(1, int(self.b_canvas.winfo_height()))
except Exception:
visible_height = 1
needs_scroll = content_height > visible_height + 2
if needs_scroll and not self._vbar_visible:
self.vbar.grid(row=1, column=1, sticky="ns")
self._vbar_visible = True
elif not needs_scroll and self._vbar_visible:
self.vbar.grid_remove()
self._vbar_visible = False
self.b_canvas.yview_moveto(0)
def _on_body_configure(self):
"""React to body resize events by syncing dimensions and header scroll."""
@@ -513,8 +538,11 @@ class ScrollTable(ctk.CTkFrame):
delta = getattr(event, "delta", 0)
if delta == 0:
return
if not self._vbar_visible:
return "break"
step = -1 if delta > 0 else 1
self.b_canvas.yview_scroll(step, "units")
return "break"
def clear_rows(self):
"""Remove all rendered body rows."""
@@ -530,14 +558,15 @@ class ScrollTable(ctk.CTkFrame):
checkbox_builder: Optional[Callable[[tk.Widget], ctk.CTkCheckBox]] = None,
):
"""Append one row to the table body."""
row = ctk.CTkFrame(self.b_inner, fg_color="transparent",
row_bg = TABLE_ROW_EVEN if row_index % 2 == 0 else TABLE_ROW_ODD
row = ctk.CTkFrame(self.b_inner, fg_color=row_bg,
height=ROW_H, width=self.total_w)
row.pack(fill="x", expand=False)
row.pack_propagate(False)
for i, col in enumerate(self.columns):
holder = ctk.CTkFrame(
row, fg_color="transparent",
row, fg_color=row_bg,
width=col.width, height=ROW_H,
border_width=1, border_color=self.GRID_COLOR
)
@@ -549,10 +578,10 @@ class ScrollTable(ctk.CTkFrame):
cb = checkbox_builder(holder)
cb.pack(padx=(self.PADX_L, self.PADX_R), pady=self.PADY, anchor="w")
else:
ctk.CTkLabel(holder, text="").pack(fill="both")
ctk.CTkLabel(holder, text="", fg_color=row_bg).pack(fill="both")
else:
anchor = (anchors[i] if anchors else col.anchor)
ctk.CTkLabel(holder, text=values[i], anchor=anchor).pack(
ctk.CTkLabel(holder, text=values[i], anchor=anchor, fg_color=row_bg, text_color="#111827").pack(
fill="both", padx=(self.PADX_L, self.PADX_R), pady=self.PADY
)
@@ -696,6 +725,7 @@ class GestionePickingListFrame(ctk.CTkFrame):
self.detail_sheet.change_theme("light green")
self.detail_sheet.enable_bindings("all")
self.detail_sheet.headers(self._detail_headers(), redraw=False)
apply_tksheet_visual_style(self.detail_sheet)
self.detail_sheet.bind("<ButtonRelease-1>", self._on_detail_sheet_left_click, add="+")
self.detail_sheet.grid(row=0, column=0, sticky="nsew")
@@ -736,8 +766,10 @@ class GestionePickingListFrame(ctk.CTkFrame):
data,
reset_col_positions=True,
reset_row_positions=True,
redraw=True,
redraw=False,
)
apply_tksheet_visual_style(self.detail_sheet)
apply_tksheet_zebra(self.detail_sheet, len(data))
self.detail_sheet.set_all_column_widths()
def _detail_sort_value(self, row: Dict[str, Any], key: str):