S1005403_RisCC/target_simulator/gui/scenario_controls_frame.py
2025-10-02 14:37:38 +02:00

119 lines
4.3 KiB
Python

# target_simulator/gui/scenario_controls_frame.py
"""
A frame containing widgets for managing scenarios.
"""
import tkinter as tk
from tkinter import ttk, simpledialog, messagebox
from typing import Callable, List
class ScenarioControlsFrame(ttk.LabelFrame):
"""Frame for scenario management controls."""
def __init__(self, master, *,
load_scenario_command: Callable[[str], None],
save_as_command: Callable[[str], None],
update_command: Callable[[str], None],
delete_command: Callable[[str], None],
send_scenario_command: Callable[[], None] = None):
super().__init__(master, text="Scenario Controls")
self._load_scenario_command = load_scenario_command
self._save_as_command = save_as_command
self._update_command = update_command
self._delete_command = delete_command
self._send_scenario_command = send_scenario_command
self.current_scenario = tk.StringVar()
# --- Widgets ---
top_frame = ttk.Frame(self)
top_frame.pack(fill=tk.X, padx=5, pady=(5, 2))
scenario_label = ttk.Label(top_frame, text="Scenario:")
scenario_label.pack(side=tk.LEFT, padx=(0, 5))
self.scenario_combobox = ttk.Combobox(
top_frame,
textvariable=self.current_scenario,
state="readonly"
)
self.scenario_combobox.pack(side=tk.LEFT, expand=True, fill=tk.X)
self.scenario_combobox.bind("<<ComboboxSelected>>", self._on_scenario_select)
# Buttons next to combobox for compact layout
if self._send_scenario_command:
send_btn = ttk.Button(top_frame, text="Send Scenario", command=self._send_scenario_command)
send_btn.pack(side=tk.LEFT, padx=5)
self.save_as_button = ttk.Button(
top_frame, text="Save As...", command=self._on_save_as
)
self.save_as_button.pack(side=tk.LEFT, padx=(10, 5))
self.update_button = ttk.Button(
top_frame, text="Update", command=self._on_update
)
self.update_button.pack(side=tk.LEFT, padx=5)
self.delete_button = ttk.Button(
top_frame, text="Delete", command=self._on_delete
)
self.delete_button.pack(side=tk.LEFT, padx=5)
def _on_scenario_select(self, event):
"""Callback for when a scenario is selected from the combobox."""
scenario_name = self.current_scenario.get()
if scenario_name:
self._load_scenario_command(scenario_name)
def _on_save_as(self):
"""Handle the 'Save As' button click."""
scenario_name = simpledialog.askstring(
"Save Scenario As",
"Enter a name for the new scenario:",
parent=self
)
if scenario_name:
self._save_as_command(scenario_name)
def _on_update(self):
"""Handle the 'Update' button click."""
scenario_name = self.current_scenario.get()
if not scenario_name:
messagebox.showwarning("No Scenario Selected", "Please select a scenario to update.", parent=self)
return
self._update_command(scenario_name)
def _on_delete(self):
"""Handle the 'Delete' button click."""
scenario_name = self.current_scenario.get()
if not scenario_name:
messagebox.showwarning("No Scenario Selected", "Please select a scenario to delete.", parent=self)
return
if messagebox.askyesno(
"Confirm Delete",
f"Are you sure you want to delete the scenario '{scenario_name}'?",
parent=self
):
self._delete_command(scenario_name)
def update_scenario_list(self, scenarios: List[str], select_scenario: str = None):
"""
Updates the list of scenarios in the combobox.
Args:
scenarios: A list of scenario names.
select_scenario: The name of the scenario to select after updating, if any.
"""
self.scenario_combobox['values'] = scenarios
if select_scenario and select_scenario in scenarios:
self.current_scenario.set(select_scenario)
elif scenarios:
self.current_scenario.set(scenarios[0]) # Select the first one
else:
self.current_scenario.set("")