From 833a2a5a47ad13fb8386761b57933d108841ed90 Mon Sep 17 00:00:00 2001 From: VALLONGOL Date: Fri, 7 Nov 2025 13:24:49 +0100 Subject: [PATCH] spostato la gestione delle scenario fuori dal noteboox tab --- .vscode/settings.json | 4 ++- settings.json | 2 +- target_simulator/gui/main_view.py | 59 +++++++++++++++++++++++++------ todo.md | 8 ++--- 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 9b38853..2ddce20 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,7 @@ "tests" ], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true + "python.testing.pytestEnabled": true, + "todo-tree.tree.showBadges": false, + "todo-tree.tree.showCountsInTree": true } \ No newline at end of file diff --git a/settings.json b/settings.json index 7c5e794..c457bec 100644 --- a/settings.json +++ b/settings.json @@ -3,7 +3,7 @@ "scan_limit": 60, "max_range": 100, "geometry": "1409x1110+159+173", - "last_selected_scenario": "corto", + "last_selected_scenario": "scenario3", "connection": { "target": { "type": "sfp", diff --git a/target_simulator/gui/main_view.py b/target_simulator/gui/main_view.py index 142141a..473c5a4 100644 --- a/target_simulator/gui/main_view.py +++ b/target_simulator/gui/main_view.py @@ -126,9 +126,30 @@ class MainView(tk.Tk): # --- Post-UI Initialization --- self._initialize_communicators() self._load_scenarios_into_ui() + # Determine initial scenario to load. Prefer last_selected_scenario + # from settings if it exists and is valid; otherwise use the + # combobox selection (which `update_scenario_list` set to the + # first available scenario when no explicit selection was provided). last_scenario = settings.get("last_selected_scenario") - if last_scenario and last_scenario in self.config_manager.get_scenario_names(): - self._on_load_scenario(last_scenario) + scenario_to_load = None + try: + available = self.config_manager.get_scenario_names() + if last_scenario and last_scenario in available: + scenario_to_load = last_scenario + else: + # fallback to whatever the scenario_controls combobox currently + # has selected (update_scenario_list should have set it) + if hasattr(self, "scenario_controls") and getattr( + self.scenario_controls, "current_scenario", None + ): + val = self.scenario_controls.current_scenario.get() + if val: + scenario_to_load = val + except Exception: + scenario_to_load = None + + if scenario_to_load: + self._on_load_scenario(scenario_to_load) self._update_window_title() self.protocol("WM_DELETE_WINDOW", self._on_closing) @@ -145,7 +166,7 @@ class MainView(tk.Tk): self.h_pane = ttk.PanedWindow(v_pane, orient=tk.HORIZONTAL) v_pane.add(self.h_pane, weight=4) - # --- Right Pane (connection panel + PPI) --- + # --- Right Pane (connection panel + PPI) --- right_container = ttk.Frame(self.h_pane) self.h_pane.add(right_container, weight=2) @@ -167,15 +188,10 @@ class MainView(tk.Tk): left_pane_container = ttk.Frame(self.h_pane) self.h_pane.add(left_pane_container, weight=1) - left_notebook = ttk.Notebook(left_pane_container) - left_notebook.pack(fill=tk.BOTH, expand=True) - - # --- TAB 1: SCENARIO CONFIG --- - scenario_tab = ttk.Frame(left_notebook) - left_notebook.add(scenario_tab, text="Scenario Config") - + # Place the ScenarioControlsFrame above the notebook so it is always visible + # regardless of which tab is selected. self.scenario_controls = ScenarioControlsFrame( - scenario_tab, + left_pane_container, main_view=self, load_scenario_command=self._on_load_scenario, save_as_command=self._on_save_scenario_as, @@ -184,6 +200,14 @@ class MainView(tk.Tk): ) self.scenario_controls.pack(fill=tk.X, expand=False, padx=5, pady=(5, 5)) + left_notebook = ttk.Notebook(left_pane_container) + left_notebook.pack(fill=tk.BOTH, expand=True) + + # --- TAB 1: Editing scenario (keeps scenario-related tools in the main + # controls area above the notebook; the tab itself is used for editing) + scenario_tab = ttk.Frame(left_notebook) + left_notebook.add(scenario_tab, text="Editing scenario") + self.target_list = TargetListFrame( scenario_tab, targets_changed_callback=self._on_targets_changed ) @@ -368,6 +392,19 @@ class MainView(tk.Tk): if self._start_in_progress_main: self.logger.info("Start already in progress; ignoring duplicate request.") return + # Ensure the scenario currently selected in the ScenarioControlsFrame + # is loaded before starting the simulation. This makes the UI's + # visible combobox the single source-of-truth for the selected scenario. + try: + if hasattr(self, "scenario_controls") and getattr( + self.scenario_controls, "current_scenario", None + ): + sel = self.scenario_controls.current_scenario.get() + if sel and sel != self.current_scenario_name: + self._on_load_scenario(sel) + except Exception: + # Non-fatal: proceed with existing scenario if anything goes wrong + pass self._start_in_progress_main = True self.simulation_controller.start_simulation(self) diff --git a/todo.md b/todo.md index b768a8a..e3897c5 100644 --- a/todo.md +++ b/todo.md @@ -1,13 +1,13 @@ # ToDo List - [x] Inserire dati di navigazione dell'ownship nel file di salvataggio della simulazione -- [ ] muovere il ppi in base al movimento dell'ownship +- [x] muovere il ppi in base al movimento dell'ownship - [x] Aggiungere tabella dei dati cinematici dell'ownship nella schermata della simulazione - [ ] Mettere nel file di comando inviato al srver l'ultimo timetag che è arrivato dal server - [ ] Implementare il comando ping con numero indentificativo per verificare i tempi di risposta - [ ] Mettere configurazione cifre decimali inviate nei json al server - [ ] Se lat/lon passato dal server non è valido posso fare come fa mcs, integrare sul tempo e simulare il movimente dell'ownship -- [ ] poter scegliere se visualizzare la mappa ppi fissa a nord o fissa con l'heading dell'ownship +- [x] poter scegliere se visualizzare la mappa ppi fissa a nord o fissa con l'heading dell'ownship - [x] salvare nei file delle simulazione i dati in lat/lon dei target così da poter piazzare su mappa oepnstreetmap le traiettorie e vedere come si è mosso lo scenario durante la simulazione - [ ] vedere anche la simulazione in 3d usando le mappe dem e le mappe operstreetmap. - [ ] Scrivere test unitari @@ -17,14 +17,14 @@ - [ ] funzione di sincronizzazione: è stato aggiunto al server la possibilità di gestire dei messaggi che sono di tipo SY (tag) che sono fatti per gestire il sincronismo tra client e server. In questa nuova tipologia di messaggi io invio un mio timetag che poi il server mi restituirà subito appena lo riceve, facendo così sappiamo in quanto tempo il messaggio che spedisco è arrivato al server, viene letto, e viene risposto il mio numero con anche il timetag del server. Facendo così misurando i delta posso scroprire esattamente il tempo che intercorre tra inviare un messaggio al server e ricevere una risposta. Per come è fatto il server il tempo di applicazione dei nuovi valori per i target sarà al massimo di 1 batch, che può essere variabile, ma a quel punto lo potremmo calibrare in altro modo. Con l'analisi sui sync possiamo sapere come allineare gli orologi. -- [ ] Aggiungere un tasto per duplicare uno scenario da uno già presente e dargli un nome diverso +- [x] Aggiungere un tasto per duplicare uno scenario da uno già presente e dargli un nome diverso - [ ] aggiungere una funzione automatica durante il salvataggio dello scenario che cancelli quelli più vecchi di 10 salvataggi fa, per evitare che aumentino in numero senza controllo # FIXME List - [ ] sistemare la visualizzazione nella tabe simulator, per poter vedere quale scenario è stato selezionato -- [ ] sistemare l'animazione della antenna che adesso non si muove più +- [x] sistemare l'animazione della antenna che adesso non si muove più - [ ] rivedere la visualizzazione della combobox per scegliere lo scenario da usare. - [ ] quando è finita la simulazione i target nella tabella si devono fermare all'ultima posizione scambiata. - [ ] quando la traiettoria si ferma deve comparire la x gialla e non deve sparire a fine simulazione \ No newline at end of file