select_outline_dialog.rs - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
 (HTM) git clone https://git.drkhsh.at/icy_draw.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       select_outline_dialog.rs (5520B)
       ---
            1 use eframe::{
            2     egui::{self},
            3     epaint::{Color32, Rect, Rounding, Vec2},
            4 };
            5 use egui_modal::Modal;
            6 use i18n_embed_fl::fl;
            7 use icy_engine::{BitFont, TheDrawFont};
            8 
            9 use crate::{AnsiEditor, Message, ModalDialog, Settings, TerminalResult};
           10 
           11 pub struct SelectOutlineDialog {
           12     should_commit: bool,
           13     selected_outline: usize,
           14     font: BitFont,
           15 }
           16 
           17 impl Default for SelectOutlineDialog {
           18     fn default() -> Self {
           19         Self {
           20             should_commit: false,
           21             selected_outline: Settings::get_font_outline_style(),
           22             font: BitFont::default(),
           23         }
           24     }
           25 }
           26 
           27 impl SelectOutlineDialog {
           28     pub fn get_outline_style(&self) -> usize {
           29         self.selected_outline
           30     }
           31 
           32     fn draw_outline_glyph(&mut self, ui: &mut egui::Ui, outline_style: usize) {
           33         let scale = 1.;
           34         let border = 4.0;
           35 
           36         let (_id, stroke_rect) = ui.allocate_space(Vec2::new(
           37             2. * border + scale * self.font.size.width as f32 * OUTLINE_WIDTH as f32,
           38             2. * border + scale * self.font.size.height as f32 * OUTLINE_HEIGHT as f32,
           39         ));
           40 
           41         let painter = ui.painter_at(stroke_rect);
           42         let s = self.font.size;
           43         let mut col = if self.selected_outline == outline_style {
           44             Color32::GRAY
           45         } else {
           46             Color32::DARK_GRAY
           47         };
           48         let bg_color = if self.selected_outline == outline_style {
           49             Color32::DARK_BLUE
           50         } else {
           51             Color32::BLACK
           52         };
           53 
           54         if let Some(pos) = ui.input(|i| i.pointer.hover_pos()) {
           55             if stroke_rect.contains(pos) {
           56                 if ui.input(|i| i.pointer.primary_clicked()) {
           57                     self.selected_outline = outline_style;
           58                 }
           59                 if ui.input(|i| i.pointer.button_double_clicked(egui::PointerButton::Primary)) {
           60                     self.selected_outline = outline_style;
           61                     self.should_commit = true;
           62                 }
           63                 col = Color32::WHITE;
           64             }
           65         }
           66         painter.rect_filled(stroke_rect, Rounding::ZERO, bg_color);
           67 
           68         for h in 0..OUTLINE_HEIGHT {
           69             for w in 0..OUTLINE_WIDTH {
           70                 let ch = TheDrawFont::transform_outline(outline_style, OUTLINE_FONT_CHAR[w + h * OUTLINE_WIDTH]);
           71                 let ch = unsafe { char::from_u32_unchecked(ch as u32) };
           72 
           73                 let xs = w as f32 * scale * self.font.size.width as f32;
           74                 let ys = h as f32 * scale * self.font.size.height as f32;
           75                 if let Some(glyph) = self.font.get_glyph(ch) {
           76                     for y in 0..s.height {
           77                         for x in 0..s.width {
           78                             if glyph.data[y as usize] & (128 >> x) != 0 {
           79                                 painter.rect_filled(
           80                                     Rect::from_min_size(
           81                                         egui::Pos2::new(
           82                                             border + xs + stroke_rect.left() + x as f32 * scale,
           83                                             border + ys + stroke_rect.top() + y as f32 * scale,
           84                                         ),
           85                                         Vec2::new(scale, scale),
           86                                     ),
           87                                     Rounding::ZERO,
           88                                     col,
           89                                 );
           90                             }
           91                         }
           92                     }
           93                 }
           94             }
           95         }
           96     }
           97 
           98     pub fn show_outline_ui(&mut self, ui: &mut egui::Ui, item_per_row: usize, spacing: Vec2) {
           99         for style in 0..TheDrawFont::OUTLINE_STYLES / item_per_row {
          100             ui.horizontal(|ui| {
          101                 ui.add_space(4.0);
          102                 for i in 0..item_per_row {
          103                     self.draw_outline_glyph(ui, style * item_per_row + i);
          104                     if i < item_per_row - 1 {
          105                         ui.add_space(spacing.x);
          106                     }
          107                 }
          108             });
          109             ui.end_row();
          110             ui.add_space(spacing.y);
          111         }
          112     }
          113 }
          114 
          115 const OUTLINE_WIDTH: usize = 8;
          116 const OUTLINE_HEIGHT: usize = 6;
          117 const OUTLINE_FONT_CHAR: [u8; 48] = [
          118     69, 65, 65, 65, 65, 65, 65, 70, 67, 79, 71, 66, 66, 72, 79, 68, 67, 79, 73, 65, 65, 74, 79, 68, 67, 79, 71, 66, 66, 72, 79, 68, 67, 79, 68, 64, 64, 67, 79,
          119     68, 75, 66, 76, 64, 64, 75, 66, 76,
          120 ];
          121 
          122 impl ModalDialog for SelectOutlineDialog {
          123     fn show(&mut self, ctx: &egui::Context) -> bool {
          124         let mut result = false;
          125         let modal = Modal::new(ctx, "select_outline_dialog");
          126 
          127         modal.show(|ui| {
          128             modal.title(ui, fl!(crate::LANGUAGE_LOADER, "select-outline-style-title"));
          129 
          130             modal.frame(ui, |ui| {
          131                 ui.add_space(8.0);
          132                 self.show_outline_ui(ui, 4, Vec2::new(8.0, 8.0));
          133             });
          134 
          135             modal.buttons(ui, |ui| {
          136                 if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
          137                     self.should_commit = true;
          138                     result = true;
          139                 }
          140                 if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
          141                     result = true;
          142                 }
          143             });
          144         });
          145         modal.open();
          146         result || self.should_commit
          147     }
          148 
          149     fn should_commit(&self) -> bool {
          150         self.should_commit
          151     }
          152 
          153     fn commit(&self, _editor: &mut AnsiEditor) -> TerminalResult<Option<Message>> {
          154         Settings::set_font_outline_style(self.selected_outline);
          155         Ok(None)
          156     }
          157 }