1use crate::message::Message;
2use crate::view::{DrawConfig, DrawingContext};
3use crate::viewport::Viewport;
4use crate::{SystemState, wave_data::WaveData};
5use egui::{Frame, Panel, PointerButton, Sense, Ui};
6use emath::{Align2, Pos2, Rect, RectTransform};
7use epaint::CornerRadius;
8
9impl SystemState {
10 pub fn add_overview_panel(&self, ui: &mut Ui, waves: &WaveData, msgs: &mut Vec<Message>) {
11 Panel::bottom("overview")
12 .frame(Frame {
13 fill: self.user.config.theme.primary_ui_color.background,
14 ..Default::default()
15 })
16 .show_inside(ui, |ui| {
17 self.draw_overview(ui, waves, msgs);
18 });
19 }
20
21 fn draw_overview(&self, ui: &mut Ui, waves: &WaveData, msgs: &mut Vec<Message>) {
22 let (response, mut painter) = ui.allocate_painter(ui.available_size(), Sense::drag());
23 let frame_size = response.rect.size();
24 let frame_width = frame_size.x;
25 let frame_height = frame_size.y;
26 let cfg = DrawConfig::new(
27 frame_height,
28 frame_width,
29 self.user.config.layout.waveforms_line_height,
30 self.user.config.layout.waveforms_text_size,
31 );
32 let container_rect = Rect::from_min_size(Pos2::ZERO, frame_size);
33 let to_screen = RectTransform::from_to(container_rect, response.rect);
34
35 let mut ctx = DrawingContext {
36 painter: &mut painter,
37 cfg: &cfg,
38 to_screen: &|x, y| to_screen.transform_pos(Pos2::new(x, y)),
39 theme: &self.user.config.theme,
40 };
41
42 let num_timestamps = waves.safe_num_timestamps();
43 let viewport_all = waves.viewport_all();
44 let fill_color = self
45 .user
46 .config
47 .theme
48 .canvas_colors
49 .foreground
50 .gamma_multiply(0.3);
51
52 waves
54 .viewports
55 .iter()
56 .map(|viewport| get_viewport_rect(&ctx, &num_timestamps, &viewport_all, viewport))
57 .for_each(|rect| {
58 ctx.painter
59 .rect_filled(rect, CornerRadius::ZERO, fill_color);
60 });
61
62 waves.draw_cursor(&self.user.config.theme, &mut ctx, &viewport_all);
64
65 let mut ticks = self.get_ticks_for_viewport(waves, &viewport_all, &cfg);
67
68 if ticks.len() >= 2 {
69 ticks.pop();
71 ticks.remove(0);
72 waves.draw_ticks(
74 self.user.config.theme.foreground,
75 &ticks,
76 &ctx,
77 frame_height * 0.5,
78 Align2::CENTER_CENTER,
79 );
80 }
81
82 waves.draw_markers(&self.user.config.theme, &mut ctx, &viewport_all);
84 waves.draw_marker_number_boxes(&mut ctx, &self.user.config.theme, &viewport_all);
85
86 response.dragged_by(PointerButton::Primary).then(|| {
88 let pointer_pos_global = ui.input(|i| i.pointer.interact_pos());
89 let pos = pointer_pos_global.map(|p| to_screen.inverse().transform_pos(p));
90 if let Some(pos) = pos {
91 let timestamp = viewport_all.as_time_bigint(pos.x, frame_width, &num_timestamps);
92 msgs.push(Message::GoToTime(Some(timestamp), 0));
93 }
94 });
95 }
96}
97
98fn get_viewport_rect(
99 ctx: &DrawingContext<'_>,
100 num_timestamps: &num::BigInt,
101 viewport_all: &Viewport,
102 viewport: &Viewport,
103) -> Rect {
104 let minx = viewport_all.pixel_from_absolute_time(
105 viewport.curr_left.absolute(num_timestamps),
106 ctx.cfg.canvas_width,
107 num_timestamps,
108 );
109 let maxx = viewport_all.pixel_from_absolute_time(
110 viewport.curr_right.absolute(num_timestamps),
111 ctx.cfg.canvas_width,
112 num_timestamps,
113 );
114 let min = (ctx.to_screen)(minx, 0.);
115 let max = (ctx.to_screen)(maxx, ctx.cfg.canvas_height);
116 Rect { min, max }
117}