commands.rs (3527B)
1 use std::collections::HashMap; 2 3 #[derive(Clone)] 4 pub enum UiCommand { 5 Label(String), 6 Heading(String), 7 Button(String), 8 AddSpace(f32), 9 DrawRect { 10 x: f32, 11 y: f32, 12 w: f32, 13 h: f32, 14 color: u32, 15 }, 16 DrawCircle { 17 cx: f32, 18 cy: f32, 19 r: f32, 20 color: u32, 21 }, 22 DrawLine { 23 x1: f32, 24 y1: f32, 25 x2: f32, 26 y2: f32, 27 width: f32, 28 color: u32, 29 }, 30 DrawText { 31 x: f32, 32 y: f32, 33 text: String, 34 size: f32, 35 color: u32, 36 }, 37 } 38 39 fn color_from_u32(c: u32) -> egui::Color32 { 40 let r = ((c >> 24) & 0xFF) as u8; 41 let g = ((c >> 16) & 0xFF) as u8; 42 let b = ((c >> 8) & 0xFF) as u8; 43 let a = (c & 0xFF) as u8; 44 egui::Color32::from_rgba_unmultiplied(r, g, b, a) 45 } 46 47 /// Render buffered commands into egui, returning button click events. 48 /// Keys are `button_key(text, occurrence)`. 49 pub fn render_commands(commands: &[UiCommand], ui: &mut egui::Ui) -> HashMap<String, bool> { 50 let mut events = HashMap::new(); 51 let mut button_occ: HashMap<&str, u32> = HashMap::new(); 52 let origin = ui.min_rect().left_top(); 53 let painter = ui.painter().clone(); 54 55 for cmd in commands { 56 match cmd { 57 UiCommand::Label(text) => { 58 ui.label(text.as_str()); 59 } 60 UiCommand::Heading(text) => { 61 ui.heading(text.as_str()); 62 } 63 UiCommand::Button(text) => { 64 let occ = button_occ.entry(text.as_str()).or_insert(0); 65 let key = button_key(text, *occ); 66 *occ += 1; 67 let clicked = ui.button(text.as_str()).clicked(); 68 events.insert(key, clicked); 69 } 70 UiCommand::AddSpace(px) => { 71 ui.add_space(*px); 72 } 73 UiCommand::DrawRect { x, y, w, h, color } => { 74 let rect = egui::Rect::from_min_size( 75 egui::pos2(origin.x + x, origin.y + y), 76 egui::vec2(*w, *h), 77 ); 78 painter.rect_filled(rect, 0.0, color_from_u32(*color)); 79 } 80 UiCommand::DrawCircle { cx, cy, r, color } => { 81 let center = egui::pos2(origin.x + cx, origin.y + cy); 82 painter.circle_filled(center, *r, color_from_u32(*color)); 83 } 84 UiCommand::DrawLine { 85 x1, 86 y1, 87 x2, 88 y2, 89 width, 90 color, 91 } => { 92 let p1 = egui::pos2(origin.x + x1, origin.y + y1); 93 let p2 = egui::pos2(origin.x + x2, origin.y + y2); 94 painter.line_segment([p1, p2], egui::Stroke::new(*width, color_from_u32(*color))); 95 } 96 UiCommand::DrawText { 97 x, 98 y, 99 text, 100 size, 101 color, 102 } => { 103 let pos = egui::pos2(origin.x + x, origin.y + y); 104 painter.text( 105 pos, 106 egui::Align2::LEFT_TOP, 107 text, 108 egui::FontId::proportional(*size), 109 color_from_u32(*color), 110 ); 111 } 112 } 113 } 114 115 events 116 } 117 118 pub fn button_key(text: &str, occurrence: u32) -> String { 119 if occurrence == 0 { 120 text.to_string() 121 } else { 122 format!("{}#{}", text, occurrence) 123 } 124 }