# target_simulator/gui/settings_window.py """ A Toplevel window for configuring application settings, like serial connection. """ import tkinter as tk from tkinter import ttk, messagebox from core.serial_communicator import SerialCommunicator class SettingsWindow(tk.Toplevel): """ A dialog window for connection settings. """ def __init__(self, master, communicator: SerialCommunicator): super().__init__(master) self.master_view = master self.communicator = communicator # --- Window Configuration --- self.title("Connection Settings") self.transient(master) # Keep this window on top of the main one self.grab_set() # Modal: block interaction with the main window self.resizable(False, False) self.selected_port = tk.StringVar() # --- UI Creation --- main_frame = ttk.Frame(self, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) ttk.Label(main_frame, text="Select Serial Port:").grid(row=0, column=0, sticky=tk.W, pady=5) self.port_combobox = ttk.Combobox(main_frame, textvariable=self.selected_port, state="readonly") self.port_combobox.grid(row=0, column=1, padx=5, sticky=tk.EW) self._populate_ports() # --- Buttons --- button_frame = ttk.Frame(main_frame) button_frame.grid(row=2, column=0, columnspan=2, pady=10) ttk.Button(button_frame, text="Test Connection", command=self._on_test_connection).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="Save", command=self._on_save).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="Cancel", command=self.destroy).pack(side=tk.LEFT, padx=5) # Center the window self.update_idletasks() x = master.winfo_x() + (master.winfo_width() // 2) - (self.winfo_width() // 2) y = master.winfo_y() + (master.winfo_height() // 2) - (self.winfo_height() // 2) self.geometry(f"+{x}+{y}") def _populate_ports(self): """Fetches and displays available serial ports.""" available_ports = self.communicator.list_available_ports() if available_ports: self.port_combobox['values'] = available_ports self.selected_port.set(available_ports[0]) else: self.port_combobox['values'] = ['No ports found'] self.selected_port.set('No ports found') def _on_test_connection(self): """Tests the connection to the selected port.""" port = self.selected_port.get() if not port or "No ports" in port: messagebox.showerror("Error", "No serial port selected.", parent=self) return if self.communicator.connect(port): messagebox.showinfo("Success", f"Successfully connected to {port}.", parent=self) self.communicator.disconnect() else: messagebox.showerror("Failure", f"Failed to connect to {port}.", parent=self) def _on_save(self): """Saves the selected settings and closes the window.""" port_to_save = self.selected_port.get() if not port_to_save or "No ports" in port_to_save: messagebox.showerror("Error", "Cannot save, no valid port selected.", parent=self) return # Call back to the main view to update its configuration self.master_view.update_connection_settings(port_to_save) self.destroy()