notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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 }