rafia_stpa_gui/panels/
tabs.rs

1// *****************************************************************************
2// Copyright (c) 2025 William Salmon
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0.
7//
8// This Source Code may also be made available under the following Secondary
9// Licenses when the conditions for such availability set forth in the Eclipse
10// Public License, v. 2.0 are satisfied: GNU General Public License, version 2
11// with the GNU Classpath Exception which is
12// available at https://www.gnu.org/software/classpath/license.html.
13//
14// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15// *****************************************************************************
16
17use eframe::egui;
18use strum::IntoEnumIterator;
19
20use crate::{
21    panels::{
22        io_options, update_ca_analyses, update_constraints, update_control_loop_sequences,
23        update_control_loops, update_diagram, update_elements, update_hazards, update_interactions,
24        update_losses, update_scenarios, update_uca_contexts, update_ucas,
25    },
26    StpaView,
27};
28use rafia_stpa::stpa::{StpaData, StpaProject};
29
30pub struct TreeBehavior {
31    pub undo: Vec<StpaData>,
32    pub redo: Vec<StpaData>,
33    pub stpa_data: StpaData,
34    pub project: Option<StpaProject>,
35}
36
37impl egui_tiles::Behavior<StpaView> for TreeBehavior {
38    fn tab_title_for_pane(&mut self, pane: &StpaView) -> egui::WidgetText {
39        pane.tab_name().into()
40    }
41
42    fn simplification_options(&self) -> egui_tiles::SimplificationOptions {
43        egui_tiles::SimplificationOptions {
44            all_panes_must_have_tabs: true,
45            ..Default::default()
46        }
47    }
48
49    fn pane_ui(
50        &mut self,
51        ui: &mut egui::Ui,
52        _tile_id: egui_tiles::TileId,
53        panel: &mut StpaView,
54    ) -> egui_tiles::UiResponse {
55        match &panel {
56            StpaView::Diagram => update_diagram(ui, self.stpa_data.diagram.as_ref()),
57            StpaView::Losses => update_losses(ui, &mut self.stpa_data.losses),
58            StpaView::Hazards => {
59                update_hazards(ui, &mut self.stpa_data.hazards, &self.stpa_data.losses)
60            }
61            StpaView::Constraints => update_constraints(
62                ui,
63                &mut self.stpa_data.constraints,
64                &self.stpa_data.hazards,
65                &self.stpa_data.ucas,
66                &self.stpa_data.scenarios,
67            ),
68            StpaView::Elements => update_elements(ui, &mut self.stpa_data.elements),
69            StpaView::Interactions => update_interactions(
70                ui,
71                &mut self.stpa_data.interactions,
72                &self.stpa_data.elements,
73            ),
74            StpaView::CaAnalyses => update_ca_analyses(
75                ui,
76                &mut self.stpa_data.ca_analyses,
77                &self.stpa_data.uca_contexts,
78                &self.stpa_data.hazards,
79                &self.stpa_data.interactions,
80            ),
81            StpaView::UcaContexts => update_uca_contexts(ui, &mut self.stpa_data.uca_contexts),
82            StpaView::Ucas => update_ucas(
83                ui,
84                &mut self.stpa_data.ucas,
85                &self.stpa_data.uca_contexts,
86                &self.stpa_data.constraints,
87                &self.stpa_data.interactions,
88            ),
89            StpaView::ControlLoops => update_control_loops(
90                ui,
91                &mut self.stpa_data.control_loops,
92                &self.stpa_data.elements,
93                &self.stpa_data.constraints,
94            ),
95            StpaView::ControlLoopSequences => update_control_loop_sequences(
96                ui,
97                &mut self.stpa_data.control_loop_sequences,
98                &self.stpa_data.control_loops,
99                &self.stpa_data.interactions,
100            ),
101            StpaView::Scenarios => update_scenarios(
102                ui,
103                &mut self.stpa_data.scenarios,
104                &self.stpa_data.control_loop_sequences,
105                &self.stpa_data.ucas,
106                &self.stpa_data.hazards,
107                &self.stpa_data.constraints,
108            ),
109            StpaView::IoOptions => io_options(ui, &self.stpa_data, self.project.as_ref()),
110        };
111        egui_tiles::UiResponse::None
112    }
113}
114
115pub fn create_tree() -> egui_tiles::Tree<StpaView> {
116    let mut tiles = egui_tiles::Tiles::default();
117
118    let mut tabs = vec![];
119    for variant in StpaView::iter() {
120        tabs.push(tiles.insert_pane(variant));
121    }
122
123    let root = tiles.insert_tab_tile(tabs);
124
125    egui_tiles::Tree::new("stpa_panels", root, tiles)
126}