S1005403_RisCC/target_simulator/gui/scenario_controls_frame.py

139 lines
4.9 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,
*,
main_view,
load_scenario_command: Callable[[str], None],
save_as_command: Callable[[str], None],
delete_command: Callable[[str], None],
new_scenario_command: Callable[[str], None],
send_scenario_command: Callable[[], None] = None,
):
super().__init__(master, text="Scenario Controls")
self.main_view = main_view
self._load_scenario_command = load_scenario_command
self._save_as_command = save_as_command
self._delete_command = delete_command
self._new_scenario_command = new_scenario_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.new_button = ttk.Button(top_frame, text="New...", command=self._on_new)
self.new_button.pack(side=tk.LEFT, padx=(10, 5))
self.save_button = ttk.Button(top_frame, text="Save", command=self._on_save)
self.save_button.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=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_save(self):
"""Handle the 'Save' button click: overwrite the selected scenario."""
scenario_name = self.current_scenario.get()
if not scenario_name:
messagebox.showwarning(
"No Scenario Selected", "Please select a scenario to save.", parent=self
)
return
# Call the new save method in MainView
self.main_view._on_save_scenario(scenario_name)
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_new(self):
"""Handle the 'New' button click."""
scenario_name = simpledialog.askstring(
"New Scenario", "Enter a name for the new scenario:", parent=self
)
if scenario_name:
self._new_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_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("")