120 lines
5.2 KiB
Python
120 lines
5.2 KiB
Python
# radian/gui/main_window.py
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk
|
|
from typing import Dict, Any, Optional, Callable
|
|
from PIL import Image, ImageTk # Assicurati di aver installato Pillow: pip install Pillow
|
|
|
|
class MainWindow(tk.Tk):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
self.title("RADIAN - Radar Data Integration & Analysis Network")
|
|
self._set_fullscreen()
|
|
|
|
# Store PhotoImage objects to prevent garbage collection
|
|
self.photo_images: Dict[str, ImageTk.PhotoImage] = {}
|
|
|
|
main_frame = ttk.Frame(self)
|
|
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
|
|
|
main_frame.rowconfigure(0, weight=1)
|
|
main_frame.columnconfigure(0, weight=1, minsize=250) # Colonna lista, peso minore ma con minsize
|
|
main_frame.columnconfigure(1, weight=5)
|
|
|
|
self._create_components_list_area(main_frame)
|
|
|
|
right_panel = ttk.Frame(main_frame)
|
|
right_panel.grid(row=0, column=1, sticky="nsew")
|
|
right_panel.rowconfigure(0, weight=3)
|
|
right_panel.rowconfigure(1, weight=1)
|
|
right_panel.columnconfigure(0, weight=1)
|
|
|
|
self._create_content_area(right_panel)
|
|
self._create_log_area(right_panel)
|
|
|
|
def _set_fullscreen(self):
|
|
self.state('zoomed')
|
|
|
|
def _create_components_list_area(self, parent: ttk.Frame):
|
|
list_frame = ttk.LabelFrame(parent, text="Components", padding="10")
|
|
list_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
|
list_frame.rowconfigure(0, weight=1)
|
|
list_frame.columnconfigure(0, weight=1)
|
|
|
|
# --- Nuovo approccio con Canvas e Frame scrollabile ---
|
|
canvas = tk.Canvas(list_frame)
|
|
scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=canvas.yview)
|
|
|
|
self.scrollable_frame = ttk.Frame(canvas)
|
|
|
|
self.scrollable_frame.bind(
|
|
"<Configure>",
|
|
lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
|
|
)
|
|
|
|
canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
|
|
canvas.configure(yscrollcommand=scrollbar.set)
|
|
|
|
canvas.grid(row=0, column=0, sticky="nsew")
|
|
scrollbar.grid(row=0, column=1, sticky="ns")
|
|
|
|
def add_component_to_list(self, component_id: str, name: str, icon_path: Optional[str], callback: Callable):
|
|
"""Adds a single, rich component widget to the scrollable list."""
|
|
|
|
# Frame per il singolo componente
|
|
comp_frame = ttk.Frame(self.scrollable_frame, padding=5)
|
|
comp_frame.pack(fill="x", expand=True, pady=2)
|
|
|
|
# Carica l'icona
|
|
try:
|
|
if icon_path:
|
|
img = Image.open(icon_path).resize((48, 48), Image.Resampling.LANCZOS)
|
|
photo = ImageTk.PhotoImage(img)
|
|
self.photo_images[component_id] = photo # Salva il riferimento!
|
|
icon_label = ttk.Label(comp_frame, image=photo)
|
|
icon_label.grid(row=0, column=0, rowspan=2, padx=(0, 10))
|
|
else:
|
|
# Placeholder se non c'è icona
|
|
icon_label = ttk.Label(comp_frame, text="⚫", font=("Segoe UI", 24))
|
|
icon_label.grid(row=0, column=0, rowspan=2, padx=(0, 10))
|
|
except Exception as e:
|
|
print(f"Error loading icon for {name}: {e}")
|
|
icon_label = ttk.Label(comp_frame, text="!", font=("Segoe UI", 24))
|
|
icon_label.grid(row=0, column=0, rowspan=2, padx=(0, 10))
|
|
|
|
# Nome del componente
|
|
name_label = ttk.Label(comp_frame, text=name, font=("Segoe UI", 12, "bold"))
|
|
name_label.grid(row=0, column=1, sticky="w")
|
|
|
|
# --- Eventi di Click ---
|
|
# Usa una lambda per passare l'id del componente al callback
|
|
click_handler = lambda e, c_id=component_id: callback(c_id)
|
|
comp_frame.bind("<Button-1>", click_handler)
|
|
name_label.bind("<Button-1>", click_handler)
|
|
icon_label.bind("<Button-1>", click_handler)
|
|
|
|
def _create_content_area(self, parent: ttk.Frame):
|
|
content_frame = ttk.LabelFrame(parent, text="Component View", padding="10")
|
|
content_frame.grid(row=0, column=0, sticky="nsew", padx=5, pady=5)
|
|
self.content_frame = content_frame
|
|
|
|
def _create_log_area(self, parent: ttk.Frame):
|
|
log_frame = ttk.LabelFrame(parent, text="System Log", padding="10")
|
|
log_frame.grid(row=1, column=0, sticky="nsew", padx=5, pady=5)
|
|
log_frame.rowconfigure(0, weight=1)
|
|
log_frame.columnconfigure(0, weight=1)
|
|
log_text_widget = tk.Text(log_frame, wrap=tk.WORD, state=tk.DISABLED, height=10)
|
|
log_text_widget.grid(row=0, column=0, sticky="nsew")
|
|
scrollbar = ttk.Scrollbar(log_frame, orient=tk.VERTICAL, command=log_text_widget.yview)
|
|
scrollbar.grid(row=0, column=1, sticky="ns")
|
|
log_text_widget.configure(yscrollcommand=scrollbar.set)
|
|
self.log_text = log_text_widget
|
|
|
|
def clear_content_area(self):
|
|
for widget in self.content_frame.winfo_children():
|
|
widget.destroy()
|
|
|
|
def display_component_ui(self, component_ui_frame: tk.Frame):
|
|
self.clear_content_area()
|
|
component_ui_frame.pack(fill=tk.BOTH, expand=True) |