libsurfer/
clock_highlighting.rs

1//! Drawing and handling of clock highlighting.
2use derive_more::{Display, FromStr};
3use egui::Ui;
4use emath::{Pos2, Rect};
5use enum_iterator::Sequence;
6use epaint::Stroke;
7use serde::{Deserialize, Serialize};
8
9use crate::{config::SurferConfig, message::Message, view::DrawingContext};
10
11#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Display, FromStr, Sequence, Serialize)]
12pub enum ClockHighlightType {
13    /// Draw a line at every posedge of the clocks
14    Line,
15
16    /// Highlight every other cycle
17    Cycle,
18
19    /// No highlighting
20    None,
21}
22
23pub fn draw_clock_edge_marks(
24    clock_edges: &Vec<f32>,
25    ctx: &mut DrawingContext,
26    config: &SurferConfig,
27    clock_highlight_type: ClockHighlightType,
28) {
29    match clock_highlight_type {
30        ClockHighlightType::Line => {
31            let stroke = Stroke {
32                color: config.theme.clock_highlight_line.color,
33                width: config.theme.clock_highlight_line.width,
34            };
35
36            for x in clock_edges {
37                let Pos2 {
38                    x: x_pos,
39                    y: y_start,
40                } = (ctx.to_screen)(*x, 0.);
41                ctx.painter
42                    .vline(x_pos, (y_start)..=(y_start + ctx.cfg.canvas_height), stroke);
43            }
44        }
45        ClockHighlightType::Cycle => {
46            let mut x_start = 0.0;
47            let mut cycle = false;
48            for x_tmp in clock_edges {
49                if cycle {
50                    let Pos2 {
51                        x: x_end,
52                        y: y_start,
53                    } = (ctx.to_screen)(*x_tmp, 0.);
54                    ctx.painter.rect_filled(
55                        Rect {
56                            min: (ctx.to_screen)(x_start, 0.),
57                            max: Pos2 {
58                                x: x_end,
59                                y: ctx.cfg.canvas_height + y_start,
60                            },
61                        },
62                        0.0,
63                        config.theme.clock_highlight_cycle,
64                    );
65                }
66                cycle = !cycle;
67                x_start = *x_tmp;
68            }
69        }
70        ClockHighlightType::None => (),
71    }
72}
73
74pub fn clock_highlight_type_menu(
75    ui: &mut Ui,
76    msgs: &mut Vec<Message>,
77    clock_highlight_type: ClockHighlightType,
78) {
79    for highlight_type in enum_iterator::all::<ClockHighlightType>() {
80        ui.radio(
81            highlight_type == clock_highlight_type,
82            highlight_type.to_string(),
83        )
84        .clicked()
85        .then(|| {
86            msgs.push(Message::SetClockHighlightType(highlight_type));
87        });
88    }
89}