ringkernel_procint/gui/panels/
fabric_panel.rs

1//! Data fabric control panel.
2
3use crate::actors::PipelineCoordinator;
4use crate::fabric::SectorTemplate;
5use crate::gui::widgets::{sector_selector, status_dot};
6use crate::gui::{section_header, styled_panel, Theme};
7use eframe::egui::{self, Ui};
8
9/// Data fabric control panel.
10pub struct FabricPanel {
11    /// Current sector.
12    pub sector: SectorTemplate,
13    /// Events per second.
14    pub events_per_second: u32,
15    /// Deviation rate.
16    pub deviation_rate: f32,
17}
18
19impl Default for FabricPanel {
20    fn default() -> Self {
21        use crate::fabric::HealthcareConfig;
22        Self {
23            sector: SectorTemplate::Healthcare(HealthcareConfig::default()),
24            events_per_second: 10000,
25            deviation_rate: 0.1,
26        }
27    }
28}
29
30impl FabricPanel {
31    /// Render the panel.
32    pub fn render(&mut self, ui: &mut Ui, theme: &Theme, coordinator: &mut PipelineCoordinator) {
33        styled_panel(ui, theme, |ui| {
34            section_header(ui, theme, "DATA FABRIC");
35
36            // Sector selector
37            ui.horizontal(|ui| {
38                if sector_selector(ui, &mut self.sector) {
39                    coordinator.set_sector(self.sector.clone());
40                }
41            });
42            ui.add_space(8.0);
43
44            // Events per second slider
45            ui.horizontal(|ui| {
46                ui.label("Events/sec:");
47                if ui
48                    .add(
49                        egui::Slider::new(&mut self.events_per_second, 1000..=100000)
50                            .logarithmic(true),
51                    )
52                    .changed()
53                {
54                    let mut config = coordinator.pipeline().config().generator.clone();
55                    config.events_per_second = self.events_per_second;
56                    coordinator.pipeline_mut().set_generator_config(config);
57                }
58            });
59
60            // Deviation rate slider
61            ui.horizontal(|ui| {
62                ui.label("Deviation:");
63                if ui
64                    .add(egui::Slider::new(&mut self.deviation_rate, 0.0..=0.5).show_value(true))
65                    .changed()
66                {
67                    let mut config = coordinator.pipeline().config().generator.clone();
68                    config.deviation_rate = self.deviation_rate;
69                    coordinator.pipeline_mut().set_generator_config(config);
70                }
71            });
72
73            ui.add_space(12.0);
74
75            // Status indicator
76            ui.horizontal(|ui| {
77                let is_running = coordinator.stats().is_running;
78                let color = if is_running {
79                    theme.success
80                } else {
81                    theme.text_muted
82                };
83                status_dot(ui, color, is_running);
84                ui.label(if is_running { "Running" } else { "Paused" });
85            });
86
87            ui.add_space(8.0);
88
89            // Control buttons
90            ui.horizontal(|ui| {
91                let is_running = coordinator.stats().is_running;
92
93                if is_running {
94                    if ui.button("⏸ Pause").clicked() {
95                        coordinator.handle_control(crate::actors::ControlMessage::Pause);
96                    }
97                } else if ui.button("▶ Start").clicked() {
98                    coordinator.handle_control(crate::actors::ControlMessage::Start);
99                }
100
101                if ui.button("↻ Reset").clicked() {
102                    coordinator.handle_control(crate::actors::ControlMessage::Reset);
103                }
104            });
105
106            ui.add_space(12.0);
107
108            // Sector info
109            ui.collapsing("Sector Info", |ui| {
110                ui.label(format!("Name: {}", self.sector.name()));
111                ui.label(format!("Activities: {}", self.sector.activities().len()));
112                ui.label(format!("Transitions: {}", self.sector.transitions().len()));
113            });
114        });
115    }
116}