SXXXXXXX_FlightMonitor/flightmonitor/gui/panels/area_management_panel.py

123 lines
5.4 KiB
Python

# FlightMonitor/gui/panels/area_management_panel.py
"""
Panel for managing the geographic area of interest (Bounding Box)
and area profiles.
"""
import tkinter as tk
from tkinter import ttk
from typing import Dict, Any, Optional
from ...utils.logger import get_logger
from ...data import config as app_config
from ...map.map_utils import _is_valid_bbox_dict
module_logger = get_logger(__name__)
class AreaManagementPanel:
"""
Manages the GUI elements for Bounding Box input and area profiles.
"""
def __init__(self, parent_frame: ttk.Frame, controller: Any):
"""
Initializes the AreaManagementPanel.
Args:
parent_frame: The parent ttk.Frame where this panel will be placed.
controller: The application controller instance.
"""
self.parent_frame = parent_frame
self.controller = controller
# --- Tkinter Variables ---
# Creiamo le variabili, ma le popoliamo subito dopo.
self.lat_min_var = tk.StringVar()
self.lon_min_var = tk.StringVar()
self.lat_max_var = tk.StringVar()
self.lon_max_var = tk.StringVar()
# Popoliamo le variabili con i valori di default dal config
self.lat_min_var.set(str(app_config.DEFAULT_BBOX_LAT_MIN))
self.lon_min_var.set(str(app_config.DEFAULT_BBOX_LON_MIN))
self.lat_max_var.set(str(app_config.DEFAULT_BBOX_LAT_MAX))
self.lon_max_var.set(str(app_config.DEFAULT_BBOX_LON_MAX))
self._build_ui()
module_logger.debug("AreaManagementPanel initialized.")
def _build_ui(self):
"""Builds the UI elements for area management."""
# Bounding Box Input Frame
self.bbox_frame = ttk.LabelFrame(
self.parent_frame,
text="Geographic Area (Bounding Box)",
padding=(10, 5)
)
self.bbox_frame.pack(side=tk.TOP, fill=tk.X, expand=True, padx=2, pady=(0,5))
self.bbox_frame.columnconfigure(1, weight=1)
self.bbox_frame.columnconfigure(3, weight=1)
ttk.Label(self.bbox_frame, text="Lat Min:").grid(row=0, column=0, padx=(0, 2), pady=2, sticky=tk.W)
self.lat_min_entry = ttk.Entry(self.bbox_frame, textvariable=self.lat_min_var)
self.lat_min_entry.grid(row=0, column=1, padx=(0, 5), pady=2, sticky=tk.EW)
ttk.Label(self.bbox_frame, text="Lon Min:").grid(row=0, column=2, padx=(5, 2), pady=2, sticky=tk.W)
self.lon_min_entry = ttk.Entry(self.bbox_frame, textvariable=self.lon_min_var)
self.lon_min_entry.grid(row=0, column=3, padx=(0, 0), pady=2, sticky=tk.EW)
ttk.Label(self.bbox_frame, text="Lat Max:").grid(row=1, column=0, padx=(0, 2), pady=2, sticky=tk.W)
self.lat_max_entry = ttk.Entry(self.bbox_frame, textvariable=self.lat_max_var)
self.lat_max_entry.grid(row=1, column=1, padx=(0, 5), pady=2, sticky=tk.EW)
ttk.Label(self.bbox_frame, text="Lon Max:").grid(row=1, column=2, padx=(5, 2), pady=2, sticky=tk.W)
self.lon_max_entry = ttk.Entry(self.bbox_frame, textvariable=self.lon_max_var)
self.lon_max_entry.grid(row=1, column=3, padx=(0, 0), pady=2, sticky=tk.EW)
# Placeholder for Profile Management
self.profiles_frame = ttk.LabelFrame(
self.parent_frame, text="Area Profiles", padding=(10, 5)
)
self.profiles_frame.pack(side=tk.TOP, fill=tk.X, expand=True, padx=2, pady=5)
ttk.Label(self.profiles_frame, text="Profile management coming soon...").pack()
def get_bounding_box_input(self) -> Optional[Dict[str, float]]:
"""
Retrieves and validates the bounding box coordinates from the GUI input fields.
Returns a dictionary {lat_min, lon_min, lat_max, lon_max} or None if invalid.
"""
try:
bbox_candidate = {
"lat_min": float(self.lat_min_var.get()),
"lon_min": float(self.lon_min_var.get()),
"lat_max": float(self.lat_max_var.get()),
"lon_max": float(self.lon_max_var.get()),
}
if _is_valid_bbox_dict(bbox_candidate):
return bbox_candidate
else:
module_logger.warning(f"BBox from GUI failed validation: {bbox_candidate}")
return None
except (ValueError, TypeError):
module_logger.warning("Invalid numeric format in BBox GUI fields.")
return None
def update_bbox_gui_fields(self, bbox_dict: Dict[str, float]):
"""Updates the bounding box input fields in the GUI."""
if bbox_dict and _is_valid_bbox_dict(bbox_dict):
decimals = getattr(app_config, "COORDINATE_DECIMAL_PLACES", 5)
self.lat_min_var.set(f"{bbox_dict['lat_min']:.{decimals}f}")
self.lon_min_var.set(f"{bbox_dict['lon_min']:.{decimals}f}")
self.lat_max_var.set(f"{bbox_dict['lat_max']:.{decimals}f}")
self.lon_max_var.set(f"{bbox_dict['lon_max']:.{decimals}f}")
else:
self.lat_min_var.set("")
self.lon_min_var.set("")
self.lat_max_var.set("")
self.lon_max_var.set("")
def set_controls_state(self, enabled: bool):
"""Enables or disables all controls in this panel."""
state = tk.NORMAL if enabled else tk.DISABLED
for entry in [self.lat_min_entry, self.lon_min_entry, self.lat_max_entry, self.lon_max_entry]:
if entry.winfo_exists():
entry.config(state=state)
# Future: Add profile buttons here