csi_webclient/ui/
control.rs1use crate::state::{AppState, UserIntent};
2
3pub fn render(ui: &mut egui::Ui, state: &mut AppState) {
5 ui.heading("Control");
6 ui.separator();
7
8 egui::ScrollArea::vertical()
9 .auto_shrink([false, false])
10 .show(ui, |ui| {
11 render_body(ui, state);
12 });
13}
14
15fn render_body(ui: &mut egui::Ui, state: &mut AppState) {
16 ui.horizontal_wrapped(|ui| {
17 ui.label("Duration (seconds, optional)");
18 ui.add(
19 egui::TextEdit::singleline(&mut state.persistent.start_duration_seconds)
20 .desired_width(80.0),
21 );
22 });
23
24 ui.horizontal_wrapped(|ui| {
25 if ui.button("Start Collection").clicked() {
26 state.push_intent(UserIntent::StartCollection {
27 duration_seconds: state.persistent.start_duration_seconds.clone(),
28 });
29 }
30
31 if ui.button("Stop Collection").clicked() {
32 state.push_intent(UserIntent::StopCollection);
33 }
34
35 if ui.button("Show Stats").clicked() {
36 state.push_intent(UserIntent::ShowStats);
37 }
38 });
39
40 ui.horizontal_wrapped(|ui| {
41 if ui.button("Reset Device (RTS)").clicked() {
42 state.push_intent(UserIntent::ResetDevice);
43 }
44
45 if ui.button("Fetch Status").clicked() {
46 state.push_intent(UserIntent::FetchStatus);
47 }
48
49 if ui.button("Fetch Info").clicked() {
50 state.push_intent(UserIntent::FetchInfo);
51 }
52
53 if ui.button("Fetch Config").clicked() {
54 state.push_intent(UserIntent::FetchConfig);
55 }
56 });
57
58 ui.separator();
59
60 ui.horizontal_wrapped(|ui| {
61 if !state.runtime.ws_connected {
62 if ui.button("Connect WebSocket").clicked() {
63 state.push_intent(UserIntent::ConnectWebSocket);
64 }
65 } else if ui.button("Disconnect WebSocket").clicked() {
66 state.push_intent(UserIntent::DisconnectWebSocket);
67 }
68
69 if ui.button("Clear Stream Frames").clicked() {
70 state.push_intent(UserIntent::ClearFrames);
71 }
72 });
73
74 ui.separator();
75 ui.add(
76 egui::Label::new(
77 "Stop sends the literal 'q' byte (graceful). Reset pulses RTS and re-verifies firmware.",
78 )
79 .wrap(),
80 );
81}