Skip to main content

embedded_window/
embedded_window.rs

1//! Example: Embedding LivePlot into your own egui application window
2//!
3//! What it demonstrates
4//! - How to embed the `LivePlotApp` UI inside an existing `eframe`/`egui` application window.
5//! - Feeding data from the main app into the embedded plot via `PlotSink` and `Trace` handles.
6//!
7//! How to run
8//! ```bash
9//! cargo run --example embedded_window
10//! ```
11//! Click "Open Plot Window" in the demo UI to show the embedded LivePlot view.
12
13use std::time::Duration;
14
15use eframe::{egui, NativeOptions};
16use liveplot::{channel_plot, LivePlotApp, PlotPoint, PlotSink, Trace};
17
18#[derive(Clone, Copy, PartialEq)]
19enum WaveKind {
20    Sine,
21    Cosine,
22}
23
24struct DemoApp {
25    kind: WaveKind,
26    // data feed
27    sink: PlotSink,
28    trace_sine: Trace,
29    trace_cos: Trace,
30    // embedded plot app (whole LivePlotApp kept so we can access main_panel)
31    plot: LivePlotApp,
32    // show window flag
33    show_plot_window: bool,
34}
35
36impl DemoApp {
37    fn new() -> Self {
38        let (sink, rx) = channel_plot();
39        let trace_sine = sink.create_trace("sine", None);
40        let trace_cos = sink.create_trace("cosine", None);
41        let mut plot = LivePlotApp::new(rx);
42        // Configure the embedded main panel's data
43        for scope in plot.main_panel.liveplot_panel.get_data_mut() {
44            scope.time_window = 10.0;
45        }
46        plot.main_panel.traces_data.max_points = 10_000;
47        Self {
48            kind: WaveKind::Sine,
49            sink,
50            trace_sine,
51            trace_cos,
52            plot,
53            show_plot_window: false,
54        }
55    }
56}
57
58impl eframe::App for DemoApp {
59    fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
60        egui::CentralPanel::default().show(ctx, |ui| {
61            ui.heading("Embedding LivePlot in egui::Window");
62            ui.horizontal(|ui| {
63                ui.label("Select wave:");
64                egui::ComboBox::from_id_salt("wave_select")
65                    .selected_text(match self.kind {
66                        WaveKind::Sine => "Sine",
67                        WaveKind::Cosine => "Cosine",
68                    })
69                    .show_ui(ui, |ui| {
70                        ui.selectable_value(&mut self.kind, WaveKind::Sine, "Sine");
71                        ui.selectable_value(&mut self.kind, WaveKind::Cosine, "Cosine");
72                    });
73                if ui.button("Open Plot Window").clicked() {
74                    self.show_plot_window = true;
75                }
76            });
77            ui.separator();
78            ui.label("Pick a wave and click the button to open the embedded LivePlot window.");
79        });
80
81        // Show the embedded plot in its own egui::Window when requested
82        if self.show_plot_window {
83            let mut open = true;
84            egui::Window::new("LivePlot Window")
85                .open(&mut open)
86                .show(ctx, |ui| {
87                    // Optional minimal size for nicer layout
88                    ui.set_min_size(egui::vec2(600.0, 300.0));
89                    self.plot.main_panel.update_embedded(ui);
90                });
91            if !open {
92                self.show_plot_window = false;
93            }
94        }
95
96        // Feed the chosen wave
97        let now_us = chrono::Utc::now().timestamp_micros();
98        let t = (now_us as f64) * 1e-6;
99        let phase = t * 2.0 * std::f64::consts::PI;
100        let val = match self.kind {
101            WaveKind::Sine => phase.sin(),
102            WaveKind::Cosine => phase.cos(),
103        };
104        let tr = match self.kind {
105            WaveKind::Sine => &self.trace_sine,
106            WaveKind::Cosine => &self.trace_cos,
107        };
108        let _ = self.sink.send_point(tr, PlotPoint { x: t, y: val });
109
110        ctx.request_repaint_after(Duration::from_millis(16));
111    }
112}
113
114fn main() -> eframe::Result<()> {
115    let app = DemoApp::new();
116    eframe::run_native(
117        "LivePlot embedded window demo",
118        NativeOptions::default(),
119        Box::new(|_cc| Ok(Box::new(app))),
120    )
121}