softbrush/
dbgui.rs

1use crate::font::print;
2use crate::font::Font;
3use crate::BitmapARGB32;
4use alloc::boxed::Box;
5use alloc::string::String;
6use alloc::vec::Vec;
7use alloc::string::ToString;
8
9/// A simple UI for debugging purposes
10pub struct DbgMenu {
11    title: &'static str,
12    menu_items: Vec<DbgMenuItem>,
13    cursor_index: usize,
14}
15
16pub struct DbgMenuItem {
17    pub text: String,
18    pub callback: Box<dyn Fn(&mut DbgMenu)>,
19}
20
21impl DbgMenu {
22    pub fn builder() -> DbgMenuBuilder {
23        DbgMenuBuilder::new()
24    }
25
26    fn assemble_string(&self) -> String {
27        let mut result = String::new();
28        result.push('[');
29        result.push_str(self.title);
30        result.push_str("]\n");
31        for (i, item) in self.menu_items.iter().enumerate() {
32            if i == self.cursor_index {
33                result.push('*');
34            } else {
35                result.push(' ');
36            }
37            result.push_str(&item.text);
38            result.push('\n');
39        }
40        result
41    }
42
43    pub fn draw(&self, font: &Font, dest: &mut BitmapARGB32, x: usize, y: usize) {
44        let text = self.assemble_string();
45        print(x, y, font, dest, &text);
46    }
47}
48
49pub struct DbgMenuBuilder {
50    title: &'static str,
51    font: Option<Font>,
52    menu_items: Vec<DbgMenuItem>,
53}
54
55impl DbgMenuBuilder {
56    pub fn new() -> Self {
57        Self {
58            title: "???",
59            font: None,
60            menu_items: Vec::new(),
61        }
62    }
63
64    pub fn title(mut self, title: &'static str) -> Self {
65        self.title = title;
66        self
67    }
68
69    pub fn font(mut self, font: Font) -> Self {
70        self.font = Some(font);
71        self
72    }
73
74    pub fn add_item(mut self, text: &str, callback: impl Fn(&mut DbgMenu) + 'static) -> Self {
75        self.menu_items.push(DbgMenuItem {
76            text: text.to_string(),
77            callback: Box::new(callback),
78        });
79        self
80    }
81
82    pub fn build(self) -> DbgMenu {
83        DbgMenu {
84            title: self.title,
85            menu_items: self.menu_items,
86            cursor_index: 0,
87        }
88    }
89}