URI: 
       Worked on tool ui. - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
  HTML git clone https://git.drkhsh.at/icy_draw.git
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit a57fc3a38ea9e191a8cfc2cf2c6b757f7334d569
   DIR parent 360d5fbd58baf9244b233fee2ac71f7812bcff82
  HTML Author: Mike Krueger <mkrueger@posteo.de>
       Date:   Sun, 11 Dec 2022 00:47:36 +0100
       
       Worked on tool ui.
       
       Diffstat:
         M src/model/tool/brush_imp.rs         |      78 ++++++++++++++++++++++++++++++-
         M src/model/tool/click_imp.rs         |       5 +++++
         M src/model/tool/draw_ellipse_filled… |       4 ++++
         M src/model/tool/draw_ellipse_imp.rs  |       5 +++++
         M src/model/tool/draw_rectangle_fill… |       5 +++++
         M src/model/tool/draw_rectangle_imp.… |       4 ++++
         M src/model/tool/erase_imp.rs         |       5 +++++
         M src/model/tool/fill_imp.rs          |       4 ++++
         M src/model/tool/flip_imp.rs          |       5 +++++
         M src/model/tool/font_imp.rs          |       5 +++++
         M src/model/tool/line_imp.rs          |       4 ++++
         M src/model/tool/mod.rs               |       4 ++++
         M src/model/tool/move_layer_imp.rs    |       6 +++++-
         M src/model/tool/pipette_imp.rs       |       5 +++++
         M src/ui/font_editor.rs               |      12 +++++++++---
         M src/ui/main_window.rs               |      30 ++++++++++++++++++++++++------
         M src/ui/mod.rs                       |       3 ++-
       
       17 files changed, 171 insertions(+), 13 deletions(-)
       ---
   DIR diff --git a/src/model/tool/brush_imp.rs b/src/model/tool/brush_imp.rs
       @@ -1,8 +1,13 @@
       -use std::{cell::{RefCell}, rc::Rc};
       +use std::{cell::{RefCell}, rc::Rc, sync::{Arc, Mutex}};
        use egui_extras::RetainedImage;
       +use eframe::{egui::{self, Sense, RichText}, epaint::{Vec2, Color32, Rounding, Rect, Pos2}};
       +use icy_engine::Buffer;
       +
       +use crate::ansi_editor::BufferView;
        
        use super::{ Tool, Editor, Position};
        
       +#[derive(PartialEq, Eq)]
        pub enum BrushType {
            Shade,
            Solid,
       @@ -13,7 +18,8 @@ pub struct BrushTool {
            pub use_fore: bool,
            pub use_back: bool,
            pub size: i32,
       -    pub char_code: u16,
       +    pub char_code: char,
       +    pub font_page: usize,
        
            pub brush_type: BrushType
        }
       @@ -87,7 +93,36 @@ impl BrushTool {
        impl Tool for BrushTool
        {
            fn get_icon_name(&self) -> &'static RetainedImage { &super::icons::BRUSH_SVG }
       +    
            fn use_caret(&self) -> bool { false }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +        ui.vertical_centered(|ui| {
       +            ui.horizontal(|ui| {
       +                if ui.selectable_label(self.use_fore, "Fg").clicked() {
       +                    self.use_fore = !self.use_fore;
       +                }
       +                if ui.selectable_label(self.use_back, "Bg").clicked() {
       +                    self.use_back = !self.use_back;
       +                }
       +            });
       +        });
       +        ui.horizontal(|ui| {
       +            ui.label("Size:");
       +            ui.add(egui::DragValue::new(&mut self.size).clamp_range(1..=20).speed(1));
       +        });
       +        ui.radio_value(&mut self.brush_type, BrushType::Shade, "Shade");
       +        ui.horizontal(|ui| {
       +            ui.radio_value(&mut self.brush_type, BrushType::Solid, "Character");
       +
       +            if let Some(b) = &buffer_opt {
       +                ui.add(draw_glyph(b.clone(), self.char_code, self.font_page));
       +            }
       +        });
       +        ui.radio_value(&mut self.brush_type, BrushType::Color, "Colorize");
       +    }
       +    
        /* 
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> super::Event {
                if button == 1 {
       @@ -101,4 +136,43 @@ impl Tool for BrushTool
                self.paint_brush(&editor, cur);
                super::Event::None
            }*/
       +}
       +
       +
       +pub fn draw_glyph(buf: Arc<Mutex<BufferView>>, ch: char, font_page: usize) ->  impl egui::Widget {
       +    move |ui: &mut egui::Ui| {
       +        let font  = &buf.lock().unwrap().editor.buf.font_table[font_page];
       +        let scale = 1.5;
       +        let (id, stroke_rect) = ui.allocate_space(Vec2::new(scale * font.size.width as f32, scale * font.size.height as f32));
       +        let mut response = ui.interact(stroke_rect, id, Sense::click());
       +       
       +        let col = if response.hovered() { Color32::WHITE } else { Color32::GRAY };
       +        
       +        let painter = ui.painter_at(stroke_rect);
       +        painter.rect_filled(stroke_rect, Rounding::none(), Color32::BLACK);
       +        let s = font.size;
       +        if let Some(glyph) = font.get_glyph(ch) {
       +            for y in 0..s.height {
       +                for x in 0..s.width {
       +                    if glyph.data[y as usize] & (128 >> x) != 0  {
       +                        painter.rect_filled( Rect::from_min_size(
       +                            Pos2::new(stroke_rect.left() + x as f32 * scale, stroke_rect.top() + y as f32 * scale),
       +                            Vec2::new(scale, scale)
       +                        ), Rounding::none(), col);
       +                    }
       +                }
       +            }
       +            response = response.on_hover_ui(|ui| {
       +                ui.horizontal(|ui| {
       +                    ui.label(RichText::new("Char").small());
       +                    ui.label(RichText::new(format!("{0}/0x{0:02X}", ch as u32)).small().color(Color32::WHITE));
       +                });
       +                ui.horizontal(|ui| {
       +                    ui.label(RichText::new("Font").small());
       +                    ui.label(RichText::new(font.name.to_string()).small().color(Color32::WHITE));
       +                });
       +            });
       +        }
       +        response
       +    }
        }
        \ No newline at end of file
   DIR diff --git a/src/model/tool/click_imp.rs b/src/model/tool/click_imp.rs
       @@ -1,6 +1,7 @@
        
        use std::{rc::Rc, cell::RefCell};
        
       +use eframe::egui;
        use egui_extras::RetainedImage;
        
        use crate::model::Selection;
       @@ -12,6 +13,10 @@ pub struct ClickTool {}
        impl Tool for ClickTool
        {
            fn get_icon_name(&self) -> &'static RetainedImage { &super::icons::CURSOR_SVG }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /* 
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> Event {
                if button == 1 {
   DIR diff --git a/src/model/tool/draw_ellipse_filled_imp.rs b/src/model/tool/draw_ellipse_filled_imp.rs
       @@ -1,3 +1,4 @@
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{plot_point, DrawMode, Editor, Event, Plottable, Position, Tool, ScanLines };
       @@ -39,6 +40,9 @@ impl Tool for DrawEllipseFilledTool {
            fn use_selection(&self) -> bool {
                false
            }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /*
            fn handle_drag(&self, editor: Rc<RefCell<Editor>>, start: Position, cur: Position) -> Event {
                if let Some(layer) = editor.borrow_mut().get_overlay_layer() {
   DIR diff --git a/src/model/tool/draw_ellipse_imp.rs b/src/model/tool/draw_ellipse_imp.rs
       @@ -1,3 +1,4 @@
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{ DrawMode, Editor, Event, Plottable, Position, Tool, ScanLines};
       @@ -39,6 +40,10 @@ impl Tool for DrawEllipseTool {
            fn use_selection(&self) -> bool {
                false
            }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /*
            fn handle_drag(&self, editor: Rc<RefCell<Editor>>, mut start: Position, mut cur: Position) -> Event {
                if let Some(layer) = editor.borrow_mut().get_overlay_layer() {
   DIR diff --git a/src/model/tool/draw_rectangle_filled_imp.rs b/src/model/tool/draw_rectangle_filled_imp.rs
       @@ -1,3 +1,4 @@
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{Editor, Event, Position, Tool, DrawMode, Plottable, plot_point, ScanLines};
       @@ -28,6 +29,10 @@ impl Tool for DrawRectangleFilledTool {
        
            fn use_caret(&self) -> bool { false }
            fn use_selection(&self) -> bool { false }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /* 
            fn handle_drag(&self, editor: Rc<RefCell<Editor>>,  start: Position, cur: Position) -> Event {
                if let Some(layer) = editor.borrow_mut().get_overlay_layer() {
   DIR diff --git a/src/model/tool/draw_rectangle_imp.rs b/src/model/tool/draw_rectangle_imp.rs
       @@ -1,4 +1,5 @@
        
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{Editor, Event, Position, Tool, DrawMode, Plottable, ScanLines};
       @@ -28,6 +29,9 @@ impl Tool for DrawRectangleTool {
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::RECTANGLE_OUTLINE_SVG }
            fn use_caret(&self) -> bool { false }
            fn use_selection(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /* 
            fn handle_drag(&self, editor: Rc<RefCell<Editor>>,  mut start: Position, mut cur: Position) -> Event {
                if let Some(layer) = editor.borrow_mut().get_overlay_layer() {
   DIR diff --git a/src/model/tool/erase_imp.rs b/src/model/tool/erase_imp.rs
       @@ -1,5 +1,7 @@
        use std::{cell::{RefCell}, rc::Rc};
        
       +use eframe::egui;
       +
        use super::{ Tool, Editor, Position};
        
        pub enum EraseType {
       @@ -72,6 +74,9 @@ impl Tool for EraseTool
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::ERASER_SVG }
           
            fn use_caret(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /*
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> super::Event {
                if button == 1 {
   DIR diff --git a/src/model/tool/fill_imp.rs b/src/model/tool/fill_imp.rs
       @@ -1,5 +1,6 @@
        use std::{cell::{RefCell, RefMut}, rc::Rc, collections::{HashSet}};
        
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{ Tool, Editor, Position, Event};
       @@ -22,6 +23,9 @@ impl Tool for FillTool
        {
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::FILL_SVG }
            fn use_caret(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
           /*
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> Event {
                if button == 1 {
   DIR diff --git a/src/model/tool/flip_imp.rs b/src/model/tool/flip_imp.rs
       @@ -1,6 +1,8 @@
        
        use std::{rc::Rc, cell::RefCell};
        
       +use eframe::egui;
       +
        use super::{Tool, Editor, Position, Event};
        pub struct FlipTool {}
        
       @@ -9,6 +11,9 @@ impl Tool for FlipTool
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::FILL_SVG }
            fn use_caret(&self) -> bool { false }
            fn use_selection(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
            /*
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> Event {
                if button == 1 {
   DIR diff --git a/src/model/tool/font_imp.rs b/src/model/tool/font_imp.rs
       @@ -1,6 +1,7 @@
        use std::{rc::Rc, cell::RefCell};
        
        use super::{Tool, MKey, Event, Editor, MKeyCode, MModifiers, Position};
       +use eframe::egui;
        use icy_engine::{TheDrawFont, Size};
        use walkdir::{DirEntry, WalkDir};
        pub struct FontTool {
       @@ -58,6 +59,10 @@ impl Tool for FontTool
        {
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::FONT_SVG }
            fn use_selection(&self) -> bool { false }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /* 
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> Event {
                if button == 1 {
   DIR diff --git a/src/model/tool/line_imp.rs b/src/model/tool/line_imp.rs
       @@ -1,3 +1,4 @@
       +use eframe::egui;
        use icy_engine::TextAttribute;
        
        use super::{Editor, Event, MKey, MKeyCode, MModifiers, Position, Tool, DrawMode, Plottable, plot_point};
       @@ -119,6 +120,9 @@ impl LineTool {
        impl Tool for LineTool {
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::LINE_SVG }
            fn use_selection(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
        /*
            fn handle_key(
                &mut self,
   DIR diff --git a/src/model/tool/mod.rs b/src/model/tool/mod.rs
       @@ -16,6 +16,7 @@ pub mod flip_imp;
        pub mod move_layer_imp;
        mod icons;
        
       +use eframe::{egui};
        use egui_extras::RetainedImage;
        use icy_engine::{Position, TextAttribute};
        pub use scan_lines::*;
       @@ -95,6 +96,9 @@ pub trait Tool
            fn use_caret(&self) -> bool { true }
            
            fn use_selection(&self) -> bool { true }
       +
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>);
       +    
              /* 
            fn handle_key(&mut self, editor: Rc<RefCell<Editor>>, key: MKey, key_code: MKeyCode, modifier: MModifiers) -> Event
            {
   DIR diff --git a/src/model/tool/move_layer_imp.rs b/src/model/tool/move_layer_imp.rs
       @@ -2,6 +2,8 @@
        use std::{rc::Rc, cell::RefCell};
        
        
       +use eframe::egui;
       +
        use super::{Tool, Editor, Position, Event};
        pub struct MoveLayer { pub pos: Position }
        
       @@ -10,7 +12,9 @@ impl Tool for MoveLayer
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::MOVE_SVG }
            fn use_caret(&self) -> bool { false }
            fn use_selection(&self) -> bool { false }
       -
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
          /* 
            fn handle_drag_begin(&mut self, editor: Rc<RefCell<Editor>>, _start: Position, _cur: Position) -> Event {
                let mut editor = editor.borrow_mut();
   DIR diff --git a/src/model/tool/pipette_imp.rs b/src/model/tool/pipette_imp.rs
       @@ -1,5 +1,7 @@
        use std::{rc::Rc, cell::RefCell};
        
       +use eframe::egui;
       +
        use super::{Tool, Editor, Position, Event};
        pub struct PipetteTool {}
        
       @@ -8,6 +10,9 @@ impl Tool for PipetteTool
            fn get_icon_name(&self) -> &'static egui_extras::RetainedImage { &super::icons::DROPPER_SVG }
            fn use_caret(&self) -> bool { false }
            fn use_selection(&self) -> bool { false }
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<std::sync::Arc<std::sync::Mutex<crate::ui::ansi_editor::BufferView>>>)
       +    {
       +    }
            /* 
            fn handle_click(&mut self, editor: Rc<RefCell<Editor>>, button: u32, pos: Position) -> Event {
                if button == 1 {
   DIR diff --git a/src/ui/font_editor.rs b/src/ui/font_editor.rs
       @@ -1,6 +1,6 @@
        use std::{fs, sync::{Arc, Mutex}};
        
       -use eframe::{egui::{self, Sense}, epaint::{Color32, Rounding, Vec2, Rect, Pos2}};
       +use eframe::{egui::{self, Sense, RichText}, epaint::{Color32, Rounding, Vec2, Rect, Pos2}};
        use icy_engine::{BitFont};
        
        use crate::{Document, TerminalResult};
       @@ -154,8 +154,14 @@ impl Document for FontEditor {
                    ui.horizontal_wrapped(|ui| {
                        for i in 0..self.font.length {
                            ui.add(self.draw_glyph( unsafe { char::from_u32_unchecked(i as u32) })).on_hover_ui(|ui| {
       -                        ui.label(format!("char {0}/0x{0:02X}", i));
       -                        ui.label(format!("ASCII '{0}'", unsafe { char::from_u32_unchecked(i as u32) }));
       +                        ui.horizontal(|ui| {
       +                            ui.label(RichText::new("Char").small());
       +                            ui.label(RichText::new(format!("{0}/0x{0:02X}", i)).small().color(Color32::WHITE));
       +                        });
       +                        ui.horizontal(|ui| {
       +                            ui.label(RichText::new("ASCII").small());
       +                            ui.label(RichText::new(format!("'{0}'", unsafe { char::from_u32_unchecked(i as u32) })).small().color(Color32::WHITE));
       +                        });
                            });
                        }
                    })
   DIR diff --git a/src/ui/main_window.rs b/src/ui/main_window.rs
       @@ -1,12 +1,10 @@
        use std::{path::PathBuf, fs, sync::Arc, time::Duration};
        
       -use eframe::{egui::{self, menu, TopBottomPanel, SidePanel}, epaint::ahash::HashMap};
       +use eframe::{egui::{self, menu, TopBottomPanel, SidePanel}};
        use egui_dock::{DockArea, Style,  Tree, Node};
       -use egui_extras::RetainedImage;
        use glow::Context;
        use icy_engine::{BitFont, Buffer};
        use rfd::FileDialog;
       -
        use crate::{Document, FontEditor, model::Tool};
        
        use super::ansi_editor::AnsiEditor;
       @@ -21,7 +19,7 @@ pub struct MainWindow {
        impl MainWindow {
            pub fn new(cc: &eframe::CreationContext<'_>) -> Self {
                let tree = Tree::new(Vec::new());
       -
       +  
                let mut tools: Vec<Box::<dyn Tool>> = Vec::new();
               
                tools.push(Box::new(crate::model::click_imp::ClickTool { }));
       @@ -30,7 +28,8 @@ impl MainWindow {
                    use_back: true,
                    use_fore: true,
                    brush_type: crate::model::brush_imp::BrushType::Shade,
       -            char_code: 176,
       +            char_code: '\u{00B0}',
       +            font_page: 0
                }));
                tools.push(Box::new(crate::model::erase_imp::EraseTool { size: 3, brush_type: crate::model::erase_imp::EraseType::Shade }));
                tools.push(Box::new(crate::model::pipette_imp::PipetteTool { }));
       @@ -146,6 +145,21 @@ impl egui_dock::TabViewer for TabViewer {
        
        impl eframe::App for MainWindow {
            fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
       +        use egui::FontFamily::Proportional;
       +        use egui::FontId;
       +        use egui::TextStyle::*;
       +
       +        let mut style: egui::Style = (*ctx.style()).clone();
       +        style.text_styles = [
       +            (Heading, FontId::new(30.0, Proportional)),
       +            (Body, FontId::new(20.0, Proportional)),
       +            (Monospace, FontId::new(20.0, Proportional)),
       +            (Button, FontId::new(20.0, Proportional)),
       +            (Small, FontId::new(16.0, Proportional)),
       +        ].into();
       +        ctx.set_style(style);
       +
       +        
                TopBottomPanel::top("top_panel").show(ctx, |ui| {
                    menu::bar(ui, |ui| {
                        ui.menu_button("File", |ui| {
       @@ -178,8 +192,12 @@ impl eframe::App for MainWindow {
                    ui.vertical_centered(|ui| {
                        ui.add(crate::palette_switcher(ctx, buffer_opt.clone()));
                    });
       -            ui.add(crate::palette_editor_16(buffer_opt));
       +            ui.add(crate::palette_editor_16(buffer_opt.clone()));
                    crate::add_tool_switcher(ctx, ui, self);
       +
       +            if let Some(tool) = self.tools.get_mut(self.selected_tool) {
       +                tool.show_ui(ctx, ui, buffer_opt.clone());
       +            }
                });
        
                DockArea::new(&mut self.tree)
   DIR diff --git a/src/ui/mod.rs b/src/ui/mod.rs
       @@ -1,4 +1,5 @@
       -mod ansi_editor;
       +pub mod ansi_editor;
       +
        mod main_window;
        use std::error::Error;