URI: 
       Reformatted source. - 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 c72ffb3d49bcbd6237adb18a504fbe679ca13e59
   DIR parent 67e79ad02a95310d8b5bef65b45554480a14256f
  HTML Author: Mike Krüger <mkrueger@posteo.de>
       Date:   Sat, 30 Sep 2023 03:10:05 +0200
       
       Reformatted source.
       
       Diffstat:
         M crates/icy_play/src/main.rs         |      32 +++++--------------------------
         A rustfmt.toml                        |       3 +++
         M src/main.rs                         |      13 ++-----------
         M src/model/tools/brush_imp.rs        |     160 ++++++-------------------------
         M src/model/tools/click_imp.rs        |      52 ++++++-------------------------
         M src/model/tools/draw_ellipse_fille… |      35 +++++--------------------------
         M src/model/tools/draw_ellipse_imp.rs |      35 +++++--------------------------
         M src/model/tools/draw_rectangle_fil… |      35 +++++--------------------------
         M src/model/tools/draw_rectangle_imp… |      35 +++++--------------------------
         M src/model/tools/erase_imp.rs        |      84 +++++--------------------------
         M src/model/tools/fill_imp.rs         |     142 +++++--------------------------
         M src/model/tools/flip_imp.rs         |      25 +++----------------------
         M src/model/tools/font_imp.rs         |     146 ++++++-------------------------
         M src/model/tools/line_imp.rs         |      36 +++++--------------------------
         M src/model/tools/mod.rs              |      53 ++++---------------------------
         M src/model/tools/move_layer_imp.rs   |      63 +++++--------------------------
         M src/model/tools/paste_tool.rs       |     147 +++++++++----------------------
         M src/model/tools/pencil_imp.rs       |      46 +++++--------------------------
         M src/model/tools/pipette_imp.rs      |      95 +++++--------------------------
         M src/model/tools/select_imp.rs       |     101 ++++++-------------------------
         M src/paint/ellipse.rs                |      27 ++++-----------------------
         M src/paint/half_block.rs             |      24 +++++-------------------
         M src/paint/line.rs                   |      16 ++--------------
         M src/paint/mod.rs                    |      72 ++++++--------------------------
         M src/paint/rectangle.rs              |      88 ++++---------------------------
         M src/plugins/mod.rs                  |     314 ++++++++-----------------------
         M src/ui/commands.rs                  |     440 ++++---------------------------
         M src/ui/dialogs/about_dialog.rs      |      11 ++---------
         M src/ui/dialogs/ask_close_file_dial… |      39 ++++++-------------------------
         M src/ui/dialogs/auto_save_dialog.rs  |      21 +++------------------
         M src/ui/dialogs/edit_layer_dialog.rs |     191 ++++++++++++-------------------
         M src/ui/dialogs/edit_sauce_dialog.rs |     123 +++++++++++++------------------
         M src/ui/dialogs/export_file_dialog/… |      20 ++++----------------
         M src/ui/dialogs/export_file_dialog/… |       5 +----
         M src/ui/dialogs/export_file_dialog/… |       5 +----
         M src/ui/dialogs/export_file_dialog/… |      38 +++++++------------------------
         M src/ui/dialogs/export_file_dialog/… |       5 +----
         M src/ui/dialogs/font_manager.rs      |     254 ++++++++++---------------------
         M src/ui/dialogs/font_selector.rs     |     190 +++++++------------------------
         M src/ui/dialogs/new_file_dialog.rs   |     330 ++++++++++---------------------
         M src/ui/dialogs/resize_layer_dialog… |      51 +++++++++++++------------------
         M src/ui/dialogs/select_character_di… |      79 +++++++------------------------
         M src/ui/dialogs/select_outline_dial… |      29 +++++++----------------------
         M src/ui/dialogs/select_palette_dial… |     211 +++++++------------------------
         M src/ui/dialogs/select_tdf_font_dia… |     147 +++++++------------------------
         M src/ui/dialogs/set_canvas_size_dia… |      71 +++++++++++--------------------
         M src/ui/dialogs/settings_dialog.rs   |     139 ++++++++++---------------------
         M src/ui/document.rs                  |       8 +-------
         M src/ui/document_docking.rs          |      89 +++++++------------------------
         M src/ui/editor/animation/highlighti… |       8 +++-----
         M src/ui/editor/animation/mod.rs      |     221 +++++++++++--------------------
         M src/ui/editor/ansi/mod.rs           |     156 ++++++-------------------------
         M src/ui/editor/bitfont/mod.rs        |     165 ++++++++-----------------------
         M src/ui/editor/bitfont/undo.rs       |      25 +++++--------------------
         M src/ui/editor/charfont/mod.rs       |     342 ++++++++++++-------------------
         M src/ui/main_window.rs               |     138 +++++++------------------------
         M src/ui/messages.rs                  |     438 ++++++-------------------------
         M src/ui/palette_editor.rs            |      85 +++++++-------------------------
         M src/ui/settings.rs                  |      19 ++++++-------------
         M src/ui/tool_docking.rs              |      17 +++--------------
         M src/ui/tool_switcher.rs             |      34 ++++++++-----------------------
         M src/ui/tools/channels.rs            |      20 ++++----------------
         M src/ui/tools/char_table.rs          |     135 ++++++++++++-------------------
         M src/ui/tools/layer_view.rs          |     140 +++++--------------------------
         M src/ui/tools/minimap_view.rs        |      59 +++++++------------------------
         M src/ui/top_bar.rs                   |     252 +++++++++++---------------------
       
       66 files changed, 1605 insertions(+), 5024 deletions(-)
       ---
   DIR diff --git a/crates/icy_play/src/main.rs b/crates/icy_play/src/main.rs
       @@ -27,11 +27,7 @@ impl Terminal {
        
        #[derive(Parser)]
        pub struct Cli {
       -    #[arg(
       -        help = "If true modern terminal output (UTF8) is used.",
       -        long,
       -        default_value_t = false
       -    )]
       +    #[arg(help = "If true modern terminal output (UTF8) is used.", long, default_value_t = false)]
            utf8: bool,
        
            #[arg(help = "File to play/show.", required = true)]
       @@ -106,16 +102,11 @@ fn main() {
        
                                    while animator.lock().unwrap().is_playing() {
                                        if let Ok(Some(v)) = io.read(false) {
       -                                    if v.contains(&b'\x1b')
       -                                        || v.contains(&b'\n')
       -                                        || v.contains(&b' ')
       -                                    {
       +                                    if v.contains(&b'\x1b') || v.contains(&b'\n') || v.contains(&b' ') {
                                                break;
                                            }
                                        }
       -                                if let Some((buffer, _, delay)) =
       -                                    animator.lock().unwrap().get_cur_frame_buffer()
       -                                {
       +                                if let Some((buffer, _, delay)) = animator.lock().unwrap().get_cur_frame_buffer() {
                                            show_buffer(&mut io, buffer, false, args.utf8, &term).unwrap();
                                            std::thread::sleep(Duration::from_millis(*delay as u64));
                                        } else {
       @@ -128,14 +119,7 @@ fn main() {
                                    let _ = io.write(b"\x1b\\\x1b[0;0 D");
                                }
                                Commands::ShowFrame { frame } => {
       -                            show_buffer(
       -                                &mut io,
       -                                &animator.lock().unwrap().frames[frame].0,
       -                                true,
       -                                args.utf8,
       -                                &term,
       -                            )
       -                            .unwrap();
       +                            show_buffer(&mut io, &animator.lock().unwrap().frames[frame].0, true, args.utf8, &term).unwrap();
                                }
                            }
                        }
       @@ -153,13 +137,7 @@ fn main() {
            }
        }
        
       -fn show_buffer(
       -    io: &mut Box<dyn Com>,
       -    buffer: &Buffer,
       -    single_frame: bool,
       -    use_utf8: bool,
       -    terminal: &Terminal,
       -) -> anyhow::Result<()> {
       +fn show_buffer(io: &mut Box<dyn Com>, buffer: &Buffer, single_frame: bool, use_utf8: bool, terminal: &Terminal) -> anyhow::Result<()> {
            let mut opt: SaveOptions = SaveOptions::default();
            if use_utf8 {
                opt.modern_terminal_output = true;
   DIR diff --git a/rustfmt.toml b/rustfmt.toml
       @@ -0,0 +1,2 @@
       +max_width = 160
       +use_small_heuristics = "Default"
       +\ No newline at end of file
   DIR diff --git a/src/main.rs b/src/main.rs
       @@ -85,12 +85,7 @@ fn main() {
                            .filter(Box::new(ThresholdFilter::new(level)))
                            .build("stderr", Box::new(stderr)),
                    )
       -            .build(
       -                Root::builder()
       -                    .appender("logfile")
       -                    .appender("stderr")
       -                    .build(LevelFilter::Info),
       -            )
       +            .build(Root::builder().appender("logfile").appender("stderr").build(LevelFilter::Info))
                    .unwrap();
        
                // Use this to change log levels at runtime.
       @@ -124,11 +119,7 @@ fn main() {
            log::info!("Starting iCY DRAW {}", VERSION);
            Plugin::read_plugin_directory();
        
       -    if let Err(err) = eframe::run_native(
       -        &DEFAULT_TITLE,
       -        options,
       -        Box::new(|cc| Box::new(MainWindow::new(cc))),
       -    ) {
       +    if let Err(err) = eframe::run_native(&DEFAULT_TITLE, options, Box::new(|cc| Box::new(MainWindow::new(cc)))) {
                log::error!("Error returned by run_native: {}", err);
            }
            let _ = Settings::save();
   DIR diff --git a/src/model/tools/brush_imp.rs b/src/model/tools/brush_imp.rs
       @@ -61,19 +61,10 @@ impl BrushTool {
                    return;
                }
        
       -        let use_selection = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .is_something_selected();
       -        editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .is_buffer_dirty = true;
       -
       -        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer()
       -        {
       +        let use_selection = editor.buffer_view.lock().get_edit_state().is_something_selected();
       +        editor.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
       +
       +        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
                    layer.get_offset()
                } else {
                    Position::default()
       @@ -82,13 +73,7 @@ impl BrushTool {
                for y in 0..self.size {
                    for x in 0..self.size {
                        let pos = center + Position::new(x, y);
       -                if use_selection
       -                    && !editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state()
       -                        .get_is_selected(pos + offset)
       -                {
       +                if use_selection && !editor.buffer_view.lock().get_edit_state().get_is_selected(pos + offset) {
                            continue;
                        }
                        let ch = editor.get_char_from_cur_layer(pos);
       @@ -118,10 +103,7 @@ impl BrushTool {
                                editor.set_char(pos, AttributedChar::new(char_code, attribute));
                            }
                            BrushType::Solid => {
       -                        editor.set_char(
       -                            center + Position::new(x, y),
       -                            AttributedChar::new(*self.char_code.borrow(), attribute),
       -                        );
       +                        editor.set_char(center + Position::new(x, y), AttributedChar::new(*self.char_code.borrow(), attribute));
                            }
                            BrushType::Color => {
                                editor.set_char(pos, AttributedChar::new(ch.ch, attribute));
       @@ -142,43 +124,22 @@ impl Tool for BrushTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        buffer_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, buffer_opt: Option<&AnsiEditor>) -> Option<Message> {
                let mut result = None;
                self.color_mode.show_ui(ui);
        
                ui.horizontal(|ui| {
                    ui.label(fl!(crate::LANGUAGE_LOADER, "tool-size-label"));
       -            ui.add(
       -                egui::DragValue::new(&mut self.size)
       -                    .clamp_range(1..=20)
       -                    .speed(1),
       -            );
       +            ui.add(egui::DragValue::new(&mut self.size).clamp_range(1..=20).speed(1));
                });
       -        ui.radio_value(
       -            &mut self.brush_type,
       -            BrushType::Shade,
       -            fl!(crate::LANGUAGE_LOADER, "tool-shade"),
       -        );
       +        ui.radio_value(&mut self.brush_type, BrushType::Shade, fl!(crate::LANGUAGE_LOADER, "tool-shade"));
                ui.horizontal(|ui| {
       -            ui.radio_value(
       -                &mut self.brush_type,
       -                BrushType::Solid,
       -                fl!(crate::LANGUAGE_LOADER, "tool-character"),
       -            );
       +            ui.radio_value(&mut self.brush_type, BrushType::Solid, fl!(crate::LANGUAGE_LOADER, "tool-character"));
                    if let Some(buffer_opt) = buffer_opt {
                        result = draw_glyph(ui, buffer_opt, &self.char_code);
                    }
                });
       -        ui.radio_value(
       -            &mut self.brush_type,
       -            BrushType::Color,
       -            fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
       -        );
       +        ui.radio_value(&mut self.brush_type, BrushType::Color, fl!(crate::LANGUAGE_LOADER, "tool-colorize"));
        
                unsafe {
                    if CUSTOM_BRUSH.is_some() {
       @@ -196,11 +157,7 @@ impl Tool for BrushTool {
                }
        
                if self.custom_brush.is_some() {
       -            ui.radio_value(
       -                &mut self.brush_type,
       -                BrushType::Custom,
       -                fl!(crate::LANGUAGE_LOADER, "tool-custom-brush"),
       -            );
       +            ui.radio_value(&mut self.brush_type, BrushType::Custom, fl!(crate::LANGUAGE_LOADER, "tool-custom-brush"));
                    if let Some(image) = &self.image {
                        let w = ui.available_width() - 16.0;
                        let scale = w / image.width() as f32;
       @@ -223,14 +180,7 @@ impl Tool for BrushTool {
                get_edit_state_mut.is_buffer_dirty = true;
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        cur: Position,
       -        cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, cur: Position, cur_abs: Position) -> egui::Response {
                if self.cur_pos != cur {
                    self.cur_pos = cur;
                    let mid = Position::new(-(self.size / 2), -(self.size / 2));
       @@ -247,22 +197,14 @@ impl Tool for BrushTool {
                }
                if matches!(self.brush_type, BrushType::Custom) {
                    editor.clear_overlay_layer();
       -            if let Some(layer) = editor
       -                .buffer_view
       -                .lock()
       -                .get_buffer_mut()
       -                .get_overlay_layer()
       -            {
       +            if let Some(layer) = editor.buffer_view.lock().get_buffer_mut().get_overlay_layer() {
                        if let Some(brush) = &self.custom_brush {
                            let mid = Position::new(-(brush.get_width() / 2), -(brush.get_height() / 2));
                            for y in 0..brush.get_height() {
                                for x in 0..brush.get_width() {
                                    let pos = Position::new(x, y);
                                    let ch = brush.get_char(pos);
       -                            layer.set_char(
       -                                cur + pos + mid,
       -                                AttributedChar::new(ch.ch, ch.attribute),
       -                            );
       +                            layer.set_char(cur + pos + mid, AttributedChar::new(ch.ch, ch.attribute));
                                }
                            }
                        }
       @@ -273,37 +215,22 @@ impl Tool for BrushTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &Response) -> Option<Message> {
                if button == 1 {
       -            let _op: AtomicUndoGuard =
       -                editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-paint-brush"));
       +            let _op: AtomicUndoGuard = editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-paint-brush"));
        
                    self.paint_brush(editor, pos);
                }
                None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                self.paint_brush(editor, editor.drag_pos.cur);
                response
            }
        
            fn handle_drag_begin(&mut self, editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
       -        self.undo_op =
       -            Some(editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-paint-brush")));
       +        self.undo_op = Some(editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-paint-brush")));
                self.paint_brush(editor, editor.drag_pos.cur);
                Event::None
            }
       @@ -315,34 +242,18 @@ impl Tool for BrushTool {
        
            fn get_toolbar_location_text(&self, _editor: &AnsiEditor) -> String {
                let pos = self.cur_pos;
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-position",
       -            line = (pos.y + 1),
       -            column = (pos.x + 1)
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-position", line = (pos.y + 1), column = (pos.x + 1))
            }
        }
        
       -pub fn draw_glyph(
       -    ui: &mut egui::Ui,
       -    editor: &AnsiEditor,
       -    ch: &Rc<RefCell<char>>,
       -) -> Option<Message> {
       +pub fn draw_glyph(ui: &mut egui::Ui, editor: &AnsiEditor, ch: &Rc<RefCell<char>>) -> Option<Message> {
            let font_page = editor.buffer_view.lock().get_caret().get_font_page();
            if let Some(font) = editor.buffer_view.lock().get_buffer().get_font(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 (id, stroke_rect) = ui.allocate_space(Vec2::new(scale * font.size.width as f32, scale * font.size.height as f32));
                let response = ui.interact(stroke_rect, id, Sense::click());
        
       -        let col = if response.hovered() {
       -            Color32::WHITE
       -        } else {
       -            Color32::GRAY
       -        };
       +        let col = if response.hovered() { Color32::WHITE } else { Color32::GRAY };
        
                if response.clicked() {
                    return Some(crate::Message::ShowCharacterSelectionDialog(ch.clone()));
       @@ -358,10 +269,7 @@ pub fn draw_glyph(
                            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,
       -                                ),
       +                                Pos2::new(stroke_rect.left() + x as f32 * scale, stroke_rect.top() + y as f32 * scale),
                                        Vec2::new(scale, scale),
                                    ),
                                    Rounding::none(),
       @@ -372,24 +280,12 @@ pub fn draw_glyph(
                    }
                    response.on_hover_ui(|ui| {
                        ui.horizontal(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-char-label")).small(),
       -                    );
       -                    ui.label(
       -                        RichText::new(format!("{0}/0x{0:02X}", ch as u32))
       -                            .small()
       -                            .color(Color32::WHITE),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-char-label")).small());
       +                    ui.label(RichText::new(format!("{0}/0x{0:02X}", ch as u32)).small().color(Color32::WHITE));
                        });
                        ui.horizontal(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-font-label")).small(),
       -                    );
       -                    ui.label(
       -                        RichText::new(font.name.to_string())
       -                            .small()
       -                            .color(Color32::WHITE),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-font-label")).small());
       +                    ui.label(RichText::new(font.name.to_string()).small().color(Color32::WHITE));
                        });
                    });
                }
   DIR diff --git a/src/model/tools/click_imp.rs b/src/model/tools/click_imp.rs
       @@ -37,23 +37,11 @@ impl Tool for ClickTool {
                &super::icons::CURSOR_SVG
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        _ui: &mut egui::Ui,
       -        _buffer_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, _ui: &mut egui::Ui, _buffer_opt: Option<&AnsiEditor>) -> Option<Message> {
                None
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        cur_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, cur_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 && !is_inside_selection(editor, cur_abs) {
                    editor.set_caret_position(pos);
                    editor.buffer_view.lock().clear_selection();
       @@ -73,13 +61,7 @@ impl Tool for ClickTool {
        
                Event::None
            }
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                let mut rect = if let Some(selection) = editor.buffer_view.lock().get_selection() {
                    selection.as_rectangle()
                } else {
       @@ -88,8 +70,7 @@ impl Tool for ClickTool {
        
                match self.selection_drag {
                    SelectionDrag::Move => {
       -                rect.start = self.start_selection.top_left() - editor.drag_pos.start_abs
       -                    + editor.drag_pos.cur_abs;
       +                rect.start = self.start_selection.top_left() - editor.drag_pos.start_abs + editor.drag_pos.cur_abs;
                        editor.buffer_view.lock().set_selection(rect);
                    }
                    SelectionDrag::Left => {
       @@ -157,14 +138,7 @@ impl Tool for ClickTool {
                response
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _cur: Position,
       -        cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _cur: Position, cur_abs: Position) -> egui::Response {
                match get_selection_drag(editor, cur_abs) {
                    SelectionDrag::None => ui.output_mut(|o| o.cursor_icon = egui::CursorIcon::Text),
                    SelectionDrag::Move => ui.output_mut(|o| o.cursor_icon = egui::CursorIcon::Move),
       @@ -262,8 +236,7 @@ impl Tool for ClickTool {
                            editor.set_caret(next_tab, pos.y);
                        } else {
                            let tabs = 1 + pos.x / tab_size;
       -                    let next_tab = (editor.buffer_view.lock().get_buffer().get_width() - 1)
       -                        .min(tabs * tab_size);
       +                    let next_tab = (editor.buffer_view.lock().get_buffer().get_width() - 1).min(tabs * tab_size);
                            editor.set_caret(next_tab, pos.y);
                        }
                    }
       @@ -311,12 +284,7 @@ impl Tool for ClickTool {
                            if VALID_OUTLINE_CHARS.contains(typed_char) {
                                editor.type_key(typed_char);
                            } else if let '1'..='8' = typed_char {
       -                        editor.type_key(
       -                            VALID_OUTLINE_CHARS
       -                                .chars()
       -                                .nth(10 + typed_char as usize - b'1' as usize)
       -                                .unwrap(),
       -                        );
       +                        editor.type_key(VALID_OUTLINE_CHARS.chars().nth(10 + typed_char as usize - b'1' as usize).unwrap());
                            }
                        } else {
                            editor.type_key(typed_char);
       @@ -432,8 +400,7 @@ impl ClickTool {
            }
        
            fn move_right(&mut self, editor: &AnsiEditor, rect: &mut Rectangle) {
       -        rect.size.width = self.start_selection.get_width() - editor.drag_pos.start_abs.x
       -            + editor.drag_pos.cur_abs.x;
       +        rect.size.width = self.start_selection.get_width() - editor.drag_pos.start_abs.x + editor.drag_pos.cur_abs.x;
                if rect.size.width < 0 {
                    rect.start.x = self.start_selection.left() + rect.size.width;
                    rect.size.width = self.start_selection.left() - rect.start.x;
       @@ -452,8 +419,7 @@ impl ClickTool {
            }
        
            fn move_bottom(&mut self, editor: &AnsiEditor, rect: &mut Rectangle) {
       -        rect.size.height = self.start_selection.get_height() - editor.drag_pos.start_abs.y
       -            + editor.drag_pos.cur_abs.y;
       +        rect.size.height = self.start_selection.get_height() - editor.drag_pos.start_abs.y + editor.drag_pos.cur_abs.y;
                if rect.size.height < 0 {
                    rect.start.y = self.start_selection.top() + rect.size.height;
                    rect.size.height = self.start_selection.top() - rect.start.y;
   DIR diff --git a/src/model/tools/draw_ellipse_filled_imp.rs b/src/model/tools/draw_ellipse_filled_imp.rs
       @@ -37,47 +37,22 @@ impl Tool for DrawEllipseFilledTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), false)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), false)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
                let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
       -        fill_ellipse(
       -            &mut editor.buffer_view.lock(),
       -            start,
       -            end,
       -            self.draw_mode.clone(),
       -            self.color_mode,
       -        );
       +        fill_ellipse(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
                response
            }
        
   DIR diff --git a/src/model/tools/draw_ellipse_imp.rs b/src/model/tools/draw_ellipse_imp.rs
       @@ -37,47 +37,22 @@ impl Tool for DrawEllipseTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), false)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), false)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
                let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
       -        draw_ellipse(
       -            &mut editor.buffer_view.lock(),
       -            start,
       -            end,
       -            self.draw_mode.clone(),
       -            self.color_mode,
       -        );
       +        draw_ellipse(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
                response
            }
        
   DIR diff --git a/src/model/tools/draw_rectangle_filled_imp.rs b/src/model/tools/draw_rectangle_filled_imp.rs
       @@ -38,47 +38,22 @@ impl Tool for DrawRectangleFilledTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), false)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), false)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
                let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
       -        fill_rectangle(
       -            &mut editor.buffer_view.lock(),
       -            start,
       -            end,
       -            self.draw_mode.clone(),
       -            self.color_mode,
       -        );
       +        fill_rectangle(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
                response
            }
        
   DIR diff --git a/src/model/tools/draw_rectangle_imp.rs b/src/model/tools/draw_rectangle_imp.rs
       @@ -36,47 +36,22 @@ impl Tool for DrawRectangleTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), true)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), true)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                editor.clear_overlay_layer();
                let p1 = editor.drag_pos.start_half_block;
                let p2 = editor.half_block_click_pos;
                let start = Position::new(p1.x.min(p2.x), p1.y.min(p2.y));
                let end = Position::new(p1.x.max(p2.x), p1.y.max(p2.y));
       -        draw_rectangle(
       -            &mut editor.buffer_view.lock(),
       -            start,
       -            end,
       -            self.draw_mode.clone(),
       -            self.color_mode,
       -        );
       +        draw_rectangle(&mut editor.buffer_view.lock(), start, end, self.draw_mode.clone(), self.color_mode);
                response
            }
        
   DIR diff --git a/src/model/tools/erase_imp.rs b/src/model/tools/erase_imp.rs
       @@ -37,32 +37,17 @@ impl EraseTool {
        
                let center = pos + mid;
                let gradient = ['\u{00DB}', '\u{00B2}', '\u{00B1}', '\u{00B0}', ' '];
       -        let use_selection = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .is_something_selected();
       -        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer()
       -        {
       +        let use_selection = editor.buffer_view.lock().get_edit_state().is_something_selected();
       +        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
                    layer.get_offset()
                } else {
                    Position::default()
                };
       -        editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .is_buffer_dirty = true;
       +        editor.buffer_view.lock().get_edit_state_mut().is_buffer_dirty = true;
                for y in 0..self.size {
                    for x in 0..self.size {
                        let pos = center + Position::new(x, y);
       -                if use_selection
       -                    && !editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state()
       -                        .get_is_selected(pos + offset)
       -                {
       +                if use_selection && !editor.buffer_view.lock().get_edit_state().get_is_selected(pos + offset) {
                            continue;
                        }
                        match self.brush_type {
       @@ -109,36 +94,18 @@ impl Tool for EraseTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        _editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, _editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                ui.horizontal(|ui| {
                    ui.label(fl!(crate::LANGUAGE_LOADER, "tool-size-label"));
       -            ui.add(
       -                egui::DragValue::new(&mut self.size)
       -                    .clamp_range(1..=20)
       -                    .speed(1),
       -            );
       +            ui.add(egui::DragValue::new(&mut self.size).clamp_range(1..=20).speed(1));
                });
       -        ui.radio_value(
       -            &mut self.brush_type,
       -            EraseType::Solid,
       -            fl!(crate::LANGUAGE_LOADER, "tool-solid"),
       -        );
       -        ui.radio_value(
       -            &mut self.brush_type,
       -            EraseType::Shade,
       -            fl!(crate::LANGUAGE_LOADER, "tool-shade"),
       -        );
       +        ui.radio_value(&mut self.brush_type, EraseType::Solid, fl!(crate::LANGUAGE_LOADER, "tool-solid"));
       +        ui.radio_value(&mut self.brush_type, EraseType::Shade, fl!(crate::LANGUAGE_LOADER, "tool-shade"));
                None
            }
        
            fn handle_no_hover(&mut self, editor: &mut AnsiEditor) {
       -        let lock: &mut eframe::epaint::mutex::MutexGuard<'_, icy_engine_egui::BufferView> =
       -            &mut editor.buffer_view.lock();
       +        let lock: &mut eframe::epaint::mutex::MutexGuard<'_, icy_engine_egui::BufferView> = &mut editor.buffer_view.lock();
                let get_edit_state_mut = lock.get_edit_state_mut();
                if get_edit_state_mut.get_tool_overlay_mask_mut().is_empty() {
                    return;
       @@ -147,14 +114,7 @@ impl Tool for EraseTool {
                get_edit_state_mut.is_buffer_dirty = true;
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        cur: Position,
       -        cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, cur: Position, cur_abs: Position) -> egui::Response {
                if self.cur_pos != cur {
                    self.cur_pos = cur;
                    let lock = &mut editor.buffer_view.lock();
       @@ -172,14 +132,7 @@ impl Tool for EraseTool {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    let _undo = editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-eraser"));
                    self.eraser(editor, pos);
       @@ -187,13 +140,7 @@ impl Tool for EraseTool {
                None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                self.eraser(editor, editor.drag_pos.cur);
                response
            }
       @@ -211,11 +158,6 @@ impl Tool for EraseTool {
        
            fn get_toolbar_location_text(&self, _editor: &AnsiEditor) -> String {
                let pos = self.cur_pos;
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-position",
       -            line = (pos.y + 1),
       -            column = (pos.x + 1)
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-position", line = (pos.y + 1), column = (pos.x + 1))
            }
        }
   DIR diff --git a/src/model/tools/fill_imp.rs b/src/model/tools/fill_imp.rs
       @@ -47,26 +47,10 @@ struct FillOperation {
        }
        
        impl FillOperation {
       -    pub fn new(
       -        fill_tool: &FillTool,
       -        editor: &AnsiEditor,
       -        base_char: AttributedChar,
       -        new_ch: AttributedChar,
       -    ) -> Self {
       -        let size = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .get_cur_layer()
       -            .unwrap()
       -            .get_size();
       -        let use_selection = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .is_something_selected();
       -        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer()
       -        {
       +    pub fn new(fill_tool: &FillTool, editor: &AnsiEditor, base_char: AttributedChar, new_ch: AttributedChar) -> Self {
       +        let size = editor.buffer_view.lock().get_edit_state().get_cur_layer().unwrap().get_size();
       +        let use_selection = editor.buffer_view.lock().get_edit_state().is_something_selected();
       +        let offset = if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
                    layer.get_offset()
                } else {
                    Position::default()
       @@ -86,74 +70,39 @@ impl FillOperation {
            }
        
            pub fn fill(&mut self, editor: &mut AnsiEditor, pos: Position) {
       -        if pos.x < 0
       -            || pos.y < 0
       -            || pos.x >= self.size.width
       -            || pos.y >= self.size.height
       -            || !self.visited.insert(pos)
       -        {
       +        if pos.x < 0 || pos.y < 0 || pos.x >= self.size.width || pos.y >= self.size.height || !self.visited.insert(pos) {
                    return;
                }
        
       -        if !self.use_selection
       -            || editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state()
       -                .get_is_selected(pos + self.offset)
       -        {
       -            let cur_char = editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state()
       -                .get_cur_layer()
       -                .unwrap()
       -                .get_char(pos);
       +        if !self.use_selection || editor.buffer_view.lock().get_edit_state().get_is_selected(pos + self.offset) {
       +            let cur_char = editor.buffer_view.lock().get_edit_state().get_cur_layer().unwrap().get_char(pos);
        
                    let mut repl_ch = cur_char;
        
                    match self.fill_type {
                        FillType::Character => {
       -                    if self.use_exact_matching && cur_char != self.base_char
       -                        || !self.use_exact_matching && cur_char.ch != self.base_char.ch
       -                    {
       +                    if self.use_exact_matching && cur_char != self.base_char || !self.use_exact_matching && cur_char.ch != self.base_char.ch {
                                return;
                            }
                            repl_ch.ch = self.new_char.ch;
                            repl_ch.set_font_page(self.new_char.get_font_page());
                        }
                        FillType::Colorize => {
       -                    if self.use_exact_matching && cur_char != self.base_char
       -                        || !self.use_exact_matching
       -                            && cur_char.attribute != self.base_char.attribute
       -                    {
       +                    if self.use_exact_matching && cur_char != self.base_char || !self.use_exact_matching && cur_char.attribute != self.base_char.attribute {
                                return;
                            }
                        }
                    }
                    if self.color_mode.use_fore() {
       -                repl_ch
       -                    .attribute
       -                    .set_foreground(self.new_char.attribute.get_foreground());
       -                repl_ch
       -                    .attribute
       -                    .set_is_bold(self.new_char.attribute.is_bold());
       +                repl_ch.attribute.set_foreground(self.new_char.attribute.get_foreground());
       +                repl_ch.attribute.set_is_bold(self.new_char.attribute.is_bold());
                    }
        
                    if self.color_mode.use_back() {
       -                repl_ch
       -                    .attribute
       -                    .set_background(self.new_char.attribute.get_background());
       +                repl_ch.attribute.set_background(self.new_char.attribute.get_background());
                    }
        
       -            repl_ch.set_font_page(
       -                editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_caret()
       -                    .get_attribute()
       -                    .get_font_page(),
       -            );
       +            repl_ch.set_font_page(editor.buffer_view.lock().get_caret().get_attribute().get_font_page());
                    repl_ch.attribute.attr &= !icy_engine::attribute::INVISIBLE;
                    editor.set_char(pos, repl_ch);
                }
       @@ -176,82 +125,37 @@ impl Tool for FillTool {
            fn use_caret(&self) -> bool {
                false
            }
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                let mut result = None;
                self.color_mode.show_ui(ui);
        
                ui.horizontal(|ui| {
       -            ui.radio_value(
       -                &mut self.fill_type,
       -                FillType::Character,
       -                fl!(crate::LANGUAGE_LOADER, "tool-character"),
       -            );
       +            ui.radio_value(&mut self.fill_type, FillType::Character, fl!(crate::LANGUAGE_LOADER, "tool-character"));
                    if let Some(editor) = editor_opt {
                        result = draw_glyph(ui, editor, &self.char_code);
                    }
                });
       -        ui.radio_value(
       -            &mut self.fill_type,
       -            FillType::Colorize,
       -            fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
       -        );
       +        ui.radio_value(&mut self.fill_type, FillType::Colorize, fl!(crate::LANGUAGE_LOADER, "tool-colorize"));
        
       -        ui.checkbox(
       -            &mut self.use_exact_matching,
       -            fl!(crate::LANGUAGE_LOADER, "tool-fill-exact_match_label"),
       -        );
       +        ui.checkbox(&mut self.use_exact_matching, fl!(crate::LANGUAGE_LOADER, "tool-fill-exact_match_label"));
        
                result
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    if editor.get_cur_layer_index() >= editor.buffer_view.lock().get_buffer().layers.len() {
                        return None;
                    }
                    let attr = editor.buffer_view.lock().get_caret().get_attribute();
       -            let ch = editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state()
       -                .get_cur_layer()
       -                .unwrap()
       -                .get_char(pos);
       -            if self.color_mode.use_fore()
       -                || self.color_mode.use_back()
       -                || matches!(self.fill_type, FillType::Character)
       -            {
       -                let _undo =
       -                    editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-bucket-fill"));
       -                let mut op = FillOperation::new(
       -                    self,
       -                    editor,
       -                    ch,
       -                    AttributedChar::new(*self.char_code.borrow(), attr),
       -                );
       +            let ch = editor.buffer_view.lock().get_edit_state().get_cur_layer().unwrap().get_char(pos);
       +            if self.color_mode.use_fore() || self.color_mode.use_back() || matches!(self.fill_type, FillType::Character) {
       +                let _undo = editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-bucket-fill"));
       +                let mut op = FillOperation::new(self, editor, ch, AttributedChar::new(*self.char_code.borrow(), attr));
                        op.fill(editor, pos);
                    }
                }
   DIR diff --git a/src/model/tools/flip_imp.rs b/src/model/tools/flip_imp.rs
       @@ -15,33 +15,14 @@ impl Tool for FlipTool {
            fn use_selection(&self) -> bool {
                false
            }
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        _ui: &mut egui::Ui,
       -        _editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, _ui: &mut egui::Ui, _editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                None
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    let mut ch = editor.get_char(pos);
        
   DIR diff --git a/src/model/tools/font_imp.rs b/src/model/tools/font_imp.rs
       @@ -29,10 +29,7 @@ impl FontTool {
            }*/
        
            pub(crate) fn is_hidden(entry: &DirEntry) -> bool {
       -        entry
       -            .file_name()
       -            .to_str()
       -            .map_or(false, |s| s.starts_with('.'))
       +        entry.file_name().to_str().map_or(false, |s| s.starts_with('.'))
            }
        
            pub fn install_watcher(&self) {
       @@ -108,22 +105,14 @@ fn read_zip_archive(data: Vec<u8>, fonts: &mut Vec<TheDrawFont>) {
                        match archive.by_index(i) {
                            Ok(mut file) => {
                                if let Some(name) = file.enclosed_name() {
       -                            if name
       -                                .to_string_lossy()
       -                                .to_ascii_lowercase()
       -                                .ends_with(".tdf")
       -                            {
       +                            if name.to_string_lossy().to_ascii_lowercase().ends_with(".tdf") {
                                        let mut data = Vec::new();
                                        file.read_to_end(&mut data).unwrap_or_default();
        
                                        if let Ok(loaded_fonts) = TheDrawFont::from_tdf_bytes(&data) {
                                            fonts.extend(loaded_fonts);
                                        }
       -                            } else if name
       -                                .to_string_lossy()
       -                                .to_ascii_lowercase()
       -                                .ends_with(".zip")
       -                            {
       +                            } else if name.to_string_lossy().to_ascii_lowercase().ends_with(".zip") {
                                        let mut data = Vec::new();
                                        file.read_to_end(&mut data).unwrap_or_default();
                                        read_zip_archive(data, fonts);
       @@ -150,12 +139,7 @@ impl Tool for FontTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        _editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, _editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                let mut select = false;
                let font_count = self.fonts.lock().unwrap().len();
                let selected_font = *self.selected_font.lock().unwrap();
       @@ -170,11 +154,8 @@ impl Tool for FontTool {
                            selected_text = font.name.clone();
                        }
                    }
       -            let selected_text =
       -                RichText::new(selected_text).font(FontId::new(18.0, FontFamily::Proportional));
       -            select = ui
       -                .add_enabled(font_count > 0, Button::new(selected_text))
       -                .clicked();
       +            let selected_text = RichText::new(selected_text).font(FontId::new(18.0, FontFamily::Proportional));
       +            select = ui.add_enabled(font_count > 0, Button::new(selected_text)).clicked();
                });
        
                if font_count == 0 {
       @@ -182,13 +163,7 @@ impl Tool for FontTool {
                    let mut msg = None;
                    ui.vertical_centered(|ui| {
                        ui.label(fl!(crate::LANGUAGE_LOADER, "font_tool_no_fonts_label"));
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "font_tool_open_directory_button"
       -                    ))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "font_tool_open_directory_button")).clicked() {
                            msg = Some(Message::OpenTdfDirectory);
                        }
                    });
       @@ -213,11 +188,7 @@ impl Tool for FontTool {
                                        ui.style().visuals.text_color()
                                    };
        
       -                            ui.colored_label(
       -                                color,
       -                                RichText::new(ch.to_string())
       -                                    .font(FontId::new(14.0, FontFamily::Monospace)),
       -                            );
       +                            ui.colored_label(color, RichText::new(ch.to_string()).font(FontId::new(14.0, FontFamily::Monospace)));
                                }
                            }
                        });
       @@ -234,11 +205,7 @@ impl Tool for FontTool {
                                        ui.style().visuals.text_color()
                                    };
        
       -                            ui.colored_label(
       -                                color,
       -                                RichText::new(ch.to_string())
       -                                    .font(FontId::new(14.0, FontFamily::Monospace)),
       -                            );
       +                            ui.colored_label(color, RichText::new(ch.to_string()).font(FontId::new(14.0, FontFamily::Monospace)));
                                }
                            }
                        });
       @@ -254,11 +221,7 @@ impl Tool for FontTool {
                                        ui.style().visuals.text_color()
                                    };
        
       -                            ui.colored_label(
       -                                color,
       -                                RichText::new(ch.to_string())
       -                                    .font(FontId::new(14.0, FontFamily::Monospace)),
       -                            );
       +                            ui.colored_label(color, RichText::new(ch.to_string()).font(FontId::new(14.0, FontFamily::Monospace)));
                                }
                            }
                        });
       @@ -273,11 +236,7 @@ impl Tool for FontTool {
                                        ui.style().visuals.text_color()
                                    };
        
       -                            ui.colored_label(
       -                                color,
       -                                RichText::new(ch.to_string())
       -                                    .font(FontId::new(14.0, FontFamily::Monospace)),
       -                            );
       +                            ui.colored_label(color, RichText::new(ch.to_string()).font(FontId::new(14.0, FontFamily::Monospace)));
                                }
                            }
                        });
       @@ -290,13 +249,7 @@ impl Tool for FontTool {
                            ui.add_space(32.0);
                            let mut msg = None;
                            ui.vertical_centered(|ui| {
       -                        if ui
       -                            .button(fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "font_tool_select_outline_button"
       -                            ))
       -                            .clicked()
       -                        {
       +                        if ui.button(fl!(crate::LANGUAGE_LOADER, "font_tool_select_outline_button")).clicked() {
                                    msg = Some(Message::ShowOutlineDialog);
                                }
                            });
       @@ -308,23 +261,13 @@ impl Tool for FontTool {
                }
        
                if select {
       -            Some(Message::SelectFontDialog(
       -                self.fonts.clone(),
       -                self.selected_font.clone(),
       -            ))
       +            Some(Message::SelectFontDialog(self.fonts.clone(), self.selected_font.clone()))
                } else {
                    None
                }
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    editor.set_caret_position(pos);
                    editor.buffer_view.lock().clear_selection();
       @@ -332,14 +275,7 @@ impl Tool for FontTool {
                None
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Text)
            }
        
       @@ -370,10 +306,7 @@ impl Tool for FontTool {
                        if let MModifiers::Control = modifier {
                            let end = editor.buffer_view.lock().get_buffer().get_width();
                            for i in 0..end {
       -                        if !editor
       -                            .get_char_from_cur_layer(pos.with_x(i))
       -                            .is_transparent()
       -                        {
       +                        if !editor.get_char_from_cur_layer(pos.with_x(i)).is_transparent() {
                                    editor.set_caret(i, pos.y);
                                    return Event::None;
                                }
       @@ -386,10 +319,7 @@ impl Tool for FontTool {
                        if let MModifiers::Control = modifier {
                            let end = editor.buffer_view.lock().get_buffer().get_width();
                            for i in (0..end).rev() {
       -                        if !editor
       -                            .get_char_from_cur_layer(pos.with_x(i))
       -                            .is_transparent()
       -                        {
       +                        if !editor.get_char_from_cur_layer(pos.with_x(i)).is_transparent() {
                                    editor.set_caret(i, pos.y);
                                    return Event::None;
                                }
       @@ -416,13 +346,7 @@ impl Tool for FontTool {
                            let mut render = false;
                            let mut reverse_count = 0;
        
       -                    let op = if let Ok(stack) = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state()
       -                        .get_undo_stack()
       -                        .lock()
       -                    {
       +                    let op = if let Ok(stack) = editor.buffer_view.lock().get_edit_state().get_undo_stack().lock() {
                                for i in (0..stack.len()).rev() {
                                    match stack[i].get_operation_type() {
                                        OperationType::RenderCharacter => {
       @@ -448,15 +372,11 @@ impl Tool for FontTool {
        
                            if render {
                                if let Some(op) = op {
       -                            let _ = editor
       -                                .buffer_view
       -                                .lock()
       -                                .get_edit_state_mut()
       -                                .push_reverse_undo(
       -                                    fl!(crate::LANGUAGE_LOADER, "undo-delete_character"),
       -                                    op,
       -                                    OperationType::ReversedRenderCharacter,
       -                                );
       +                            let _ = editor.buffer_view.lock().get_edit_state_mut().push_reverse_undo(
       +                                fl!(crate::LANGUAGE_LOADER, "undo-delete_character"),
       +                                op,
       +                                OperationType::ReversedRenderCharacter,
       +                            );
                                    use_backspace = false;
                                }
                            }
       @@ -472,30 +392,18 @@ impl Tool for FontTool {
                            .buffer_view
                            .lock()
                            .get_edit_state_mut()
       -                    .begin_typed_atomic_undo(
       -                        fl!(crate::LANGUAGE_LOADER, "undo-render_character"),
       -                        OperationType::RenderCharacter,
       -                    );
       +                    .begin_typed_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-render_character"), OperationType::RenderCharacter);
        
                        let outline_style = if editor.outline_font_mode {
                            usize::MAX
                        } else {
                            Settings::get_font_outline_style()
                        };
       -                editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .set_outline_style(outline_style);
       +                editor.buffer_view.lock().get_edit_state_mut().set_outline_style(outline_style);
        
       -                let _ = editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .undo_caret_position();
       +                let _ = editor.buffer_view.lock().get_edit_state_mut().undo_caret_position();
        
       -                let opt_size: Option<Size> =
       -                    font.render(editor.buffer_view.lock().get_edit_state_mut(), ch as u8);
       +                let opt_size: Option<Size> = font.render(editor.buffer_view.lock().get_edit_state_mut(), ch as u8);
                        if let Some(size) = opt_size {
                            editor.set_caret(c_pos.x + size.width + font.spaces, c_pos.y);
                            let new_pos = editor.get_caret_position();
   DIR diff --git a/src/model/tools/line_imp.rs b/src/model/tools/line_imp.rs
       @@ -171,49 +171,23 @@ impl Tool for LineTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), false)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), false)
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    editor.set_caret_position(pos);
                }
                None
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                editor.clear_overlay_layer();
                draw_line(
                    &mut editor.buffer_view.lock(),
   DIR diff --git a/src/model/tools/mod.rs b/src/model/tools/mod.rs
       @@ -107,25 +107,13 @@ pub trait Tool {
                true
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message>;
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message>;
        
            fn handle_key(&mut self, _editor: &mut AnsiEditor, _key: MKey, _modifier: MModifiers) -> Event {
                Event::None
            }
        
       -    fn handle_click(
       -        &mut self,
       -        _editor: &mut AnsiEditor,
       -        _button: i32,
       -        _pos: Position,
       -        _pos_abs: Position,
       -        _response: &Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, _editor: &mut AnsiEditor, _button: i32, _pos: Position, _pos_abs: Position, _response: &Response) -> Option<Message> {
                None
            }
        
       @@ -133,24 +121,11 @@ pub trait Tool {
                Event::None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: Response,
       -        _editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: Response, _editor: &mut AnsiEditor, _calc: &TerminalCalc) -> Response {
                response
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> Response {
                response
            }
        
       @@ -167,26 +142,12 @@ pub trait Tool {
        
        fn toolbar_pos_sel_text(editor: &AnsiEditor, show_selection: bool) -> String {
            let pos = editor.get_caret_position();
       -    let sel = if show_selection {
       -        editor.buffer_view.lock().get_selection()
       -    } else {
       -        None
       -    };
       +    let sel = if show_selection { editor.buffer_view.lock().get_selection() } else { None };
        
            if let Some(sel) = sel {
                let r = sel.as_rectangle();
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-size",
       -            colums = r.size.height,
       -            rows = r.size.width
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-size", colums = r.size.height, rows = r.size.width)
            } else {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-position",
       -            line = (pos.y + 1),
       -            column = (pos.x + 1)
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-position", line = (pos.y + 1), column = (pos.x + 1))
            }
        }
   DIR diff --git a/src/model/tools/move_layer_imp.rs b/src/model/tools/move_layer_imp.rs
       @@ -23,48 +23,26 @@ impl Tool for MoveLayer {
            fn use_selection(&self) -> bool {
                false
            }
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        _ui: &mut egui::Ui,
       -        _editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, _ui: &mut egui::Ui, _editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                None
            }
        
            fn handle_drag_begin(&mut self, editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
                self.drag_started = false;
        
       -        if let Some(layer) = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_cur_layer_mut()
       -        {
       +        if let Some(layer) = editor.buffer_view.lock().get_edit_state_mut().get_cur_layer_mut() {
                    self.start_offset = layer.get_offset();
                    self.drag_started = true;
                }
                Event::None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                if !self.drag_started {
                    return response;
                }
       -        if let Some(layer) = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_cur_layer_mut()
       -        {
       -            self.drag_offset =
       -                self.start_offset + editor.drag_pos.cur_abs - editor.drag_pos.start_abs;
       +        if let Some(layer) = editor.buffer_view.lock().get_edit_state_mut().get_cur_layer_mut() {
       +            self.drag_offset = self.start_offset + editor.drag_pos.cur_abs - editor.drag_pos.start_abs;
                    layer.set_preview_offset(Some(self.drag_offset));
                }
                response.on_hover_cursor(egui::CursorIcon::Grabbing)
       @@ -74,14 +52,7 @@ impl Tool for MoveLayer {
                get_layer_offset_text(editor)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Move)
            }
        
       @@ -89,30 +60,14 @@ impl Tool for MoveLayer {
                if !self.drag_started {
                    return None;
                }
       -        to_message(
       -            editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .move_layer(self.drag_offset),
       -        )
       +        to_message(editor.buffer_view.lock().get_edit_state_mut().move_layer(self.drag_offset))
            }
        }
        
        pub(super) fn get_layer_offset_text(editor: &AnsiEditor) -> String {
       -    if let Some(layer) = editor
       -        .buffer_view
       -        .lock()
       -        .get_edit_state_mut()
       -        .get_cur_layer()
       -    {
       +    if let Some(layer) = editor.buffer_view.lock().get_edit_state_mut().get_cur_layer() {
                let pos = layer.get_offset();
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-layer_offset",
       -            line = pos.y,
       -            column = pos.x
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-layer_offset", line = pos.y, column = pos.x)
            } else {
                String::new()
            }
   DIR diff --git a/src/model/tools/paste_tool.rs b/src/model/tools/paste_tool.rs
       @@ -1,5 +1,5 @@
        use super::{move_layer_imp::get_layer_offset_text, Event, Position, Tool};
       -use crate::{AnsiEditor, Message, to_message};
       +use crate::{to_message, AnsiEditor, Message};
        use eframe::egui::{self, Key};
        use i18n_embed_fl::fl;
        use icy_engine_egui::TerminalCalc;
       @@ -42,12 +42,7 @@ impl Tool for PasteTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                let mut result = None;
                if let Some(editor) = editor_opt {
                    if let Some(layer) = editor.buffer_view.lock().get_edit_state().get_cur_layer() {
       @@ -63,66 +58,43 @@ impl Tool for PasteTool {
        
                ui.label(fl!(crate::LANGUAGE_LOADER, "paste_mode-description"));
                ui.add_space(8.0);
       -        egui::Grid::new("paste_mode_grid")
       -            .num_columns(2)
       -            .spacing([4.0, 4.0])
       -            .show(ui, |ui| {
       -                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.strong("S -");
       -                });
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "paste_mode-stamp"))
       -                    .clicked()
       -                    || ui.input(|i| i.key_pressed(Key::S))
       -                {
       -                    result = Some(Message::StampLayerDown);
       -                }
       -                ui.end_row();
       -                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.strong("R -");
       -                });
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "paste_mode-rotate"))
       -                    .clicked()
       -                    || ui.input(|i| i.key_pressed(Key::R))
       -                {
       -                    result = Some(Message::RotateLayer);
       -                }
       -                ui.end_row();
       -                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.strong("X -");
       -                });
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "paste_mode-flipx"))
       -                    .clicked()
       -                    || ui.input(|i| i.key_pressed(Key::X))
       -                {
       -                    result = Some(Message::FlipX);
       -                }
       -                ui.end_row();
       -                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.strong("Y -");
       -                });
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "paste_mode-flipy"))
       -                    .clicked()
       -                    || ui.input(|i| i.key_pressed(Key::Y))
       -                {
       -                    result = Some(Message::FlipY);
       -                }
       -                ui.end_row();
       -                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.strong("T -");
       -                });
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "paste_mode-transparent"))
       -                    .clicked()
       -                    || ui.input(|i| i.key_pressed(Key::T))
       -                {
       -                    result = Some(Message::MakeLayerTransparent);
       -                }
       -                ui.end_row();
       +        egui::Grid::new("paste_mode_grid").num_columns(2).spacing([4.0, 4.0]).show(ui, |ui| {
       +            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.strong("S -");
                    });
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "paste_mode-stamp")).clicked() || ui.input(|i| i.key_pressed(Key::S)) {
       +                result = Some(Message::StampLayerDown);
       +            }
       +            ui.end_row();
       +            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.strong("R -");
       +            });
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "paste_mode-rotate")).clicked() || ui.input(|i| i.key_pressed(Key::R)) {
       +                result = Some(Message::RotateLayer);
       +            }
       +            ui.end_row();
       +            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.strong("X -");
       +            });
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "paste_mode-flipx")).clicked() || ui.input(|i| i.key_pressed(Key::X)) {
       +                result = Some(Message::FlipX);
       +            }
       +            ui.end_row();
       +            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.strong("Y -");
       +            });
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "paste_mode-flipy")).clicked() || ui.input(|i| i.key_pressed(Key::Y)) {
       +                result = Some(Message::FlipY);
       +            }
       +            ui.end_row();
       +            ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.strong("T -");
       +            });
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "paste_mode-transparent")).clicked() || ui.input(|i| i.key_pressed(Key::T)) {
       +                result = Some(Message::MakeLayerTransparent);
       +            }
       +            ui.end_row();
       +        });
        
                if ctx.input(|i| i.key_pressed(Key::Escape)) {
                    return Some(Message::RemoveFloatingLayer);
       @@ -130,40 +102,22 @@ impl Tool for PasteTool {
                result
            }
        
       -
            fn handle_drag_begin(&mut self, editor: &mut AnsiEditor, _response: &egui::Response) -> Event {
                self.drag_started = false;
        
       -        if let Some(layer) = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_cur_layer_mut()
       -        {
       +        if let Some(layer) = editor.buffer_view.lock().get_edit_state_mut().get_cur_layer_mut() {
                    self.start_offset = layer.get_offset();
                    self.drag_started = true;
                }
                Event::None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                if !self.drag_started {
                    return response;
                }
       -        if let Some(layer) = editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_cur_layer_mut()
       -        {
       -            self.drag_offset =
       -                self.start_offset + editor.drag_pos.cur_abs - editor.drag_pos.start_abs;
       +        if let Some(layer) = editor.buffer_view.lock().get_edit_state_mut().get_cur_layer_mut() {
       +            self.drag_offset = self.start_offset + editor.drag_pos.cur_abs - editor.drag_pos.start_abs;
                    layer.set_preview_offset(Some(self.drag_offset));
                }
                response.on_hover_cursor(egui::CursorIcon::Grabbing)
       @@ -173,14 +127,7 @@ impl Tool for PasteTool {
                get_layer_offset_text(editor)
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        _cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, _cur: Position, _cur_abs: Position) -> egui::Response {
                response.on_hover_cursor(egui::CursorIcon::Move)
            }
        
       @@ -188,12 +135,6 @@ impl Tool for PasteTool {
                if !self.drag_started {
                    return None;
                }
       -        to_message(
       -            editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .move_layer(self.drag_offset),
       -        )
       +        to_message(editor.buffer_view.lock().get_edit_state_mut().move_layer(self.drag_offset))
            }
        }
   DIR diff --git a/src/model/tools/pencil_imp.rs b/src/model/tools/pencil_imp.rs
       @@ -47,29 +47,15 @@ impl Tool for PencilTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                self.color_mode.show_ui(ui);
       -        self.draw_mode
       -            .show_ui(ui, editor_opt, self.char_code.clone(), false)
       +        self.draw_mode.show_ui(ui, editor_opt, self.char_code.clone(), false)
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    self.last_pos = pos;
       -            let _op: AtomicUndoGuard =
       -                editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-pencil"));
       +            let _op: AtomicUndoGuard = editor.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-pencil"));
                    editor.clear_overlay_layer();
                    plot_point(
                        &mut editor.buffer_view.lock(),
       @@ -82,25 +68,12 @@ impl Tool for PencilTool {
                }
                None
            }
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        _editor: &mut AnsiEditor,
       -        cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, _editor: &mut AnsiEditor, cur: Position, _cur_abs: Position) -> egui::Response {
                self.cur_pos = cur;
                response.on_hover_cursor(egui::CursorIcon::Crosshair)
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                plot_point(
                    &mut editor.buffer_view.lock(),
                    editor.half_block_click_pos,
       @@ -139,11 +112,6 @@ impl Tool for PencilTool {
        
            fn get_toolbar_location_text(&self, _editor: &AnsiEditor) -> String {
                let pos = self.cur_pos;
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "toolbar-position",
       -            line = (pos.y + 1),
       -            column = (pos.x + 1)
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "toolbar-position", line = (pos.y + 1), column = (pos.x + 1))
            }
        }
   DIR diff --git a/src/model/tools/pipette_imp.rs b/src/model/tools/pipette_imp.rs
       @@ -33,90 +33,39 @@ impl Tool for PipetteTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                let Some(editor) = editor_opt else {
                    return None;
                };
        
                if let Some(ch) = unsafe { CUR_CHAR } {
                    ui.vertical_centered(|ui| {
       -                ui.label(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "pipette_tool_char_code",
       -                    code = (ch.ch as u32)
       -                ));
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "pipette_tool_char_code", code = (ch.ch as u32)));
        
                        if self.ch.is_none() || !self.ch.unwrap().eq(&ch.ch) {
                            self.ch = Some(ch.ch);
        
                            let mut buf = Buffer::new((1, 1));
                            buf.clear_font_table();
       -                    buf.set_font(
       -                        0,
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_buffer()
       -                            .get_font(ch.get_font_page())
       -                            .unwrap()
       -                            .clone(),
       -                    );
       -                    buf.layers[0]
       -                        .set_char((0, 0), AttributedChar::new(ch.ch, TextAttribute::default()));
       -                    self.char_image =
       -                        Some(create_retained_image(&buf).with_options(TextureOptions::NEAREST));
       +                    buf.set_font(0, editor.buffer_view.lock().get_buffer().get_font(ch.get_font_page()).unwrap().clone());
       +                    buf.layers[0].set_char((0, 0), AttributedChar::new(ch.ch, TextAttribute::default()));
       +                    self.char_image = Some(create_retained_image(&buf).with_options(TextureOptions::NEAREST));
                        }
        
                        if let Some(image) = &self.char_image {
                            image.show_scaled(ui, 2.0);
                        }
        
       -                ui.label(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "pipette_tool_foreground",
       -                    fg = ch.attribute.get_foreground()
       -                ));
       -                paint_color(
       -                    ui,
       -                    &editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer()
       -                        .palette
       -                        .get_color(ch.attribute.get_foreground()),
       -                );
       -                ui.label(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "pipette_tool_background",
       -                    bg = ch.attribute.get_background()
       -                ));
       -                paint_color(
       -                    ui,
       -                    &editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer()
       -                        .palette
       -                        .get_color(ch.attribute.get_background()),
       -                );
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "pipette_tool_foreground", fg = ch.attribute.get_foreground()));
       +                paint_color(ui, &editor.buffer_view.lock().get_buffer().palette.get_color(ch.attribute.get_foreground()));
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "pipette_tool_background", bg = ch.attribute.get_background()));
       +                paint_color(ui, &editor.buffer_view.lock().get_buffer().palette.get_color(ch.attribute.get_background()));
                    });
                }
                None
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        cur: Position,
       -        _cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, cur: Position, _cur_abs: Position) -> egui::Response {
                unsafe {
                    CUR_CHAR = Some(editor.get_char(cur));
                }
       @@ -127,12 +76,7 @@ impl Tool for PipetteTool {
        
            fn get_toolbar_location_text(&self, _editor: &AnsiEditor) -> String {
                if let Some(pos) = self.cur_pos {
       -            fl!(
       -                crate::LANGUAGE_LOADER,
       -                "toolbar-position",
       -                line = (pos.y + 1),
       -                column = (pos.x + 1)
       -            )
       +            fl!(crate::LANGUAGE_LOADER, "toolbar-position", line = (pos.y + 1), column = (pos.x + 1))
                } else {
                    String::new()
                }
       @@ -145,14 +89,7 @@ impl Tool for PipetteTool {
                self.cur_pos = None;
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        _pos_abs: Position,
       -        _response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, _pos_abs: Position, _response: &egui::Response) -> Option<Message> {
                if button == 1 {
                    let ch = editor.get_char(pos);
                    editor.set_caret_attribute(ch.attribute);
       @@ -181,11 +118,5 @@ fn paint_color(ui: &mut egui::Ui, color: &icy_engine::Color) {
        
            let text = format!("#{r:02x}{g:02x}{b:02x}");
            let font_id: eframe::epaint::FontId = FontId::monospace(16.0);
       -    painter.text(
       -        stroke_rect.center(),
       -        Align2::CENTER_CENTER,
       -        text,
       -        font_id,
       -        text_color,
       -    );
       +    painter.text(stroke_rect.center(), Align2::CENTER_CENTER, text, font_id, text_color);
        }
   DIR diff --git a/src/model/tools/select_imp.rs b/src/model/tools/select_imp.rs
       @@ -77,39 +77,14 @@ impl Tool for SelectTool {
                false
            }
        
       -    fn show_ui(
       -        &mut self,
       -        _ctx: &egui::Context,
       -        ui: &mut egui::Ui,
       -        _editor_opt: Option<&AnsiEditor>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui, _editor_opt: Option<&AnsiEditor>) -> Option<Message> {
                ui.label(fl!(crate::LANGUAGE_LOADER, "tool-select-label"));
       -        ui.radio_value(
       -            &mut self.mode,
       -            SelectionMode::Normal,
       -            fl!(crate::LANGUAGE_LOADER, "tool-select-normal"),
       -        );
       -        ui.radio_value(
       -            &mut self.mode,
       -            SelectionMode::Character,
       -            fl!(crate::LANGUAGE_LOADER, "tool-select-character"),
       -        );
       -        ui.radio_value(
       -            &mut self.mode,
       -            SelectionMode::Attribute,
       -            fl!(crate::LANGUAGE_LOADER, "tool-select-attribute"),
       -        );
       -        ui.radio_value(
       -            &mut self.mode,
       -            SelectionMode::Foreground,
       -            fl!(crate::LANGUAGE_LOADER, "tool-select-foreground"),
       -        );
       -
       -        ui.radio_value(
       -            &mut self.mode,
       -            SelectionMode::Background,
       -            fl!(crate::LANGUAGE_LOADER, "tool-select-background"),
       -        );
       +        ui.radio_value(&mut self.mode, SelectionMode::Normal, fl!(crate::LANGUAGE_LOADER, "tool-select-normal"));
       +        ui.radio_value(&mut self.mode, SelectionMode::Character, fl!(crate::LANGUAGE_LOADER, "tool-select-character"));
       +        ui.radio_value(&mut self.mode, SelectionMode::Attribute, fl!(crate::LANGUAGE_LOADER, "tool-select-attribute"));
       +        ui.radio_value(&mut self.mode, SelectionMode::Foreground, fl!(crate::LANGUAGE_LOADER, "tool-select-foreground"));
       +
       +        ui.radio_value(&mut self.mode, SelectionMode::Background, fl!(crate::LANGUAGE_LOADER, "tool-select-background"));
                ui.add_space(8.0);
                ui.vertical_centered(|ui| {
                    ui.small(fl!(crate::LANGUAGE_LOADER, "tool-select-description"));
       @@ -118,14 +93,7 @@ impl Tool for SelectTool {
                None
            }
        
       -    fn handle_click(
       -        &mut self,
       -        editor: &mut AnsiEditor,
       -        button: i32,
       -        pos: Position,
       -        cur_abs: Position,
       -        response: &egui::Response,
       -    ) -> Option<Message> {
       +    fn handle_click(&mut self, editor: &mut AnsiEditor, button: i32, pos: Position, cur_abs: Position, response: &egui::Response) -> Option<Message> {
                let cur_ch = editor.get_char_from_cur_layer(pos);
        
                let selection_mode = if response.ctx.input(|i| i.modifiers.shift_only()) {
       @@ -152,27 +120,17 @@ impl Tool for SelectTool {
                        .buffer_view
                        .lock()
                        .get_edit_state_mut()
       -                .enumerate_selections(|_, ch, _| {
       -                    selection_mode.get_response(ch.attribute == cur_ch.attribute)
       -                }),
       +                .enumerate_selections(|_, ch, _| selection_mode.get_response(ch.attribute == cur_ch.attribute)),
                    SelectionMode::Foreground => editor
                        .buffer_view
                        .lock()
                        .get_edit_state_mut()
       -                .enumerate_selections(|_, ch, _| {
       -                    selection_mode.get_response(
       -                        ch.attribute.get_foreground() == cur_ch.attribute.get_foreground(),
       -                    )
       -                }),
       +                .enumerate_selections(|_, ch, _| selection_mode.get_response(ch.attribute.get_foreground() == cur_ch.attribute.get_foreground())),
                    SelectionMode::Background => editor
                        .buffer_view
                        .lock()
                        .get_edit_state_mut()
       -                .enumerate_selections(|_, ch, _| {
       -                    selection_mode.get_response(
       -                        ch.attribute.get_background() == cur_ch.attribute.get_background(),
       -                    )
       -                }),
       +                .enumerate_selections(|_, ch, _| selection_mode.get_response(ch.attribute.get_background() == cur_ch.attribute.get_background())),
                }
                None
            }
       @@ -188,26 +146,13 @@ impl Tool for SelectTool {
                    if let Some(selection) = editor.buffer_view.lock().get_selection() {
                        self.start_selection = selection.as_rectangle();
                    }
       -        } else if !response
       -            .ctx
       -            .input(|i| i.modifiers.shift_only() || i.modifiers.command_only())
       -        {
       -            let _ = editor
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .clear_selection();
       +        } else if !response.ctx.input(|i| i.modifiers.shift_only() || i.modifiers.command_only()) {
       +            let _ = editor.buffer_view.lock().get_edit_state_mut().clear_selection();
                }
                Event::None
            }
        
       -    fn handle_drag(
       -        &mut self,
       -        _ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _calc: &TerminalCalc,
       -    ) -> egui::Response {
       +    fn handle_drag(&mut self, _ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _calc: &TerminalCalc) -> egui::Response {
                if self.mode != SelectionMode::Normal {
                    return response;
                }
       @@ -219,8 +164,7 @@ impl Tool for SelectTool {
        
                match self.selection_drag {
                    SelectionDrag::Move => {
       -                rect.start = self.start_selection.top_left() - editor.drag_pos.start_abs
       -                    + editor.drag_pos.cur_abs;
       +                rect.start = self.start_selection.top_left() - editor.drag_pos.start_abs + editor.drag_pos.cur_abs;
                        editor.buffer_view.lock().set_selection(rect);
                    }
                    SelectionDrag::Left => {
       @@ -287,14 +231,7 @@ impl Tool for SelectTool {
                response
            }
        
       -    fn handle_hover(
       -        &mut self,
       -        ui: &egui::Ui,
       -        response: egui::Response,
       -        editor: &mut AnsiEditor,
       -        _cur: Position,
       -        cur_abs: Position,
       -    ) -> egui::Response {
       +    fn handle_hover(&mut self, ui: &egui::Ui, response: egui::Response, editor: &mut AnsiEditor, _cur: Position, cur_abs: Position) -> egui::Response {
                if self.mode != SelectionMode::Normal {
                    return response.on_hover_cursor(egui::CursorIcon::Crosshair);
                }
       @@ -365,8 +302,7 @@ impl SelectTool {
            }
        
            fn move_right(&mut self, editor: &AnsiEditor, rect: &mut Rectangle) {
       -        rect.size.width = self.start_selection.get_width() - editor.drag_pos.start_abs.x
       -            + editor.drag_pos.cur_abs.x;
       +        rect.size.width = self.start_selection.get_width() - editor.drag_pos.start_abs.x + editor.drag_pos.cur_abs.x;
                if rect.size.width < 0 {
                    rect.start.x = self.start_selection.left() + rect.size.width;
                    rect.size.width = self.start_selection.left() - rect.start.x;
       @@ -385,8 +321,7 @@ impl SelectTool {
            }
        
            fn move_bottom(&mut self, editor: &AnsiEditor, rect: &mut Rectangle) {
       -        rect.size.height = self.start_selection.get_height() - editor.drag_pos.start_abs.y
       -            + editor.drag_pos.cur_abs.y;
       +        rect.size.height = self.start_selection.get_height() - editor.drag_pos.start_abs.y + editor.drag_pos.cur_abs.y;
                if rect.size.height < 0 {
                    rect.start.y = self.start_selection.top() + rect.size.height;
                    rect.size.height = self.start_selection.top() - rect.start.y;
   DIR diff --git a/src/paint/ellipse.rs b/src/paint/ellipse.rs
       @@ -38,8 +38,7 @@ fn get_ellipse_points(from: Position, to: Position) -> Vec<Position> {
                }
            }
        
       -    let mut d2 = ((ry * ry) * ((x/*+ 0.5f*/) * (x/*+ 0.5f*/))) + ((rx * rx) * ((y - 1) * (y - 1)))
       -        - (rx * rx * ry * ry);
       +    let mut d2 = ((ry * ry) * ((x/*+ 0.5f*/) * (x/*+ 0.5f*/))) + ((rx * rx) * ((y - 1) * (y - 1))) - (rx * rx * ry * ry);
        
            while y >= 0 {
                result.push(Position::new(-x + xc, y + yc));
       @@ -62,33 +61,15 @@ fn get_ellipse_points(from: Position, to: Position) -> Vec<Position> {
            result
        }
        
       -pub fn draw_ellipse(
       -    buffer_view: &mut BufferView,
       -    from: impl Into<Position>,
       -    to: impl Into<Position>,
       -    mode: BrushMode,
       -    color_mode: ColorMode,
       -) {
       +pub fn draw_ellipse(buffer_view: &mut BufferView, from: impl Into<Position>, to: impl Into<Position>, mode: BrushMode, color_mode: ColorMode) {
            let from = from.into();
            let to = to.into();
            for point in get_ellipse_points(from, to) {
       -        plot_point(
       -            buffer_view,
       -            point,
       -            mode.clone(),
       -            color_mode,
       -            PointRole::Line,
       -        );
       +        plot_point(buffer_view, point, mode.clone(), color_mode, PointRole::Line);
            }
        }
        
       -pub fn fill_ellipse(
       -    buffer_view: &mut BufferView,
       -    from: impl Into<Position>,
       -    to: impl Into<Position>,
       -    mode: BrushMode,
       -    color_mode: ColorMode,
       -) {
       +pub fn fill_ellipse(buffer_view: &mut BufferView, from: impl Into<Position>, to: impl Into<Position>, mode: BrushMode, color_mode: ColorMode) {
            let from = from.into();
            let to = to.into();
            let points = get_ellipse_points(from, to);
   DIR diff --git a/src/paint/half_block.rs b/src/paint/half_block.rs
       @@ -79,31 +79,17 @@ pub fn get_half_block(cur_char: AttributedChar, pos: Position, color: u32) -> At
            let half_block = HalfBlock::from(cur_char, pos);
        
            let ch = if half_block.is_blocky {
       -        if (half_block.is_top && half_block.lower_block_color == color)
       -            || (!half_block.is_top && half_block.upper_block_color == color)
       -        {
       +        if (half_block.is_top && half_block.lower_block_color == color) || (!half_block.is_top && half_block.upper_block_color == color) {
                    AttributedChar::new(FULL_BLOCK, TextAttribute::new(color, 0))
                } else if half_block.is_top {
       -            AttributedChar::new(
       -                HALF_BLOCK_TOP,
       -                TextAttribute::new(color, half_block.lower_block_color),
       -            )
       +            AttributedChar::new(HALF_BLOCK_TOP, TextAttribute::new(color, half_block.lower_block_color))
                } else {
       -            AttributedChar::new(
       -                HALF_BLOCK_BOTTOM,
       -                TextAttribute::new(color, half_block.upper_block_color),
       -            )
       +            AttributedChar::new(HALF_BLOCK_BOTTOM, TextAttribute::new(color, half_block.upper_block_color))
                }
            } else if half_block.is_top {
       -        AttributedChar::new(
       -            HALF_BLOCK_TOP,
       -            TextAttribute::new(color, half_block.block.attribute.get_background()),
       -        )
       +        AttributedChar::new(HALF_BLOCK_TOP, TextAttribute::new(color, half_block.block.attribute.get_background()))
            } else {
       -        AttributedChar::new(
       -            HALF_BLOCK_BOTTOM,
       -            TextAttribute::new(color, half_block.block.attribute.get_background()),
       -        )
       +        AttributedChar::new(HALF_BLOCK_BOTTOM, TextAttribute::new(color, half_block.block.attribute.get_background()))
            };
            optimize_block(ch, &half_block)
        }
   DIR diff --git a/src/paint/line.rs b/src/paint/line.rs
       @@ -32,22 +32,10 @@ fn get_line_points(from: Position, to: Position) -> Vec<Position> {
            result
        }
        
       -pub fn draw_line(
       -    buffer_view: &mut BufferView,
       -    from: impl Into<Position>,
       -    to: impl Into<Position>,
       -    mode: BrushMode,
       -    color_mode: ColorMode,
       -) {
       +pub fn draw_line(buffer_view: &mut BufferView, from: impl Into<Position>, to: impl Into<Position>, mode: BrushMode, color_mode: ColorMode) {
            let from = from.into();
            let to = to.into();
            for point in get_line_points(from, to) {
       -        plot_point(
       -            buffer_view,
       -            point,
       -            mode.clone(),
       -            color_mode,
       -            PointRole::Line,
       -        );
       +        plot_point(buffer_view, point, mode.clone(), color_mode, PointRole::Line);
            }
        }
   DIR diff --git a/src/paint/mod.rs b/src/paint/mod.rs
       @@ -34,56 +34,26 @@ impl BrushMode {
                show_outline: bool,
            ) -> Option<Message> {
                let mut msg = None;
       -        ui.radio_value(
       -            self,
       -            BrushMode::HalfBlock,
       -            fl!(crate::LANGUAGE_LOADER, "tool-half-block"),
       -        );
       -        ui.radio_value(
       -            self,
       -            BrushMode::Block,
       -            fl!(crate::LANGUAGE_LOADER, "tool-full-block"),
       -        );
       +        ui.radio_value(self, BrushMode::HalfBlock, fl!(crate::LANGUAGE_LOADER, "tool-half-block"));
       +        ui.radio_value(self, BrushMode::Block, fl!(crate::LANGUAGE_LOADER, "tool-full-block"));
        
                if show_outline {
                    ui.horizontal(|ui| {
       -                ui.radio_value(
       -                    self,
       -                    BrushMode::Outline,
       -                    fl!(crate::LANGUAGE_LOADER, "tool-outline"),
       -                );
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "font_tool_select_outline_button"
       -                    ))
       -                    .clicked()
       -                {
       +                ui.radio_value(self, BrushMode::Outline, fl!(crate::LANGUAGE_LOADER, "tool-outline"));
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "font_tool_select_outline_button")).clicked() {
                            msg = Some(Message::ShowOutlineDialog);
                        }
                    });
                }
        
                ui.horizontal(|ui| {
       -            ui.radio_value(
       -                self,
       -                BrushMode::Char(char_code.clone()),
       -                fl!(crate::LANGUAGE_LOADER, "tool-character"),
       -            );
       +            ui.radio_value(self, BrushMode::Char(char_code.clone()), fl!(crate::LANGUAGE_LOADER, "tool-character"));
                    if let Some(editor) = editor_opt {
                        draw_glyph(ui, editor, &char_code);
                    }
                });
       -        ui.radio_value(
       -            self,
       -            BrushMode::Shade,
       -            fl!(crate::LANGUAGE_LOADER, "tool-shade"),
       -        );
       -        ui.radio_value(
       -            self,
       -            BrushMode::Colorize,
       -            fl!(crate::LANGUAGE_LOADER, "tool-colorize"),
       -        );
       +        ui.radio_value(self, BrushMode::Shade, fl!(crate::LANGUAGE_LOADER, "tool-shade"));
       +        ui.radio_value(self, BrushMode::Colorize, fl!(crate::LANGUAGE_LOADER, "tool-colorize"));
        
                msg
            }
       @@ -114,19 +84,13 @@ impl ColorMode {
                    let mut use_back = self.use_back();
        
                    if ui
       -                .selectable_label(
       -                    use_fore,
       -                    RichText::new(fl!(crate::LANGUAGE_LOADER, "tool-fg")).size(20.0),
       -                )
       +                .selectable_label(use_fore, RichText::new(fl!(crate::LANGUAGE_LOADER, "tool-fg")).size(20.0))
                        .clicked()
                    {
                        use_fore = !use_fore;
                    }
                    if ui
       -                .selectable_label(
       -                    use_back,
       -                    RichText::new(fl!(crate::LANGUAGE_LOADER, "tool-bg")).size(20.0),
       -                )
       +                .selectable_label(use_back, RichText::new(fl!(crate::LANGUAGE_LOADER, "tool-bg")).size(20.0))
                        .clicked()
                    {
                        use_back = !use_back;
       @@ -145,13 +109,7 @@ impl ColorMode {
            }
        }
        
       -pub fn plot_point(
       -    buffer_view: &mut BufferView,
       -    pos: impl Into<Position>,
       -    mut mode: BrushMode,
       -    color_mode: ColorMode,
       -    point_role: PointRole,
       -) {
       +pub fn plot_point(buffer_view: &mut BufferView, pos: impl Into<Position>, mut mode: BrushMode, color_mode: ColorMode, point_role: PointRole) {
            let pos = pos.into();
            let text_pos = Position::new(pos.x, pos.y / 2);
            let mut ch = if let Some(layer) = buffer_view.get_edit_state().get_cur_layer() {
       @@ -188,10 +146,7 @@ pub fn plot_point(
            }
            match mode {
                BrushMode::HalfBlock => {
       -            layer.set_char(
       -                text_pos,
       -                get_half_block(ch, pos, attribute.get_foreground()),
       -            );
       +            layer.set_char(text_pos, get_half_block(ch, pos, attribute.get_foreground()));
                }
                BrushMode::Block => {
                    layer.set_char(text_pos, AttributedChar::new(219 as char, attribute));
       @@ -220,10 +175,7 @@ pub fn plot_point(
                    let outline_style = crate::Settings::get_font_outline_style();
                    layer.set_char(
                        text_pos,
       -                AttributedChar::new(
       -                    TheDrawFont::transform_outline(outline_style, ch as u8) as char,
       -                    attribute,
       -                ),
       +                AttributedChar::new(TheDrawFont::transform_outline(outline_style, ch as u8) as char, attribute),
                    );
                }
        
   DIR diff --git a/src/paint/rectangle.rs b/src/paint/rectangle.rs
       @@ -3,99 +3,33 @@ use icy_engine_egui::BufferView;
        
        use super::{plot_point, BrushMode, ColorMode, PointRole};
        
       -pub fn draw_rectangle(
       -    buffer_view: &mut BufferView,
       -    from: impl Into<Position>,
       -    to: impl Into<Position>,
       -    mode: BrushMode,
       -    color_mode: ColorMode,
       -) {
       +pub fn draw_rectangle(buffer_view: &mut BufferView, from: impl Into<Position>, to: impl Into<Position>, mode: BrushMode, color_mode: ColorMode) {
            let from = from.into();
            let to = to.into();
       -    plot_point(
       -        buffer_view,
       -        from,
       -        mode.clone(),
       -        color_mode,
       -        PointRole::NWCorner,
       -    );
       -    plot_point(
       -        buffer_view,
       -        (to.x, from.y),
       -        mode.clone(),
       -        color_mode,
       -        PointRole::NECorner,
       -    );
       +    plot_point(buffer_view, from, mode.clone(), color_mode, PointRole::NWCorner);
       +    plot_point(buffer_view, (to.x, from.y), mode.clone(), color_mode, PointRole::NECorner);
        
       -    plot_point(
       -        buffer_view,
       -        (from.x, to.y),
       -        mode.clone(),
       -        color_mode,
       -        PointRole::SWCorner,
       -    );
       -    plot_point(
       -        buffer_view,
       -        (to.x, to.y),
       -        mode.clone(),
       -        color_mode,
       -        PointRole::SECorner,
       -    );
       +    plot_point(buffer_view, (from.x, to.y), mode.clone(), color_mode, PointRole::SWCorner);
       +    plot_point(buffer_view, (to.x, to.y), mode.clone(), color_mode, PointRole::SECorner);
        
            for x in from.x + 1..to.x {
       -        plot_point(
       -            buffer_view,
       -            (x, from.y),
       -            mode.clone(),
       -            color_mode,
       -            PointRole::TopSide,
       -        );
       -        plot_point(
       -            buffer_view,
       -            (x, to.y),
       -            mode.clone(),
       -            color_mode,
       -            PointRole::BottomSide,
       -        );
       +        plot_point(buffer_view, (x, from.y), mode.clone(), color_mode, PointRole::TopSide);
       +        plot_point(buffer_view, (x, to.y), mode.clone(), color_mode, PointRole::BottomSide);
            }
        
            for y in from.y + 1..to.y {
       -        plot_point(
       -            buffer_view,
       -            (from.x, y),
       -            mode.clone(),
       -            color_mode,
       -            PointRole::LeftSide,
       -        );
       -        plot_point(
       -            buffer_view,
       -            (to.x, y),
       -            mode.clone(),
       -            color_mode,
       -            PointRole::RightSide,
       -        );
       +        plot_point(buffer_view, (from.x, y), mode.clone(), color_mode, PointRole::LeftSide);
       +        plot_point(buffer_view, (to.x, y), mode.clone(), color_mode, PointRole::RightSide);
            }
        }
        
       -pub fn fill_rectangle(
       -    buffer_view: &mut BufferView,
       -    from: impl Into<Position>,
       -    to: impl Into<Position>,
       -    mode: BrushMode,
       -    color_mode: ColorMode,
       -) {
       +pub fn fill_rectangle(buffer_view: &mut BufferView, from: impl Into<Position>, to: impl Into<Position>, mode: BrushMode, color_mode: ColorMode) {
            let from = from.into();
            let to = to.into();
        
            for y in from.y + 1..to.y {
                for x in from.x + 1..to.x {
       -            plot_point(
       -                buffer_view,
       -                (x, y),
       -                mode.clone(),
       -                color_mode,
       -                PointRole::Fill,
       -            );
       +            plot_point(buffer_view, (x, y), mode.clone(), color_mode, PointRole::Fill);
                }
            }
            draw_rectangle(buffer_view, from, to, mode, color_mode);
   DIR diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs
       @@ -26,11 +26,7 @@ impl Plugin {
                Err(anyhow::anyhow!("No plugin file"))
            }
        
       -    pub(crate) fn run_plugin(
       -        &self,
       -        _window: &mut crate::MainWindow,
       -        editor: &crate::AnsiEditor,
       -    ) -> anyhow::Result<()> {
       +    pub(crate) fn run_plugin(&self, _window: &mut crate::MainWindow, editor: &crate::AnsiEditor) -> anyhow::Result<()> {
                let lua = Lua::new();
                let globals = lua.globals();
        
       @@ -77,11 +73,7 @@ impl Plugin {
                    .buffer_view
                    .lock()
                    .get_edit_state_mut()
       -            .begin_atomic_undo(fl!(
       -                crate::LANGUAGE_LOADER,
       -                "undo-plugin",
       -                title = self.title.clone()
       -            ));
       +            .begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-plugin", title = self.title.clone()));
                lua.load(&self.text).exec()?;
                Ok(())
            }
       @@ -125,14 +117,16 @@ impl LuaBufferView {
                let buffer_type = self.buffer_view.lock().get_buffer().buffer_type;
                let ch = match buffer_type {
                    icy_engine::BufferType::Unicode => ch,
       -            icy_engine::BufferType::CP437 => icy_engine::ascii::Parser::default()
       -                .convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page()),
       -            icy_engine::BufferType::Petscii => icy_engine::petscii::Parser::default()
       -                .convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page()),
       -            icy_engine::BufferType::Atascii => icy_engine::atascii::Parser::default()
       -                .convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page()),
       -            icy_engine::BufferType::Viewdata => icy_engine::viewdata::Parser::default()
       -                .convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page()),
       +            icy_engine::BufferType::CP437 => icy_engine::ascii::Parser::default().convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page()),
       +            icy_engine::BufferType::Petscii => {
       +                icy_engine::petscii::Parser::default().convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page())
       +            }
       +            icy_engine::BufferType::Atascii => {
       +                icy_engine::atascii::Parser::default().convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page())
       +            }
       +            icy_engine::BufferType::Viewdata => {
       +                icy_engine::viewdata::Parser::default().convert_from_unicode(ch, self.buffer_view.lock().get_caret().get_font_page())
       +            }
                };
                Ok(ch)
            }
       @@ -141,18 +135,10 @@ impl LuaBufferView {
                let buffer_type = self.buffer_view.lock().get_buffer().buffer_type;
                let ch = match buffer_type {
                    icy_engine::BufferType::Unicode => ch.ch,
       -            icy_engine::BufferType::CP437 => {
       -                icy_engine::ascii::Parser::default().convert_to_unicode(ch)
       -            }
       -            icy_engine::BufferType::Petscii => {
       -                icy_engine::petscii::Parser::default().convert_to_unicode(ch)
       -            }
       -            icy_engine::BufferType::Atascii => {
       -                icy_engine::atascii::Parser::default().convert_to_unicode(ch)
       -            }
       -            icy_engine::BufferType::Viewdata => {
       -                icy_engine::viewdata::Parser::default().convert_to_unicode(ch)
       -            }
       +            icy_engine::BufferType::CP437 => icy_engine::ascii::Parser::default().convert_to_unicode(ch),
       +            icy_engine::BufferType::Petscii => icy_engine::petscii::Parser::default().convert_to_unicode(ch),
       +            icy_engine::BufferType::Atascii => icy_engine::atascii::Parser::default().convert_to_unicode(ch),
       +            icy_engine::BufferType::Viewdata => icy_engine::viewdata::Parser::default().convert_to_unicode(ch),
                };
                ch.to_string()
            }
       @@ -160,63 +146,37 @@ impl LuaBufferView {
        
        impl UserData for LuaBufferView {
            fn add_fields<'lua, F: mlua::UserDataFields<'lua, Self>>(fields: &mut F) {
       -        fields.add_field_method_get("height", |_, this| {
       -            Ok(this.buffer_view.lock().get_buffer_mut().get_height())
       -        });
       +        fields.add_field_method_get("height", |_, this| Ok(this.buffer_view.lock().get_buffer_mut().get_height()));
                fields.add_field_method_set("height", |_, this, val| {
                    this.buffer_view.lock().get_buffer_mut().set_height(val);
                    Ok(())
                });
       -        fields.add_field_method_get("width", |_, this| {
       -            Ok(this.buffer_view.lock().get_buffer_mut().get_width())
       -        });
       +        fields.add_field_method_get("width", |_, this| Ok(this.buffer_view.lock().get_buffer_mut().get_width()));
                fields.add_field_method_set("width", |_, this, val| {
                    this.buffer_view.lock().get_buffer_mut().set_width(val);
                    Ok(())
                });
        
       -        fields.add_field_method_get("font_page", |_, this| {
       -            Ok(this.buffer_view.lock().get_caret_mut().get_font_page())
       -        });
       +        fields.add_field_method_get("font_page", |_, this| Ok(this.buffer_view.lock().get_caret_mut().get_font_page()));
                fields.add_field_method_set("font_page", |_, this, val| {
                    this.buffer_view.lock().get_caret_mut().set_font_page(val);
                    Ok(())
                });
        
       -        fields.add_field_method_get("layer", |_, this| {
       -            Ok(this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer())
       -        });
       +        fields.add_field_method_get("layer", |_, this| Ok(this.buffer_view.lock().get_edit_state_mut().get_current_layer()));
                fields.add_field_method_set("layer", |_, this, val| {
                    if val < this.buffer_view.lock().get_buffer_mut().layers.len() {
       -                this.buffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .set_current_layer(val);
       +                this.buffer_view.lock().get_edit_state_mut().set_current_layer(val);
                        Ok(())
                    } else {
                        Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Layer {} out of range (0..<{})",
       -                        val,
       -                        this.buffer_view.lock().get_buffer_mut().layers.len()
       -                    ),
       +                    message: format!("Layer {} out of range (0..<{})", val, this.buffer_view.lock().get_buffer_mut().layers.len()),
                            incomplete_input: false,
                        })
                    }
                });
        
       -        fields.add_field_method_get("fg", |_, this| {
       -            Ok(this
       -                .buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .get_attribute()
       -                .get_foreground())
       -        });
       +        fields.add_field_method_get("fg", |_, this| Ok(this.buffer_view.lock().get_caret_mut().get_attribute().get_foreground()));
                fields.add_field_method_set("fg", |_, this, val| {
                    let mut attr = this.buffer_view.lock().get_caret_mut().get_attribute();
                    attr.set_foreground(val);
       @@ -224,14 +184,7 @@ impl UserData for LuaBufferView {
                    Ok(())
                });
        
       -        fields.add_field_method_get("bg", |_, this| {
       -            Ok(this
       -                .buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .get_attribute()
       -                .get_background())
       -        });
       +        fields.add_field_method_get("bg", |_, this| Ok(this.buffer_view.lock().get_caret_mut().get_attribute().get_background()));
                fields.add_field_method_set("bg", |_, this, val| {
                    let mut attr = this.buffer_view.lock().get_caret_mut().get_attribute();
                    attr.set_background(val);
       @@ -239,96 +192,56 @@ impl UserData for LuaBufferView {
                    Ok(())
                });
        
       -        fields.add_field_method_get("x", |_, this| {
       -            Ok(this.buffer_view.lock().get_caret_mut().get_position().x)
       -        });
       +        fields.add_field_method_get("x", |_, this| Ok(this.buffer_view.lock().get_caret_mut().get_position().x));
                fields.add_field_method_set("x", |_, this, val| {
                    this.buffer_view.lock().get_caret_mut().set_x_position(val);
                    Ok(())
                });
        
       -        fields.add_field_method_get("y", |_, this| {
       -            Ok(this.buffer_view.lock().get_caret_mut().get_position().y)
       -        });
       +        fields.add_field_method_get("y", |_, this| Ok(this.buffer_view.lock().get_caret_mut().get_position().y));
                fields.add_field_method_set("y", |_, this, val| {
                    this.buffer_view.lock().get_caret_mut().set_y_position(val);
                    Ok(())
                });
        
       -        fields.add_field_method_get("layer_count", |_, this| {
       -            Ok(this.buffer_view.lock().get_buffer_mut().layers.len())
       -        });
       +        fields.add_field_method_get("layer_count", |_, this| Ok(this.buffer_view.lock().get_buffer_mut().layers.len()));
            }
        
            fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) {
                methods.add_method_mut("fg_rgb", |_, this, (r, g, b): (u8, u8, u8)| {
       -            let color = this
       -                .buffer_view
       -                .lock()
       -                .get_buffer_mut()
       -                .palette
       -                .insert_color_rgb(r, g, b);
       -            this.buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_foreground(color);
       +            let color = this.buffer_view.lock().get_buffer_mut().palette.insert_color_rgb(r, g, b);
       +            this.buffer_view.lock().get_caret_mut().set_foreground(color);
                    Ok(color)
                });
        
                methods.add_method_mut("bg_rgb", |_, this, (r, g, b): (u8, u8, u8)| {
       -            let color = this
       -                .buffer_view
       -                .lock()
       -                .get_buffer_mut()
       -                .palette
       -                .insert_color_rgb(r, g, b);
       -            this.buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_background(color);
       +            let color = this.buffer_view.lock().get_buffer_mut().palette.insert_color_rgb(r, g, b);
       +            this.buffer_view.lock().get_caret_mut().set_background(color);
                    Ok(color)
                });
        
                methods.add_method_mut("set_char", |_, this, (x, y, ch): (i32, i32, String)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
                    let attr = this.buffer_view.lock().get_caret_mut().get_attribute();
                    let ch = AttributedChar::new(this.convert_from_unicode(ch)?, attr);
        
       -            this.buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .set_char((x, y), ch)
       -                .unwrap();
       +            this.buffer_view.lock().get_edit_state_mut().set_char((x, y), ch).unwrap();
                    Ok(())
                });
        
                methods.add_method_mut("get_char", |_, this, (x, y): (i32, i32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
       @@ -338,67 +251,42 @@ impl UserData for LuaBufferView {
                });
        
                methods.add_method_mut("pickup_char", |_, this, (x, y): (i32, i32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
        
                    let ch = this.buffer_view.lock().get_buffer_mut().layers[cur_layer].get_char((x, y));
       -            this.buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_attr(ch.attribute);
       +            this.buffer_view.lock().get_caret_mut().set_attr(ch.attribute);
        
                    Ok(this.convert_to_unicode(ch))
                });
        
                methods.add_method_mut("set_fg", |_, this, (x, y, col): (i32, i32, u32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
       -            let mut ch =
       -                this.buffer_view.lock().get_buffer_mut().layers[cur_layer].get_char((x, y));
       +            let mut ch = this.buffer_view.lock().get_buffer_mut().layers[cur_layer].get_char((x, y));
                    ch.attribute.set_foreground(col);
                    this.buffer_view.lock().get_buffer_mut().layers[cur_layer].set_char((x, y), ch);
                    Ok(())
                });
        
                methods.add_method_mut("get_fg", |_, this, (x, y): (i32, i32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
       @@ -408,41 +296,26 @@ impl UserData for LuaBufferView {
                });
        
                methods.add_method_mut("set_bg", |_, this, (x, y, col): (i32, i32, u32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
       -            let mut ch =
       -                this.buffer_view.lock().get_buffer_mut().layers[cur_layer].get_char((x, y));
       +            let mut ch = this.buffer_view.lock().get_buffer_mut().layers[cur_layer].get_char((x, y));
                    ch.attribute.set_background(col);
                    this.buffer_view.lock().get_buffer_mut().layers[cur_layer].set_char((x, y), ch);
                    Ok(())
                });
        
                methods.add_method_mut("get_bg", |_, this, (x, y): (i32, i32)| {
       -            let cur_layer = this
       -                .buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .get_current_layer();
       +            let cur_layer = this.buffer_view.lock().get_edit_state_mut().get_current_layer();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Current layer {} out of range (0..<{})",
       -                        cur_layer, layer_len
       -                    ),
       +                    message: format!("Current layer {} out of range (0..<{})", cur_layer, layer_len),
                            incomplete_input: false,
                        });
                    }
       @@ -455,11 +328,7 @@ impl UserData for LuaBufferView {
                        let mut pos = this.buffer_view.lock().get_caret_mut().get_position();
                        let attribute = this.buffer_view.lock().get_caret_mut().get_attribute();
                        let ch = AttributedChar::new(this.convert_from_unicode(c.to_string())?, attribute);
       -                let _ = this
       -                    .buffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .set_char(pos, ch);
       +                let _ = this.buffer_view.lock().get_edit_state_mut().set_char(pos, ch);
                        pos.x += 1;
                        this.buffer_view.lock().get_caret_mut().set_position(pos);
                    }
       @@ -467,82 +336,53 @@ impl UserData for LuaBufferView {
                });
        
                methods.add_method_mut("gotoxy", |_, this, (x, y): (i32, i32)| {
       -            this.buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_position(Position::new(x, y));
       +            this.buffer_view.lock().get_caret_mut().set_position(Position::new(x, y));
                    Ok(())
                });
        
       -        methods.add_method_mut(
       -            "set_layer_position",
       -            |_, this, (layer, x, y): (usize, i32, i32)| {
       -                if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
       -                    let _ = this
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state_mut()
       -                        .move_layer(Position::new(x, y));
       -                    Ok(())
       -                } else {
       -                    Err(mlua::Error::SyntaxError {
       -                        message: format!(
       -                            "Layer {} out of range (0..<{})",
       -                            layer,
       -                            this.buffer_view.lock().get_buffer_mut().layers.len()
       -                        ),
       -                        incomplete_input: false,
       -                    })
       -                }
       -            },
       -        );
       +        methods.add_method_mut("set_layer_position", |_, this, (layer, x, y): (usize, i32, i32)| {
       +            if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
       +                let _ = this.buffer_view.lock().get_edit_state_mut().move_layer(Position::new(x, y));
       +                Ok(())
       +            } else {
       +                Err(mlua::Error::SyntaxError {
       +                    message: format!("Layer {} out of range (0..<{})", layer, this.buffer_view.lock().get_buffer_mut().layers.len()),
       +                    incomplete_input: false,
       +                })
       +            }
       +        });
                methods.add_method_mut("get_layer_position", |_, this, layer: usize| {
                    if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
                        let pos = this.buffer_view.lock().get_buffer_mut().layers[layer].get_offset();
                        Ok((pos.x, pos.y))
                    } else {
                        Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Layer {} out of range (0..<{})",
       -                        layer,
       -                        this.buffer_view.lock().get_buffer_mut().layers.len()
       -                    ),
       +                    message: format!("Layer {} out of range (0..<{})", layer, this.buffer_view.lock().get_buffer_mut().layers.len()),
                            incomplete_input: false,
                        })
                    }
                });
        
       -        methods.add_method_mut(
       -            "set_layer_visible",
       -            |_, this, (layer, is_visible): (i32, bool)| {
       -                let layer = layer as usize;
       -                if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
       -                    // todo
       -                    this.buffer_view.lock().get_buffer_mut().layers[layer].is_visible = is_visible;
       -                    Ok(())
       -                } else {
       -                    Err(mlua::Error::SyntaxError {
       -                        message: format!(
       -                            "Layer {} out of range (0..<{})",
       -                            layer,
       -                            this.buffer_view.lock().get_buffer_mut().layers.len()
       -                        ),
       -                        incomplete_input: false,
       -                    })
       -                }
       -            },
       -        );
       +        methods.add_method_mut("set_layer_visible", |_, this, (layer, is_visible): (i32, bool)| {
       +            let layer = layer as usize;
       +            if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
       +                // todo
       +                this.buffer_view.lock().get_buffer_mut().layers[layer].is_visible = is_visible;
       +                Ok(())
       +            } else {
       +                Err(mlua::Error::SyntaxError {
       +                    message: format!("Layer {} out of range (0..<{})", layer, this.buffer_view.lock().get_buffer_mut().layers.len()),
       +                    incomplete_input: false,
       +                })
       +            }
       +        });
        
                methods.add_method_mut("get_layer_visible", |_, this, layer: usize| {
                    if layer < this.buffer_view.lock().get_buffer_mut().layers.len() {
                        Ok(this.buffer_view.lock().get_buffer_mut().layers[layer].is_visible)
                    } else {
                        Err(mlua::Error::SyntaxError {
       -                    message: format!(
       -                        "Layer {} out of range (0..<{})",
       -                        layer,
       -                        this.buffer_view.lock().get_buffer_mut().layers.len()
       -                    ),
       +                    message: format!("Layer {} out of range (0..<{})", layer, this.buffer_view.lock().get_buffer_mut().layers.len()),
                            incomplete_input: false,
                        })
                    }
   DIR diff --git a/src/ui/commands.rs b/src/ui/commands.rs
       @@ -42,10 +42,7 @@ impl CommandState for CanSwitchPaletteState {
                if let Some(pane) = open_tab_opt {
                    if let Ok(doc) = pane.doc.lock() {
                        if let Some(editor) = doc.get_ansi_editor() {
       -                    return !matches!(
       -                        editor.buffer_view.lock().get_buffer().palette_mode,
       -                        PaletteMode::Fixed16
       -                    );
       +                    return !matches!(editor.buffer_view.lock().get_buffer().palette_mode, PaletteMode::Fixed16);
                        }
                    }
                }
       @@ -419,12 +416,7 @@ fn hash(str: impl Into<String>) -> u32 {
        }
        
        impl CommandWrapper {
       -    pub fn new(
       -        key: Option<(egui::Key, Modifiers)>,
       -        message: Message,
       -        description: String,
       -        state_key: u32,
       -    ) -> Self {
       +    pub fn new(key: Option<(egui::Key, Modifiers)>, message: Message, description: String, state_key: u32) -> Self {
                let key = key.map(|(k, m)| (KeyOrPointer::Key(k), m));
                Self {
                    key,
       @@ -448,10 +440,7 @@ impl CommandWrapper {
        
            pub fn ui(&self, ui: &mut egui::Ui, message: &mut Option<Message>) {
                if let Some(mut checked) = self.is_checked {
       -            if ui
       -                .add(egui::Checkbox::new(&mut checked, &self.label))
       -                .clicked()
       -            {
       +            if ui.add(egui::Checkbox::new(&mut checked, &self.label)).clicked() {
                        *message = Some(self.message.clone());
                        ui.close_menu();
                    }
       @@ -489,184 +478,40 @@ impl CommandWrapper {
        }
        
        keys![
       -    (
       -        new_file,
       -        "menu-new",
       -        NewFileDialog,
       -        AlwaysEnabledState,
       -        N,
       -        CTRL
       -    ),
       +    (new_file, "menu-new", NewFileDialog, AlwaysEnabledState, N, CTRL),
            (save, "menu-save", SaveFile, FileIsDirtyState, S, CTRL),
       -    (
       -        save_as,
       -        "menu-save-as",
       -        SaveFileAs,
       -        FileOpenState,
       -        S,
       -        CTRL_SHIFT
       -    ),
       -    (
       -        open_file,
       -        "menu-open",
       -        OpenFileDialog,
       -        AlwaysEnabledState,
       -        O,
       -        CTRL
       -    ),
       +    (save_as, "menu-save-as", SaveFileAs, FileOpenState, S, CTRL_SHIFT),
       +    (open_file, "menu-open", OpenFileDialog, AlwaysEnabledState, O, CTRL),
            (export, "menu-export", ExportFile, BufferOpenState),
       -    (
       -        edit_font_outline,
       -        "menu-edit-font-outline",
       -        ShowOutlineDialog,
       -        AlwaysEnabledState
       -    ),
       -    (
       -        close_window,
       -        "menu-close",
       -        CloseWindow,
       -        AlwaysEnabledState,
       -        Q,
       -        CTRL
       -    ),
       +    (edit_font_outline, "menu-edit-font-outline", ShowOutlineDialog, AlwaysEnabledState),
       +    (close_window, "menu-close", CloseWindow, AlwaysEnabledState, Q, CTRL),
            (undo, "menu-undo", Undo, CanUndoState, Z, CTRL),
            (redo, "menu-redo", Redo, CanRedoState, Z, CTRL_SHIFT),
            (cut, "menu-cut", Cut, CanCutState, X, CTRL),
            (copy, "menu-copy", Copy, CanCopyState, C, CTRL),
            (paste, "menu-paste", Paste, CanPasteState, V, CTRL),
       -    (
       -        show_settings,
       -        "menu-show_settings",
       -        ShowSettings,
       -        AlwaysEnabledState
       -    ),
       -    (
       -        select_all,
       -        "menu-select-all",
       -        SelectAll,
       -        BufferOpenState,
       -        A,
       -        CTRL
       -    ),
       -    (
       -        deselect,
       -        "menu-select_nothing",
       -        SelectNothing,
       -        BufferOpenState
       -    ),
       -    (
       -        erase_selection,
       -        "menu-erase",
       -        DeleteSelection,
       -        BufferOpenState,
       -        Delete,
       -        NONE
       -    ),
       +    (show_settings, "menu-show_settings", ShowSettings, AlwaysEnabledState),
       +    (select_all, "menu-select-all", SelectAll, BufferOpenState, A, CTRL),
       +    (deselect, "menu-select_nothing", SelectNothing, BufferOpenState),
       +    (erase_selection, "menu-erase", DeleteSelection, BufferOpenState, Delete, NONE),
            (flip_x, "menu-flipx", FlipX, BufferOpenState),
            (flip_y, "menu-flipy", FlipY, BufferOpenState),
            (justifycenter, "menu-justifycenter", Center, BufferOpenState),
       -    (
       -        justifyleft,
       -        "menu-justifyleft",
       -        JustifyLeft,
       -        BufferOpenState
       -    ),
       -    (
       -        justifyright,
       -        "menu-justifyright",
       -        JustifyRight,
       -        BufferOpenState
       -    ),
       +    (justifyleft, "menu-justifyleft", JustifyLeft, BufferOpenState),
       +    (justifyright, "menu-justifyright", JustifyRight, BufferOpenState),
            (crop, "menu-crop", Crop, BufferOpenState),
            (about, "menu-about", ShowAboutDialog, AlwaysEnabledState),
       -    (
       -        justify_line_center,
       -        "menu-justify_line_center",
       -        CenterLine,
       -        BufferOpenState,
       -        C,
       -        ALT
       -    ),
       -    (
       -        justify_line_left,
       -        "menu-justify_line_left",
       -        JustifyLineLeft,
       -        BufferOpenState,
       -        L,
       -        ALT
       -    ),
       -    (
       -        justify_line_right,
       -        "menu-justify_line_right",
       -        JustifyLineRight,
       -        BufferOpenState,
       -        R,
       -        ALT
       -    ),
       -    (
       -        insert_row,
       -        "menu-insert_row",
       -        InsertRow,
       -        BufferOpenState,
       -        ArrowUp,
       -        ALT
       -    ),
       -    (
       -        delete_row,
       -        "menu-delete_row",
       -        DeleteRow,
       -        BufferOpenState,
       -        ArrowDown,
       -        ALT
       -    ),
       -    (
       -        insert_column,
       -        "menu-insert_colum",
       -        InsertColumn,
       -        BufferOpenState,
       -        ArrowRight,
       -        ALT
       -    ),
       -    (
       -        delete_column,
       -        "menu-delete_colum",
       -        DeleteColumn,
       -        BufferOpenState,
       -        ArrowLeft,
       -        ALT
       -    ),
       -    (
       -        erase_row,
       -        "menu-erase_row",
       -        EraseRow,
       -        BufferOpenState,
       -        E,
       -        ALT
       -    ),
       -    (
       -        erase_row_to_start,
       -        "menu-erase_row_to_start",
       -        EraseRowToStart,
       -        BufferOpenState,
       -        Home,
       -        ALT
       -    ),
       -    (
       -        erase_row_to_end,
       -        "menu-erase_row_to_end",
       -        EraseRowToEnd,
       -        BufferOpenState,
       -        End,
       -        ALT
       -    ),
       -    (
       -        erase_column,
       -        "menu-erase_column",
       -        EraseColumn,
       -        BufferOpenState,
       -        E,
       -        ALT
       -    ),
       +    (justify_line_center, "menu-justify_line_center", CenterLine, BufferOpenState, C, ALT),
       +    (justify_line_left, "menu-justify_line_left", JustifyLineLeft, BufferOpenState, L, ALT),
       +    (justify_line_right, "menu-justify_line_right", JustifyLineRight, BufferOpenState, R, ALT),
       +    (insert_row, "menu-insert_row", InsertRow, BufferOpenState, ArrowUp, ALT),
       +    (delete_row, "menu-delete_row", DeleteRow, BufferOpenState, ArrowDown, ALT),
       +    (insert_column, "menu-insert_colum", InsertColumn, BufferOpenState, ArrowRight, ALT),
       +    (delete_column, "menu-delete_colum", DeleteColumn, BufferOpenState, ArrowLeft, ALT),
       +    (erase_row, "menu-erase_row", EraseRow, BufferOpenState, E, ALT),
       +    (erase_row_to_start, "menu-erase_row_to_start", EraseRowToStart, BufferOpenState, Home, ALT),
       +    (erase_row_to_end, "menu-erase_row_to_end", EraseRowToEnd, BufferOpenState, End, ALT),
       +    (erase_column, "menu-erase_column", EraseColumn, BufferOpenState, E, ALT),
            (
                erase_column_to_start,
                "menu-erase_column_to_start",
       @@ -675,38 +520,10 @@ keys![
                Home,
                ALT
            ),
       -    (
       -        erase_column_to_end,
       -        "menu-erase_column_to_end",
       -        EraseColumnToEnd,
       -        BufferOpenState,
       -        End,
       -        ALT
       -    ),
       -    (
       -        scroll_area_up,
       -        "menu-scroll_area_up",
       -        ScrollAreaUp,
       -        BufferOpenState,
       -        ArrowUp,
       -        ALT_CTRL
       -    ),
       -    (
       -        scroll_area_down,
       -        "menu-scroll_area_down",
       -        ScrollAreaDown,
       -        BufferOpenState,
       -        ArrowDown,
       -        ALT_CTRL
       -    ),
       -    (
       -        scroll_area_left,
       -        "menu-scroll_area_left",
       -        ScrollAreaLeft,
       -        BufferOpenState,
       -        ArrowLeft,
       -        ALT_CTRL
       -    ),
       +    (erase_column_to_end, "menu-erase_column_to_end", EraseColumnToEnd, BufferOpenState, End, ALT),
       +    (scroll_area_up, "menu-scroll_area_up", ScrollAreaUp, BufferOpenState, ArrowUp, ALT_CTRL),
       +    (scroll_area_down, "menu-scroll_area_down", ScrollAreaDown, BufferOpenState, ArrowDown, ALT_CTRL),
       +    (scroll_area_left, "menu-scroll_area_left", ScrollAreaLeft, BufferOpenState, ArrowLeft, ALT_CTRL),
            (
                scroll_area_right,
                "menu-scroll_area_right",
       @@ -715,14 +532,7 @@ keys![
                ArrowRight,
                ALT_CTRL
            ),
       -    (
       -        set_reference_image,
       -        "menu-reference-image",
       -        SetReferenceImage,
       -        BufferOpenState,
       -        O,
       -        CTRL_SHIFT
       -    ),
       +    (set_reference_image, "menu-reference-image", SetReferenceImage, BufferOpenState, O, CTRL_SHIFT),
            (
                toggle_reference_image,
                "menu-toggle-reference-image",
       @@ -731,12 +541,7 @@ keys![
                Tab,
                CTRL
            ),
       -    (
       -        clear_reference_image,
       -        "menu-clear-reference-image",
       -        ClearReferenceImage,
       -        BufferOpenState
       -    ),
       +    (clear_reference_image, "menu-clear-reference-image", ClearReferenceImage, BufferOpenState),
            (
                pick_attribute_under_caret,
                "menu-pick_attribute_under_caret",
       @@ -745,172 +550,35 @@ keys![
                U,
                ALT
            ),
       -    (
       -        switch_to_default_color,
       -        "menu-default_color",
       -        SwitchToDefaultColor,
       -        BufferOpenState,
       -        D,
       -        CTRL
       -    ),
       -    (
       -        toggle_color,
       -        "menu-toggle_color",
       -        ToggleColor,
       -        BufferOpenState,
       -        X,
       -        ALT
       -    ),
       -    (
       -        fullscreen,
       -        "menu-toggle_fullscreen",
       -        ToggleFullScreen,
       -        AlwaysEnabledState,
       -        F11,
       -        NONE
       -    ),
       -    (
       -        zoom_reset,
       -        "menu-zoom_reset",
       -        ZoomReset,
       -        BufferOpenState,
       -        Num0,
       -        CTRL
       -    ),
       -    (
       -        zoom_in,
       -        "menu-zoom_in",
       -        ZoomIn,
       -        BufferOpenState,
       -        PlusEquals,
       -        CTRL
       -    ),
       -    (
       -        zoom_out,
       -        "menu-zoom_out",
       -        ZoomOut,
       -        BufferOpenState,
       -        Minus,
       -        CTRL
       -    ),
       -    (
       -        open_tdf_directory,
       -        "menu-open_tdf_directoy",
       -        OpenTdfDirectory,
       -        AlwaysEnabledState
       -    ),
       -    (
       -        open_font_selector,
       -        "menu-open_font_selector",
       -        OpenFontSelector,
       -        BufferOpenState
       -    ),
       +    (switch_to_default_color, "menu-default_color", SwitchToDefaultColor, BufferOpenState, D, CTRL),
       +    (toggle_color, "menu-toggle_color", ToggleColor, BufferOpenState, X, ALT),
       +    (fullscreen, "menu-toggle_fullscreen", ToggleFullScreen, AlwaysEnabledState, F11, NONE),
       +    (zoom_reset, "menu-zoom_reset", ZoomReset, BufferOpenState, Num0, CTRL),
       +    (zoom_in, "menu-zoom_in", ZoomIn, BufferOpenState, PlusEquals, CTRL),
       +    (zoom_out, "menu-zoom_out", ZoomOut, BufferOpenState, Minus, CTRL),
       +    (open_tdf_directory, "menu-open_tdf_directoy", OpenTdfDirectory, AlwaysEnabledState),
       +    (open_font_selector, "menu-open_font_selector", OpenFontSelector, BufferOpenState),
            (add_fonts, "menu-add_fonts", OpenAddFonts, BufferOpenState),
       -    (
       -        open_font_manager,
       -        "menu-open_font_manager",
       -        OpenFontManager,
       -        BufferOpenState
       -    ),
       -    (
       -        open_font_directory,
       -        "menu-open_font_directoy",
       -        OpenFontDirectory,
       -        AlwaysEnabledState
       -    ),
       +    (open_font_manager, "menu-open_font_manager", OpenFontManager, BufferOpenState),
       +    (open_font_directory, "menu-open_font_directoy", OpenFontDirectory, AlwaysEnabledState),
            (
                open_palettes_directory,
                "menu-open_palettes_directoy",
                OpenPalettesDirectory,
                AlwaysEnabledState
            ),
       -    (
       -        mirror_mode,
       -        "menu-mirror_mode",
       -        ToggleMirrorMode,
       -        BufferOpenState
       -    ),
       -    (
       -        clear_recent_open,
       -        "menu-open_recent_clear",
       -        ClearRecentOpenFiles,
       -        HasRecentFilesState
       -    ),
       -    (
       -        inverse_selection,
       -        "menu-inverse_selection",
       -        InverseSelection,
       -        BufferOpenState
       -    ),
       -    (
       -        clear_selection,
       -        "menu-delete_row",
       -        ClearSelection,
       -        BufferOpenState,
       -        Escape,
       -        NONE
       -    ),
       -    (
       -        select_palette,
       -        "menu-select_palette",
       -        SelectPalette,
       -        CanSwitchPaletteState
       -    ),
       -    (
       -        show_layer_borders,
       -        "menu-show_layer_borders",
       -        ToggleLayerBorders,
       -        LayerBordersState
       -    ),
       -    (
       -        show_line_numbers,
       -        "menu-show_line_numbers",
       -        ToggleLineNumbers,
       -        LineNumberState
       -    ),
       -    (
       -        open_plugin_directory,
       -        "menu-open_plugin_directory",
       -        OpenPluginDirectory,
       -        AlwaysEnabledState
       -    ),
       -    (
       -        next_fg_color,
       -        "menu-next_fg_color",
       -        NextFgColor,
       -        BufferOpenState,
       -        ArrowDown,
       -        CTRL
       -    ),
       -    (
       -        prev_fg_color,
       -        "menu-prev_fg_color",
       -        PreviousFgColor,
       -        BufferOpenState,
       -        ArrowUp,
       -        CTRL
       -    ),
       -    (
       -        next_bg_color,
       -        "menu-next_bg_color",
       -        NextBgColor,
       -        BufferOpenState,
       -        ArrowRight,
       -        CTRL
       -    ),
       -    (
       -        prev_bg_color,
       -        "menu-prev_bg_color",
       -        PreviousBgColor,
       -        BufferOpenState,
       -        ArrowLeft,
       -        CTRL
       -    ),
       +    (mirror_mode, "menu-mirror_mode", ToggleMirrorMode, BufferOpenState),
       +    (clear_recent_open, "menu-open_recent_clear", ClearRecentOpenFiles, HasRecentFilesState),
       +    (inverse_selection, "menu-inverse_selection", InverseSelection, BufferOpenState),
       +    (clear_selection, "menu-delete_row", ClearSelection, BufferOpenState, Escape, NONE),
       +    (select_palette, "menu-select_palette", SelectPalette, CanSwitchPaletteState),
       +    (show_layer_borders, "menu-show_layer_borders", ToggleLayerBorders, LayerBordersState),
       +    (show_line_numbers, "menu-show_line_numbers", ToggleLineNumbers, LineNumberState),
       +    (open_plugin_directory, "menu-open_plugin_directory", OpenPluginDirectory, AlwaysEnabledState),
       +    (next_fg_color, "menu-next_fg_color", NextFgColor, BufferOpenState, ArrowDown, CTRL),
       +    (prev_fg_color, "menu-prev_fg_color", PreviousFgColor, BufferOpenState, ArrowUp, CTRL),
       +    (next_bg_color, "menu-next_bg_color", NextBgColor, BufferOpenState, ArrowRight, CTRL),
       +    (prev_bg_color, "menu-prev_bg_color", PreviousBgColor, BufferOpenState, ArrowLeft, CTRL),
            (lga_font, "menu-9px-font", ToggleLGAFont, LGAFontState),
       -    (
       -        aspect_ratio,
       -        "menu-aspect-ratio",
       -        ToggleAspectRatio,
       -        AspectRatioState
       -    ),
       +    (aspect_ratio, "menu-aspect-ratio", ToggleAspectRatio, AspectRatioState),
        ];
   DIR diff --git a/src/ui/dialogs/about_dialog.rs b/src/ui/dialogs/about_dialog.rs
       @@ -22,20 +22,13 @@ impl crate::ModalDialog for AboutDialog {
        
                        ui.label(fl!(crate::LANGUAGE_LOADER, "about-dialog-description"));
                        ui.add_space(12.0); // ui.separator();
       -                ui.label(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "about-dialog-created_by",
       -                    authors = env!("CARGO_PKG_AUTHORS")
       -                ));
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "about-dialog-created_by", authors = env!("CARGO_PKG_AUTHORS")));
        
                        ui.add_space(8.0); // ui.separator();
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/ask_close_file_dialog.rs b/src/ui/dialogs/ask_close_file_dialog.rs
       @@ -37,42 +37,20 @@ impl crate::ModalDialog for AskCloseFileDialog {
                    };
        
                    modal.frame(ui, |ui| {
       -                ui.strong(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "ask_close_file_dialog-description",
       -                    filename = file_name
       -                ));
       -                ui.small(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "ask_close_file_dialog-subdescription"
       -                ));
       +                ui.strong(fl!(crate::LANGUAGE_LOADER, "ask_close_file_dialog-description", filename = file_name));
       +                ui.small(fl!(crate::LANGUAGE_LOADER, "ask_close_file_dialog-subdescription"));
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "ask_close_file_dialog-save_button"
       -                    ))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "ask_close_file_dialog-save_button")).clicked() {
                            self.save = true;
                            self.do_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "ask_close_file_dialog-dont_save_button"
       -                    ))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "ask_close_file_dialog-dont_save_button")).clicked() {
                            self.save = false;
                            self.do_commit = true;
                            result = true;
       @@ -94,8 +72,7 @@ impl crate::ModalDialog for AskCloseFileDialog {
                        window.open_dialog(SaveFileDialog::default());
                        return Ok(None);
                    }
       -            if let Some(egui_tiles::Tile::Pane(pane)) = window.document_tree.tiles.get_mut(self.id)
       -            {
       +            if let Some(egui_tiles::Tile::Pane(pane)) = window.document_tree.tiles.get_mut(self.id) {
                        // TODO: potential message clash. Maybe we should return a Vec<Message> instead? OR a Vec MessageType?
                        msg = pane.save();
                        let msg2 = pane.destroy(&window.gl);
       @@ -103,9 +80,7 @@ impl crate::ModalDialog for AskCloseFileDialog {
                            msg = msg2;
                        }
                    }
       -        } else if let Some(egui_tiles::Tile::Pane(pane)) =
       -            window.document_tree.tiles.get_mut(self.id)
       -        {
       +        } else if let Some(egui_tiles::Tile::Pane(pane)) = window.document_tree.tiles.get_mut(self.id) {
                    msg = pane.destroy(&window.gl);
                }
                window.document_tree.tiles.remove(self.id);
   DIR diff --git a/src/ui/dialogs/auto_save_dialog.rs b/src/ui/dialogs/auto_save_dialog.rs
       @@ -34,25 +34,13 @@ impl crate::ModalDialog for AutoSaveDialog {
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "autosave-dialog-load_autosave_button"
       -                    ))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "autosave-dialog-load_autosave_button")).clicked() {
                            self.load_autosave = true;
                            self.finish = true;
                            result = true;
                        }
        
       -                if ui
       -                    .button(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "autosave-dialog-discard_autosave_button"
       -                    ))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "autosave-dialog-discard_autosave_button")).clicked() {
                            remove_autosave(&self.path);
                            self.load_autosave = false;
                            self.finish = true;
       @@ -69,9 +57,6 @@ impl crate::ModalDialog for AutoSaveDialog {
            }
        
            fn commit_self(&self, _window: &mut MainWindow) -> TerminalResult<Option<Message>> {
       -        Ok(Some(Message::LoadFile(
       -            self.path.clone(),
       -            self.load_autosave,
       -        )))
       +        Ok(Some(Message::LoadFile(self.path.clone(), self.load_autosave)))
            }
        }
   DIR diff --git a/src/ui/dialogs/edit_layer_dialog.rs b/src/ui/dialogs/edit_layer_dialog.rs
       @@ -54,143 +54,100 @@ impl ModalDialog for EditLayerDialog {
                    modal.title(ui, fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-title"));
        
                    modal.frame(ui, |ui| {
       -                egui::Grid::new("some_unique_id")
       -                    .num_columns(2)
       -                    .spacing([4.0, 8.0])
       -                    .show(ui, |ui| {
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-name-label"));
       -                        });
       -                        ui.add(egui::TextEdit::singleline(&mut self.title));
       -                        ui.end_row();
       +                egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-name-label"));
       +                    });
       +                    ui.add(egui::TextEdit::singleline(&mut self.title));
       +                    ui.end_row();
       +
       +                    if self.color.is_some() {
       +                        let mut use_color = true;
        
       -                        if self.color.is_some() {
       -                            let mut use_color = true;
       -
       -                            if let Some(color) = &mut self.color {
       -                                ui.label("");
       -                                ui.horizontal(|ui| {
       -                                    let mut c: [u8; 3] = (color.clone()).into();
       -                                    color_picker::color_edit_button_srgb(ui, &mut c);
       -                                    *color = c.into();
       -
       -                                    ui.checkbox(&mut use_color, "Use Color");
       -                                });
       -                                ui.end_row();
       -                            }
       -
       -                            if !use_color {
       -                                self.color = None;
       -                            }
       -                        } else {
       +                        if let Some(color) = &mut self.color {
                                    ui.label("");
       -                            let mut use_color = false;
       -                            ui.checkbox(&mut use_color, "Use Color");
       +                            ui.horizontal(|ui| {
       +                                let mut c: [u8; 3] = (color.clone()).into();
       +                                color_picker::color_edit_button_srgb(ui, &mut c);
       +                                *color = c.into();
       +
       +                                ui.checkbox(&mut use_color, "Use Color");
       +                            });
                                    ui.end_row();
       -                            if use_color {
       -                                self.color = Some(Color::new(255, 255, 255));
       -                            }
                                }
        
       +                        if !use_color {
       +                            self.color = None;
       +                        }
       +                    } else {
                                ui.label("");
       -                        ui.checkbox(
       -                            &mut self.is_visible,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-layer-dialog-is-visible-checkbox"
       -                            ),
       -                        );
       -                        ui.end_row();
       -                        ui.label("");
       -                        ui.checkbox(
       -                            &mut self.is_locked,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-layer-dialog-is-edit-locked-checkbox"
       -                            ),
       -                        );
       -                        ui.end_row();
       -                        ui.label("");
       -                        ui.checkbox(
       -                            &mut self.is_position_locked,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-layer-dialog-is-position-locked-checkbox"
       -                            ),
       -                        );
       +                        let mut use_color = false;
       +                        ui.checkbox(&mut use_color, "Use Color");
                                ui.end_row();
       -
       +                        if use_color {
       +                            self.color = Some(Color::new(255, 255, 255));
       +                        }
       +                    }
       +
       +                    ui.label("");
       +                    ui.checkbox(&mut self.is_visible, fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-visible-checkbox"));
       +                    ui.end_row();
       +                    ui.label("");
       +                    ui.checkbox(&mut self.is_locked, fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-edit-locked-checkbox"));
       +                    ui.end_row();
       +                    ui.label("");
       +                    ui.checkbox(
       +                        &mut self.is_position_locked,
       +                        fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-position-locked-checkbox"),
       +                    );
       +                    ui.end_row();
       +
       +                    ui.label("");
       +                    ui.checkbox(&mut self.has_alpha_channel, fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-has-alpha-checkbox"));
       +                    ui.end_row();
       +
       +                    if self.has_alpha_channel {
                                ui.label("");
                                ui.checkbox(
       -                            &mut self.has_alpha_channel,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-layer-dialog-has-alpha-checkbox"
       -                            ),
       +                            &mut self.is_alpha_channel_locked,
       +                            fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-alpha-locked-checkbox"),
                                );
                                ui.end_row();
       +                    }
       +
       +                    ui.label("Mode:");
       +
       +                    egui::ComboBox::from_id_source("combobox1")
       +                        .width(150.)
       +                        .selected_text(RichText::new(match self.mode {
       +                            Mode::Normal => "Normal",
       +                            Mode::Chars => "Chars only",
       +                            Mode::Attributes => "Attribute only",
       +                        }))
       +                        .show_ui(ui, |ui| {
       +                            ui.selectable_value(&mut self.mode, Mode::Normal, "Normal");
       +                            ui.selectable_value(&mut self.mode, Mode::Chars, "Chars only");
       +                            ui.selectable_value(&mut self.mode, Mode::Attributes, "Attribute only");
       +                        });
       +                    ui.end_row();
        
       -                        if self.has_alpha_channel {
       -                            ui.label("");
       -                            ui.checkbox(
       -                                &mut self.is_alpha_channel_locked,
       -                                fl!(
       -                                    crate::LANGUAGE_LOADER,
       -                                    "edit-layer-dialog-is-alpha-locked-checkbox"
       -                                ),
       -                            );
       -                            ui.end_row();
       -                        }
       -
       -                        ui.label("Mode:");
       -
       -                        egui::ComboBox::from_id_source("combobox1")
       -                            .width(150.)
       -                            .selected_text(RichText::new(match self.mode {
       -                                Mode::Normal => "Normal",
       -                                Mode::Chars => "Chars only",
       -                                Mode::Attributes => "Attribute only",
       -                            }))
       -                            .show_ui(ui, |ui| {
       -                                ui.selectable_value(&mut self.mode, Mode::Normal, "Normal");
       -                                ui.selectable_value(&mut self.mode, Mode::Chars, "Chars only");
       -                                ui.selectable_value(
       -                                    &mut self.mode,
       -                                    Mode::Attributes,
       -                                    "Attribute only",
       -                                );
       -                            });
       -                        ui.end_row();
       +                    ui.label(fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-x-offset-label"));
       +                    ui.add(egui::DragValue::new(&mut self.x_offset));
       +                    ui.end_row();
        
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "edit-layer-dialog-is-x-offset-label"
       -                        ));
       -                        ui.add(egui::DragValue::new(&mut self.x_offset));
       -                        ui.end_row();
       -
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "edit-layer-dialog-is-y-offset-label"
       -                        ));
       -                        ui.add(egui::DragValue::new(&mut self.y_offset));
       -                        ui.end_row();
       -                    });
       +                    ui.label(fl!(crate::LANGUAGE_LOADER, "edit-layer-dialog-is-y-offset-label"));
       +                    ui.add(egui::DragValue::new(&mut self.y_offset));
       +                    ui.end_row();
       +                });
                        ui.add_space(16.0);
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/edit_sauce_dialog.rs b/src/ui/dialogs/edit_sauce_dialog.rs
       @@ -28,63 +28,57 @@ impl ModalDialog for EditSauceDialog {
                    modal.title(ui, fl!(crate::LANGUAGE_LOADER, "edit-sauce-title"));
        
                    modal.frame(ui, |ui| {
       -                egui::Grid::new("some_unique_id")
       -                    .num_columns(2)
       -                    .spacing([4.0, 8.0])
       -                    .show(ui, |ui| {
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-title-label"));
       -                        });
       -                        ui.horizontal(|ui| {
       -                            let mut tmp_str = self.sauce_data.title.to_string();
       -                            ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -                            self.sauce_data.title = SauceString::from(&tmp_str);
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-title-label-length"));
       -                        });
       -                        ui.end_row();
       +                egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-title-label"));
       +                    });
       +                    ui.horizontal(|ui| {
       +                        let mut tmp_str = self.sauce_data.title.to_string();
       +                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +                        self.sauce_data.title = SauceString::from(&tmp_str);
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-title-label-length"));
       +                    });
       +                    ui.end_row();
        
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-author-label"));
       -                        });
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-author-label"));
       +                    });
        
       -                        ui.horizontal(|ui| {
       -                            let mut tmp_str = self.sauce_data.author.to_string();
       -                            ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(20));
       -                            self.sauce_data.author = SauceString::from(&tmp_str);
       -                            ui.label(fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-sauce-author-label-length"
       -                            ));
       -                        });
       -                        ui.end_row();
       +                    ui.horizontal(|ui| {
       +                        let mut tmp_str = self.sauce_data.author.to_string();
       +                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(20));
       +                        self.sauce_data.author = SauceString::from(&tmp_str);
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-author-label-length"));
       +                    });
       +                    ui.end_row();
        
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-group-label"));
       -                        });
       -                        ui.horizontal(|ui| {
       -                            let mut tmp_str = self.sauce_data.group.to_string();
       -                            ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(20));
       -                            self.sauce_data.group = SauceString::from(&tmp_str);
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-group-label-length"));
       -                        });
       -                        ui.end_row();
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-group-label"));
       +                    });
       +                    ui.horizontal(|ui| {
       +                        let mut tmp_str = self.sauce_data.group.to_string();
       +                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(20));
       +                        self.sauce_data.group = SauceString::from(&tmp_str);
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-group-label-length"));
       +                    });
       +                    ui.end_row();
        
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-letter-spacing"));
       -                        });
       -                        ui.horizontal(|ui| {
       -                            ui.checkbox(&mut self.sauce_data.use_letter_spacing, "");
       -                        });
       -                        ui.end_row();
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-letter-spacing"));
       +                    });
       +                    ui.horizontal(|ui| {
       +                        ui.checkbox(&mut self.sauce_data.use_letter_spacing, "");
       +                    });
       +                    ui.end_row();
        
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-aspect-ratio"));
       -                        });
       -                        ui.horizontal(|ui| {
       -                            ui.checkbox(&mut self.sauce_data.use_aspect_ratio, "");
       -                        });
       -                        ui.end_row();
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-aspect-ratio"));
                            });
       +                    ui.horizontal(|ui| {
       +                        ui.checkbox(&mut self.sauce_data.use_aspect_ratio, "");
       +                    });
       +                    ui.end_row();
       +                });
                        ui.add_space(16.0);
                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-sauce-comments-label"));
                        ui.add_space(4.0);
       @@ -94,15 +88,9 @@ impl ModalDialog for EditSauceDialog {
                            tmp_str.push('\n');
                        }
                        self.sauce_data.comments.clear();
       -                egui::ScrollArea::vertical()
       -                    .max_height(180.0)
       -                    .show(ui, |ui| {
       -                        ui.add(
       -                            egui::TextEdit::multiline(&mut tmp_str)
       -                                .desired_rows(6)
       -                                .desired_width(f32::INFINITY),
       -                        );
       -                    });
       +                egui::ScrollArea::vertical().max_height(180.0).show(ui, |ui| {
       +                    ui.add(egui::TextEdit::multiline(&mut tmp_str).desired_rows(6).desired_width(f32::INFINITY));
       +                });
        
                        let mut number = 0;
                        for line in tmp_str.lines() {
       @@ -116,17 +104,11 @@ impl ModalDialog for EditSauceDialog {
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
       @@ -141,9 +123,6 @@ impl ModalDialog for EditSauceDialog {
        
            fn commit(&self, editor: &mut AnsiEditor) -> TerminalResult<Option<Message>> {
                let bv = &mut editor.buffer_view.lock();
       -        Ok(to_message(
       -            bv.get_edit_state_mut()
       -                .update_sauce_data(Some(self.sauce_data.clone())),
       -        ))
       +        Ok(to_message(bv.get_edit_state_mut().update_sauce_data(Some(self.sauce_data.clone()))))
            }
        }
   DIR diff --git a/src/ui/dialogs/export_file_dialog/ansi.rs b/src/ui/dialogs/export_file_dialog/ansi.rs
       @@ -5,10 +5,7 @@ use icy_engine::{SaveOptions, ScreenPreperation};
        pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
            ui.vertical(|ui| {
                ui.horizontal(|ui| {
       -            ui.label(fl!(
       -                crate::LANGUAGE_LOADER,
       -                "export-video-preparation-label"
       -            ));
       +            ui.label(fl!(crate::LANGUAGE_LOADER, "export-video-preparation-label"));
        
                    let label = match options.screen_preparation {
                        ScreenPreperation::None => {
       @@ -43,10 +40,7 @@ pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
                            );
                        });
                });
       -        ui.checkbox(
       -            &mut options.compress,
       -            fl!(crate::LANGUAGE_LOADER, "export-compression-label"),
       -        );
       +        ui.checkbox(&mut options.compress, fl!(crate::LANGUAGE_LOADER, "export-compression-label"));
                ui.horizontal(|ui| {
                    ui.add(egui::Checkbox::new(
                        &mut options.modern_terminal_output,
       @@ -64,10 +58,7 @@ pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
                    let mut use_max_lines = options.output_line_length.is_some();
                    ui.add(egui::Checkbox::new(
                        &mut use_max_lines,
       -                fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "export-limit-output-line-length-label"
       -                ),
       +                fl!(crate::LANGUAGE_LOADER, "export-limit-output-line-length-label"),
                    ));
                    if use_max_lines != options.output_line_length.is_some() {
                        if use_max_lines {
       @@ -77,10 +68,7 @@ pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
                        }
                    }
                    if let Some(mut len) = options.output_line_length {
       -                ui.add(
       -                    egui::Slider::new(&mut len, 32..=255)
       -                        .text(fl!(crate::LANGUAGE_LOADER, "export-maximum_line_length")),
       -                );
       +                ui.add(egui::Slider::new(&mut len, 32..=255).text(fl!(crate::LANGUAGE_LOADER, "export-maximum_line_length")));
                        options.output_line_length = Some(len);
                    }
                });
   DIR diff --git a/src/ui/dialogs/export_file_dialog/avatar.rs b/src/ui/dialogs/export_file_dialog/avatar.rs
       @@ -5,10 +5,7 @@ use icy_engine::{SaveOptions, ScreenPreperation};
        pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
            ui.vertical(|ui| {
                ui.horizontal(|ui| {
       -            ui.label(fl!(
       -                crate::LANGUAGE_LOADER,
       -                "export-video-preparation-label"
       -            ));
       +            ui.label(fl!(crate::LANGUAGE_LOADER, "export-video-preparation-label"));
        
                    let label = match options.screen_preparation {
                        ScreenPreperation::None => {
   DIR diff --git a/src/ui/dialogs/export_file_dialog/ice_draw.rs b/src/ui/dialogs/export_file_dialog/ice_draw.rs
       @@ -4,10 +4,7 @@ use icy_engine::SaveOptions;
        
        pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
            ui.vertical(|ui| {
       -        ui.checkbox(
       -            &mut options.compress,
       -            fl!(crate::LANGUAGE_LOADER, "export-compression-label"),
       -        );
       +        ui.checkbox(&mut options.compress, fl!(crate::LANGUAGE_LOADER, "export-compression-label"));
                ui.add(egui::Checkbox::new(
                    &mut options.save_sauce,
                    fl!(crate::LANGUAGE_LOADER, "export-save-sauce-label"),
   DIR diff --git a/src/ui/dialogs/export_file_dialog/mod.rs b/src/ui/dialogs/export_file_dialog/mod.rs
       @@ -108,8 +108,7 @@ impl ModalDialog for ExportFileDialog {
                                        ui.selectable_value(&mut format_type, i, td.0);
                                    });
                                });
       -                    self.file_name
       -                        .set_extension(TYPE_DESCRIPTIONS[format_type].2);
       +                    self.file_name.set_extension(TYPE_DESCRIPTIONS[format_type].2);
                            //    });
                        });
        
       @@ -117,17 +116,11 @@ impl ModalDialog for ExportFileDialog {
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "export-button-title"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "export-button-title")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
       @@ -147,27 +140,16 @@ impl ModalDialog for ExportFileDialog {
                        if ext == "png" {
                            let lock = &editor.buffer_view.lock();
                            let buf = lock.get_buffer();
       -                    let (size, pixels) = buf.render_to_rgba(Rectangle::from(
       -                        0,
       -                        0,
       -                        buf.get_width(),
       -                        buf.get_height(),
       -                    ));
       -                    let image_buffer =
       -                        image::RgbaImage::from_raw(size.width as u32, size.height as u32, pixels);
       +                    let (size, pixels) = buf.render_to_rgba(Rectangle::from(0, 0, buf.get_width(), buf.get_height()));
       +                    let image_buffer = image::RgbaImage::from_raw(size.width as u32, size.height as u32, pixels);
                            match image_buffer {
                                Some(img) => {
                                    if let Err(err) = img.save(&self.file_name) {
       -                                return Ok(Some(Message::ShowError(format!(
       -                                    "Failed to save image: {}",
       -                                    err
       -                                ))));
       +                                return Ok(Some(Message::ShowError(format!("Failed to save image: {}", err))));
                                    }
                                }
                                None => {
       -                            return Ok(Some(Message::ShowError(
       -                                "Failed to save image".to_string(),
       -                            )));
       +                            return Ok(Some(Message::ShowError("Failed to save image".to_string())));
                                }
                            }
        
       @@ -190,11 +172,7 @@ const TYPE_DESCRIPTIONS: [(&str, CreateSettingsFunction, &str); 11] = [
            ("Ascii (.asc)", ascii::create_settings_page, "asc"),
            ("Artworx (.adf)", artworx::create_settings_page, "adf"),
            ("Ice Draw (.idf)", ice_draw::create_settings_page, "idf"),
       -    (
       -        "Tundra Draw (.tnd)",
       -        tundra_draw::create_settings_page,
       -        "tnd",
       -    ),
       +    ("Tundra Draw (.tnd)", tundra_draw::create_settings_page, "tnd"),
            ("Bin (.bin)", bin::create_settings_page, "bin"),
            ("XBin (.xb)", xbin::create_settings_page, "xb"),
            ("CtrlA (.msg)", pcboard::create_settings_page, "msg"),
   DIR diff --git a/src/ui/dialogs/export_file_dialog/xbin.rs b/src/ui/dialogs/export_file_dialog/xbin.rs
       @@ -4,10 +4,7 @@ use icy_engine::SaveOptions;
        
        pub fn create_settings_page(ui: &mut Ui, options: &mut SaveOptions) {
            ui.vertical(|ui| {
       -        ui.checkbox(
       -            &mut options.compress,
       -            fl!(crate::LANGUAGE_LOADER, "export-compression-label"),
       -        );
       +        ui.checkbox(&mut options.compress, fl!(crate::LANGUAGE_LOADER, "export-compression-label"));
                ui.add(egui::Checkbox::new(
                    &mut options.save_sauce,
                    fl!(crate::LANGUAGE_LOADER, "export-save-sauce-label"),
   DIR diff --git a/src/ui/dialogs/font_manager.rs b/src/ui/dialogs/font_manager.rs
       @@ -47,119 +47,81 @@ impl crate::ModalDialog for FontManager {
                        egui::CentralPanel::default().show_inside(ui, |ui| {
                            let row_height = 24.0;
                            ui.label(fl!(crate::LANGUAGE_LOADER, "manage-font-used_font_label"));
       -                    egui::ScrollArea::vertical()
       -                        .id_source("bitfont_scroll_area")
       -                        .show(ui, |ui| {
       -                            for (i, font) in self.buffer_view.lock().get_buffer().font_iter() {
       -                                let is_selected = *i == self.selected;
       -
       -                                let (id, rect) =
       -                                    ui.allocate_space([ui.available_width(), row_height].into());
       -                                let response = ui.interact(rect, id, Sense::click());
       -                                if response.hovered() {
       -                                    ui.painter().rect_filled(
       -                                        rect.expand(1.0),
       -                                        Rounding::same(4.0),
       -                                        ui.style().visuals.widgets.active.bg_fill,
       -                                    );
       -                                } else if is_selected {
       -                                    ui.painter().rect_filled(
       -                                        rect.expand(1.0),
       -                                        Rounding::same(4.0),
       -                                        ui.style().visuals.extreme_bg_color,
       -                                    );
       -                                }
       +                    egui::ScrollArea::vertical().id_source("bitfont_scroll_area").show(ui, |ui| {
       +                        for (i, font) in self.buffer_view.lock().get_buffer().font_iter() {
       +                            let is_selected = *i == self.selected;
       +
       +                            let (id, rect) = ui.allocate_space([ui.available_width(), row_height].into());
       +                            let response = ui.interact(rect, id, Sense::click());
       +                            if response.hovered() {
       +                                ui.painter()
       +                                    .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +                            } else if is_selected {
       +                                ui.painter()
       +                                    .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
       +                            }
        
       -                                let font_id = FontId::new(12.0, FontFamily::Monospace);
       -                                let text: WidgetText = format!("{i:-3}.").into();
       -                                let galley = text.into_galley(
       -                                    ui,
       -                                    Some(false),
       -                                    f32::INFINITY,
       -                                    font_id.clone(),
       -                                );
       -                                let size = galley.size();
       -                                let mut title_rect = rect;
       -                                title_rect.set_left(title_rect.left() + 4.0);
       -                                title_rect.set_top(title_rect.bottom() - size.y - 8.0);
       -                                let text_color = if is_selected {
       -                                    ui.style().visuals.strong_text_color()
       -                                } else {
       -                                    ui.style().visuals.text_color()
       -                                };
       -                                ui.painter().galley_with_color(
       -                                    egui::Align2::LEFT_TOP
       -                                        .align_size_within_rect(
       -                                            galley.size(),
       -                                            title_rect.shrink(4.0),
       -                                        )
       -                                        .min,
       -                                    galley.galley,
       -                                    text_color,
       -                                );
       +                            let font_id = FontId::new(12.0, FontFamily::Monospace);
       +                            let text: WidgetText = format!("{i:-3}.").into();
       +                            let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id.clone());
       +                            let size = galley.size();
       +                            let mut title_rect = rect;
       +                            title_rect.set_left(title_rect.left() + 4.0);
       +                            title_rect.set_top(title_rect.bottom() - size.y - 8.0);
       +                            let text_color = if is_selected {
       +                                ui.style().visuals.strong_text_color()
       +                            } else {
       +                                ui.style().visuals.text_color()
       +                            };
       +                            ui.painter().galley_with_color(
       +                                egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), title_rect.shrink(4.0)).min,
       +                                galley.galley,
       +                                text_color,
       +                            );
        
       -                                let font_id = TextStyle::Button.resolve(ui.style());
       -                                let text: WidgetText = font.name.clone().into();
       -                                let galley =
       -                                    text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       -                                let mut title_rect = rect;
       -                                title_rect.set_left(title_rect.left() + 4.0 + size.x + 4.0);
       -                                ui.painter().galley_with_color(
       -                                    egui::Align2::LEFT_TOP
       -                                        .align_size_within_rect(
       -                                            galley.size(),
       -                                            title_rect.shrink(4.0),
       -                                        )
       -                                        .min,
       -                                    galley.galley,
       -                                    text_color,
       -                                );
       +                            let font_id = TextStyle::Button.resolve(ui.style());
       +                            let text: WidgetText = font.name.clone().into();
       +                            let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       +                            let mut title_rect = rect;
       +                            title_rect.set_left(title_rect.left() + 4.0 + size.x + 4.0);
       +                            ui.painter().galley_with_color(
       +                                egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), title_rect.shrink(4.0)).min,
       +                                galley.galley,
       +                                text_color,
       +                            );
        
       -                                let font_id = TextStyle::Button.resolve(ui.style());
       -                                let text: WidgetText =
       -                                    format!("{}x{}", font.size.width, font.size.height).into();
       -                                let galley =
       -                                    text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       -                                let mut title_rect = rect;
       -                                title_rect.set_left(title_rect.left() + 399.0);
       -                                ui.painter().galley_with_color(
       -                                    egui::Align2::LEFT_TOP
       -                                        .align_size_within_rect(
       -                                            galley.size(),
       -                                            title_rect.shrink(4.0),
       -                                        )
       -                                        .min,
       -                                    galley.galley,
       -                                    text_color,
       -                                );
       +                            let font_id = TextStyle::Button.resolve(ui.style());
       +                            let text: WidgetText = format!("{}x{}", font.size.width, font.size.height).into();
       +                            let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       +                            let mut title_rect = rect;
       +                            title_rect.set_left(title_rect.left() + 399.0);
       +                            ui.painter().galley_with_color(
       +                                egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), title_rect.shrink(4.0)).min,
       +                                galley.galley,
       +                                text_color,
       +                            );
        
       -                                let font_id = TextStyle::Button.resolve(ui.style());
       -                                let text: WidgetText = if self.used_fonts.contains(i) {
       -                                    fl!(crate::LANGUAGE_LOADER, "manage-font-used_label")
       -                                } else {
       -                                    fl!(crate::LANGUAGE_LOADER, "manage-font-not_used_label")
       -                                }
       -                                .into();
       -                                let galley =
       -                                    text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       -                                let mut title_rect = rect;
       -                                title_rect.set_left(title_rect.left() + 480.0);
       -                                ui.painter().galley_with_color(
       -                                    egui::Align2::LEFT_TOP
       -                                        .align_size_within_rect(
       -                                            galley.size(),
       -                                            title_rect.shrink(4.0),
       -                                        )
       -                                        .min,
       -                                    galley.galley,
       -                                    text_color,
       -                                );
       +                            let font_id = TextStyle::Button.resolve(ui.style());
       +                            let text: WidgetText = if self.used_fonts.contains(i) {
       +                                fl!(crate::LANGUAGE_LOADER, "manage-font-used_label")
       +                            } else {
       +                                fl!(crate::LANGUAGE_LOADER, "manage-font-not_used_label")
       +                            }
       +                            .into();
       +                            let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       +                            let mut title_rect = rect;
       +                            title_rect.set_left(title_rect.left() + 480.0);
       +                            ui.painter().galley_with_color(
       +                                egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), title_rect.shrink(4.0)).min,
       +                                galley.galley,
       +                                text_color,
       +                            );
        
       -                                if response.clicked() {
       -                                    self.selected = *i;
       -                                }
       +                            if response.clicked() {
       +                                self.selected = *i;
                                    }
       -                        });
       +                        }
       +                    });
                        });
                        TopBottomPanel::bottom("font_manager_bottom_panel")
                            .exact_height(24.0)
       @@ -170,30 +132,15 @@ impl crate::ModalDialog for FontManager {
                                ui.horizontal(|ui| {
                                    ui.label(fl!(crate::LANGUAGE_LOADER, "manage-font-replace_label"));
                                    let mut tmp_str = self.replace_with.to_string();
       -                            ui.add(
       -                                egui::TextEdit::singleline(&mut tmp_str)
       -                                    .desired_width(80.0)
       -                                    .char_limit(4),
       -                            );
       +                            ui.add(egui::TextEdit::singleline(&mut tmp_str).desired_width(80.0).char_limit(4));
                                    if let Ok(new_width) = tmp_str.parse::<usize>() {
                                        self.replace_with = new_width;
                                    } else {
                                        self.replace_with = 0;
                                    }
       -                            let enabled = self
       -                                .buffer_view
       -                                .lock()
       -                                .get_buffer()
       -                                .get_font(self.replace_with)
       -                                .is_some();
       +                            let enabled = self.buffer_view.lock().get_buffer().get_font(self.replace_with).is_some();
                                    if ui
       -                                .add_enabled(
       -                                    enabled,
       -                                    Button::new(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "manage-font-replace_font_button"
       -                                    )),
       -                                )
       +                                .add_enabled(enabled, Button::new(fl!(crate::LANGUAGE_LOADER, "manage-font-replace_font_button")))
                                        .clicked()
                                    {
                                        if let Err(err) = self
       @@ -202,11 +149,7 @@ impl crate::ModalDialog for FontManager {
                                            .get_edit_state_mut()
                                            .replace_font_usage(self.selected, self.replace_with)
                                        {
       -                                    log::error!(
       -                                        "Error replacing font {}->{}: {err}",
       -                                        self.selected,
       -                                        self.replace_with
       -                                    );
       +                                    log::error!("Error replacing font {}->{}: {err}", self.selected, self.replace_with);
                                        }
                                        self.update_used_fonts();
                                        self.selected = 0;
       @@ -215,26 +158,11 @@ impl crate::ModalDialog for FontManager {
                                    }
        
                                    if ui
       -                                .add_enabled(
       -                                    !enabled,
       -                                    Button::new(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "manage-font-change_font_slot_button"
       -                                    )),
       -                                )
       +                                .add_enabled(!enabled, Button::new(fl!(crate::LANGUAGE_LOADER, "manage-font-change_font_slot_button")))
                                        .clicked()
                                    {
       -                                if let Err(err) = self
       -                                    .buffer_view
       -                                    .lock()
       -                                    .get_edit_state_mut()
       -                                    .change_font_slot(self.selected, self.replace_with)
       -                                {
       -                                    log::error!(
       -                                        "Error change font {}->{}: {err}",
       -                                        self.selected,
       -                                        self.replace_with
       -                                    );
       +                                if let Err(err) = self.buffer_view.lock().get_edit_state_mut().change_font_slot(self.selected, self.replace_with) {
       +                                    log::error!("Error change font {}->{}: {err}", self.selected, self.replace_with);
                                        }
                                        self.update_used_fonts();
                                        self.selected = 0;
       @@ -246,22 +174,13 @@ impl crate::ModalDialog for FontManager {
                    });
                    ui.add_space(8.0);
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            result = true;
                        }
        
       -                let copy_font_button = ui.add(Button::new(fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "manage-font-copy_font_button"
       -                )));
       +                let copy_font_button = ui.add(Button::new(fl!(crate::LANGUAGE_LOADER, "manage-font-copy_font_button")));
                        let copy_font_button = copy_font_button.on_hover_ui(|ui| {
       -                    ui.label(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "manage-font-copy_font_button-tooltip"
       -                    ));
       +                    ui.label(fl!(crate::LANGUAGE_LOADER, "manage-font-copy_font_button-tooltip"));
                        });
        
                        if copy_font_button.clicked() {
       @@ -270,20 +189,9 @@ impl crate::ModalDialog for FontManager {
                                ui.output_mut(|o| o.copied_text = font.encode_as_ansi(self.selected));
                            }
                        }
       -                let remove_font_button = &ui.add_enabled(
       -                    self.selected > 0,
       -                    Button::new(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "manage-font-remove_font_button"
       -                    )),
       -                );
       +                let remove_font_button = &ui.add_enabled(self.selected > 0, Button::new(fl!(crate::LANGUAGE_LOADER, "manage-font-remove_font_button")));
                        if remove_font_button.clicked() {
       -                    if let Err(err) = self
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state_mut()
       -                        .remove_font(self.selected)
       -                    {
       +                    if let Err(err) = self.buffer_view.lock().get_edit_state_mut().remove_font(self.selected) {
                                log::error!("Error removing font {}: {err}", self.selected);
                            }
                            self.update_used_fonts();
   DIR diff --git a/src/ui/dialogs/font_selector.rs b/src/ui/dialogs/font_selector.rs
       @@ -10,9 +10,7 @@ use i18n_embed_fl::fl;
        use icy_engine::{AttributedChar, BitFont, Buffer, TextAttribute, ANSI_FONTS, SAUCE_FONT_NAMES};
        use walkdir::WalkDir;
        
       -use crate::{
       -    create_retained_image, is_font_extensions, AnsiEditor, Message, Settings, TerminalResult,
       -};
       +use crate::{create_retained_image, is_font_extensions, AnsiEditor, Message, Settings, TerminalResult};
        
        #[derive(Default)]
        struct BitfontSource {
       @@ -52,10 +50,7 @@ impl FontSelector {
                    ));
                }
        
       -        let only_sauce_fonts = matches!(
       -            editor.buffer_view.lock().get_buffer().font_mode,
       -            icy_engine::FontMode::Sauce
       -        );
       +        let only_sauce_fonts = matches!(editor.buffer_view.lock().get_buffer().font_mode, icy_engine::FontMode::Sauce);
        
                if !only_sauce_fonts {
                    for slot in 0..ANSI_FONTS {
       @@ -232,29 +227,17 @@ impl FontSelector {
                }
            }
        
       -    pub fn draw_font_row(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_font: usize,
       -        row_height: f32,
       -        is_selected: bool,
       -    ) -> Response {
       +    pub fn draw_font_row(&mut self, ui: &mut egui::Ui, cur_font: usize, row_height: f32, is_selected: bool) -> Response {
                let font = &self.fonts[cur_font];
                let (id, rect) = ui.allocate_space([ui.available_width(), row_height].into());
                let response = ui.interact(rect, id, Sense::click());
        
                if response.hovered() {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.widgets.active.bg_fill,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
                } else if is_selected {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.extreme_bg_color,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
                }
        
                let text_color = if is_selected {
       @@ -267,9 +250,7 @@ impl FontSelector {
                let text: WidgetText = font.0.name.clone().into();
                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
                ui.painter().galley_with_color(
       -            egui::Align2::LEFT_TOP
       -                .align_size_within_rect(galley.size(), rect.shrink(4.0))
       -                .min,
       +            egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), rect.shrink(4.0)).min,
                    galley.galley,
                    text_color,
                );
       @@ -281,10 +262,7 @@ impl FontSelector {
                    for ch in 0..256 {
                        buffer.layers[0].set_char(
                            (ch % 64, ch / 64),
       -                    AttributedChar::new(
       -                        unsafe { char::from_u32_unchecked(ch as u32) },
       -                        TextAttribute::default(),
       -                    ),
       +                    AttributedChar::new(unsafe { char::from_u32_unchecked(ch as u32) }, TextAttribute::default()),
                        );
                    }
                    let img = create_retained_image(&buffer);
       @@ -294,10 +272,7 @@ impl FontSelector {
                if let Some(image) = self.image_cache.get(&cur_font) {
                    let w = (image.width() as f32).floor();
                    let h = (image.height() as f32).floor();
       -            let r = Rect::from_min_size(
       -                Pos2::new((rect.left() + 4.0).floor(), (rect.top() + 24.0).floor()),
       -                Vec2::new(w, h),
       -            );
       +            let r = Rect::from_min_size(Pos2::new((rect.left() + 4.0).floor(), (rect.top() + 24.0).floor()), Vec2::new(w, h));
                    ui.painter().image(
                        image.texture_id(ui.ctx()),
                        r,
       @@ -307,42 +282,22 @@ impl FontSelector {
        
                    let mut rect = rect;
                    if font.1.library {
       -                let left = print_source(
       -                    fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"),
       -                    ui,
       -                    rect,
       -                    text_color,
       -                );
       +                let left = print_source(fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"), ui, rect, text_color);
                        rect.set_right(left);
                    }
        
                    if font.1.sauce.is_some() {
       -                let left = print_source(
       -                    fl!(crate::LANGUAGE_LOADER, "font_selector-sauce_font"),
       -                    ui,
       -                    rect,
       -                    text_color,
       -                );
       +                let left = print_source(fl!(crate::LANGUAGE_LOADER, "font_selector-sauce_font"), ui, rect, text_color);
                        rect.set_right(left);
                    }
        
                    if font.1.ansi_slot.is_some() {
       -                let left = print_source(
       -                    fl!(crate::LANGUAGE_LOADER, "font_selector-ansi_font"),
       -                    ui,
       -                    rect,
       -                    text_color,
       -                );
       +                let left = print_source(fl!(crate::LANGUAGE_LOADER, "font_selector-ansi_font"), ui, rect, text_color);
                        rect.set_right(left);
                    }
        
                    if font.1.file_slot.is_some() {
       -                let left = print_source(
       -                    fl!(crate::LANGUAGE_LOADER, "font_selector-file_font"),
       -                    ui,
       -                    rect,
       -                    text_color,
       -                );
       +                let left = print_source(fl!(crate::LANGUAGE_LOADER, "font_selector-file_font"), ui, rect, text_color);
                        rect.set_right(left);
                    }
                }
       @@ -357,24 +312,15 @@ fn print_source(font_type: String, ui: &egui::Ui, rect: Rect, text_color: Color3
            let galley_size = galley.size();
        
            let left_side = rect.right() - galley_size.x - 10.0;
       -    let rect = Rect::from_min_size(
       -        Pos2::new((left_side).floor(), (rect.top() + 8.0).floor()),
       -        galley_size,
       -    );
       -
       -    ui.painter().rect_filled(
       -        rect.expand(2.0),
       -        Rounding::same(4.0),
       -        ui.style().visuals.widgets.active.bg_fill,
       -    );
       +    let rect = Rect::from_min_size(Pos2::new((left_side).floor(), (rect.top() + 8.0).floor()), galley_size);
        
            ui.painter()
       -        .rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
       +        .rect_filled(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +
       +    ui.painter().rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
        
            ui.painter().galley_with_color(
       -        egui::Align2::CENTER_CENTER
       -            .align_size_within_rect(galley_size, rect)
       -            .min,
       +        egui::Align2::CENTER_CENTER.align_size_within_rect(galley_size, rect).min,
                galley.galley,
                text_color,
            );
       @@ -390,17 +336,9 @@ impl crate::ModalDialog for FontSelector {
                    modal.title(
                        ui,
                        if self.should_add {
       -                    fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "add-font-dialog-title",
       -                        fontcount = font_count
       -                    )
       +                    fl!(crate::LANGUAGE_LOADER, "add-font-dialog-title", fontcount = font_count)
                        } else {
       -                    fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "select-font-dialog-title",
       -                        fontcount = font_count
       -                    )
       +                    fl!(crate::LANGUAGE_LOADER, "select-font-dialog-title", fontcount = font_count)
                        },
                    );
                    modal.frame(ui, |ui| {
       @@ -408,43 +346,28 @@ impl crate::ModalDialog for FontSelector {
                        ui.horizontal(|ui: &mut egui::Ui| {
                            ui.add_sized(
                                [250.0, 20.0],
       -                        TextEdit::singleline(&mut self.filter).hint_text(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-filter-text"
       -                        )),
       +                        TextEdit::singleline(&mut self.filter).hint_text(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-filter-text")),
                            );
                            let response = ui.button("🗙");
                            if response.clicked() {
                                self.filter.clear();
                            }
                            if !self.only_sauce_fonts {
       -                        let response = ui.selectable_label(
       -                            self.show_library,
       -                            fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"),
       -                        );
       +                        let response = ui.selectable_label(self.show_library, fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"));
                                if response.clicked() {
                                    self.show_library = !self.show_library;
                                }
        
       -                        let response = ui.selectable_label(
       -                            self.show_file,
       -                            fl!(crate::LANGUAGE_LOADER, "font_selector-file_font"),
       -                        );
       +                        let response = ui.selectable_label(self.show_file, fl!(crate::LANGUAGE_LOADER, "font_selector-file_font"));
                                if response.clicked() {
                                    self.show_file = !self.show_file;
                                }
        
       -                        let response = ui.selectable_label(
       -                            self.show_builtin,
       -                            fl!(crate::LANGUAGE_LOADER, "font_selector-ansi_font"),
       -                        );
       +                        let response = ui.selectable_label(self.show_builtin, fl!(crate::LANGUAGE_LOADER, "font_selector-ansi_font"));
                                if response.clicked() {
                                    self.show_builtin = !self.show_builtin;
                                }
       -                        let response = ui.selectable_label(
       -                            self.show_sauce,
       -                            fl!(crate::LANGUAGE_LOADER, "font_selector-sauce_font"),
       -                        );
       +                        let response = ui.selectable_label(self.show_sauce, fl!(crate::LANGUAGE_LOADER, "font_selector-sauce_font"));
                                if response.clicked() {
                                    self.show_sauce = !self.show_sauce;
                                }
       @@ -461,39 +384,23 @@ impl crate::ModalDialog for FontSelector {
                                || self.show_library && font.1.library
                                || self.show_sauce && font.1.sauce.is_some();
        
       -                    if font
       -                        .0
       -                        .name
       -                        .to_lowercase()
       -                        .contains(&self.filter.to_lowercase())
       -                        && match_filter
       -                    {
       +                    if font.0.name.to_lowercase().contains(&self.filter.to_lowercase()) && match_filter {
                                filtered_fonts.push(i);
                            }
                        }
                        if filtered_fonts.is_empty() {
                            if font_count == 0 {
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-no-fonts-installed"
       -                        ));
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-no-fonts-installed"));
                            } else {
                                ui.label(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-no-fonts"));
                            }
                        } else {
       -                    egui::ScrollArea::vertical().max_height(300.).show_rows(
       -                        ui,
       -                        row_height,
       -                        filtered_fonts.len(),
       -                        |ui, range| {
       +                    egui::ScrollArea::vertical()
       +                        .max_height(300.)
       +                        .show_rows(ui, row_height, filtered_fonts.len(), |ui, range| {
                                    for row in range {
                                        let is_selected = self.selected_font == filtered_fonts[row] as i32;
       -                                let response = self.draw_font_row(
       -                                    ui,
       -                                    filtered_fonts[row],
       -                                    row_height,
       -                                    is_selected,
       -                                );
       +                                let response = self.draw_font_row(ui, filtered_fonts[row], row_height, is_selected);
        
                                        if response.clicked() {
                                            self.selected_font = filtered_fonts[row] as i32;
       @@ -504,8 +411,7 @@ impl crate::ModalDialog for FontSelector {
                                            result = true;
                                        }
                                    }
       -                        },
       -                    );
       +                        });
                        }
                    });
        
       @@ -520,22 +426,13 @@ impl crate::ModalDialog for FontSelector {
                            self.do_select = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
        
                        let enabled = self.fonts[self.selected_font as usize].0.path_opt.is_some();
                        if ui
       -                    .add_enabled(
       -                        enabled,
       -                        Button::new(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-edit-button"
       -                        )),
       -                    )
       +                    .add_enabled(enabled, Button::new(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-edit-button")))
                            .clicked()
                        {
                            self.edit_selected_font = true;
       @@ -578,17 +475,12 @@ impl crate::ModalDialog for FontSelector {
                    } else {
                        let mut font_set = false;
                        let mut font_slot = 0;
       -                editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_buffer()
       -                    .font_iter()
       -                    .for_each(|(id, f)| {
       -                        if f == font {
       -                            font_slot = *id;
       -                            font_set = true;
       -                        }
       -                    });
       +                editor.buffer_view.lock().get_buffer().font_iter().for_each(|(id, f)| {
       +                    if f == font {
       +                        font_slot = *id;
       +                        font_set = true;
       +                    }
       +                });
                        if font_set {
                            return Ok(Some(Message::SwitchToFontPage(font_slot)));
                        }
   DIR diff --git a/src/ui/dialogs/new_file_dialog.rs b/src/ui/dialogs/new_file_dialog.rs
       @@ -44,10 +44,7 @@ impl Template for Dos16Template {
            }
        
            fn description(&self) -> String {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-cp437-description"
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "new-file-template-cp437-description")
            }
        
            fn show_ui(&mut self, ui: &mut Ui) {
       @@ -152,10 +149,7 @@ impl Template for XBExtTemplate {
            }
        
            fn description(&self) -> String {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-xb-ext-description"
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "new-file-template-xb-ext-description")
            }
        
            fn show_ui(&mut self, ui: &mut Ui) {
       @@ -225,10 +219,7 @@ impl Template for FileIdTemplate {
            }
        
            fn description(&self) -> String {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-file_id-description"
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "new-file-template-file_id-description")
            }
        
            fn show_ui(&mut self, ui: &mut Ui) {
       @@ -248,30 +239,27 @@ impl Template for FileIdTemplate {
        }
        
        fn show_file_ui(ui: &mut Ui, width: &mut i32, height: &mut i32) {
       -    egui::Grid::new("some_unique_id")
       -        .num_columns(2)
       -        .spacing([4.0, 8.0])
       -        .show(ui, |ui| {
       -            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       -            });
       -            let mut tmp_str = width.to_string();
       -            ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -            if let Ok(new_width) = tmp_str.parse::<i32>() {
       -                *width = new_width;
       -            }
       -            ui.end_row();
       +    egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +            ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       +        });
       +        let mut tmp_str = width.to_string();
       +        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +        if let Ok(new_width) = tmp_str.parse::<i32>() {
       +            *width = new_width;
       +        }
       +        ui.end_row();
        
       -            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
       -            });
       -            let mut tmp_str = height.to_string();
       -            ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -            if let Ok(new_height) = tmp_str.parse::<i32>() {
       -                *height = new_height;
       -            }
       -            ui.end_row();
       +        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +            ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
                });
       +        let mut tmp_str = height.to_string();
       +        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +        if let Ok(new_height) = tmp_str.parse::<i32>() {
       +            *height = new_height;
       +        }
       +        ui.end_row();
       +    });
        }
        
        struct AnsiMationTemplate {}
       @@ -286,10 +274,7 @@ impl Template for AnsiMationTemplate {
            }
        
            fn description(&self) -> String {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-ansimation-description"
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "new-file-template-ansimation-description")
            }
        
            fn create_file(&self, window: &mut MainWindow) -> crate::TerminalResult<Option<Message>> {
       @@ -309,10 +294,7 @@ end"#;
            }
        
            fn show_ui(&mut self, ui: &mut Ui) {
       -        ui.label(fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-ansimation-ui-label"
       -        ));
       +        ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-template-ansimation-ui-label"));
                ui.hyperlink("https://github.com/mkrueger/icy_draw/blob/main/doc/lua_api.md");
            }
        }
       @@ -332,10 +314,7 @@ impl Template for BitFontTemplate {
            }
        
            fn description(&self) -> String {
       -        fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-bit_font-description"
       -        )
       +        fl!(crate::LANGUAGE_LOADER, "new-file-template-bit_font-description")
            }
        
            fn create_file(&self, window: &mut MainWindow) -> crate::TerminalResult<Option<Message>> {
       @@ -359,27 +338,21 @@ impl Template for BitFontTemplate {
                Ok(None)
            }
            fn show_ui(&mut self, ui: &mut Ui) {
       -        ui.label(fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-bitfont-ui-label"
       -        ));
       +        ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-template-bitfont-ui-label"));
                ui.add_space(8.0);
       -        egui::Grid::new("some_unique_id")
       -            .num_columns(2)
       -            .spacing([4.0, 8.0])
       -            .show(ui, |ui| {
       -                ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       -                });
       -                ui.add(egui::Slider::new(&mut self.width, 2..=8));
       -                ui.end_row();
       +        egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       +            });
       +            ui.add(egui::Slider::new(&mut self.width, 2..=8));
       +            ui.end_row();
        
       -                ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                    ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
       -                });
       -                ui.add(egui::Slider::new(&mut self.height, 2..=19));
       -                ui.end_row();
       +            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
                    });
       +            ui.add(egui::Slider::new(&mut self.height, 2..=19));
       +            ui.end_row();
       +        });
            }
        }
        
       @@ -398,10 +371,7 @@ impl Template for TdfFontTemplate {
        
            fn title(&self) -> String {
                match self.font_type {
       -            FontType::Outline => fl!(
       -                crate::LANGUAGE_LOADER,
       -                "new-file-template-outline_font-title"
       -            ),
       +            FontType::Outline => fl!(crate::LANGUAGE_LOADER, "new-file-template-outline_font-title"),
                    FontType::Block => fl!(crate::LANGUAGE_LOADER, "new-file-template-block_font-title"),
                    FontType::Color => fl!(crate::LANGUAGE_LOADER, "new-file-template-color_font-title"),
                }
       @@ -409,18 +379,9 @@ impl Template for TdfFontTemplate {
        
            fn description(&self) -> String {
                match self.font_type {
       -            FontType::Outline => fl!(
       -                crate::LANGUAGE_LOADER,
       -                "new-file-template-outline_font-description"
       -            ),
       -            FontType::Block => fl!(
       -                crate::LANGUAGE_LOADER,
       -                "new-file-template-block_font-description"
       -            ),
       -            FontType::Color => fl!(
       -                crate::LANGUAGE_LOADER,
       -                "new-file-template-color_font-description"
       -            ),
       +            FontType::Outline => fl!(crate::LANGUAGE_LOADER, "new-file-template-outline_font-description"),
       +            FontType::Block => fl!(crate::LANGUAGE_LOADER, "new-file-template-block_font-description"),
       +            FontType::Color => fl!(crate::LANGUAGE_LOADER, "new-file-template-color_font-description"),
                }
            }
        
       @@ -433,10 +394,7 @@ impl Template for TdfFontTemplate {
            }
        
            fn show_ui(&mut self, ui: &mut Ui) {
       -        ui.label(fl!(
       -            crate::LANGUAGE_LOADER,
       -            "new-file-template-thedraw-ui-label"
       -        ));
       +        ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-template-thedraw-ui-label"));
                ui.hyperlink("http://www.roysac.com/thedrawfonts-tdf.html");
            }
        }
       @@ -444,44 +402,17 @@ impl Template for TdfFontTemplate {
        impl Default for NewFileDialog {
            fn default() -> Self {
                let templates: Vec<Box<dyn Template>> = vec![
       -            Box::new(AnsiTemplate {
       -                width: 80,
       -                height: 25,
       -            }),
       -            Box::new(XB16Template {
       -                width: 80,
       -                height: 25,
       -            }),
       -            Box::new(Dos16Template {
       -                width: 80,
       -                height: 25,
       -            }),
       -            Box::new(Ice16Template {
       -                width: 80,
       -                height: 25,
       -            }),
       -            Box::new(XBExtTemplate {
       -                width: 80,
       -                height: 25,
       -            }),
       -            Box::new(FileIdTemplate {
       -                width: 44,
       -                height: 25,
       -            }),
       +            Box::new(AnsiTemplate { width: 80, height: 25 }),
       +            Box::new(XB16Template { width: 80, height: 25 }),
       +            Box::new(Dos16Template { width: 80, height: 25 }),
       +            Box::new(Ice16Template { width: 80, height: 25 }),
       +            Box::new(XBExtTemplate { width: 80, height: 25 }),
       +            Box::new(FileIdTemplate { width: 44, height: 25 }),
                    Box::new(AnsiMationTemplate {}),
       -            Box::new(BitFontTemplate {
       -                width: 8,
       -                height: 16,
       -            }),
       -            Box::new(TdfFontTemplate {
       -                font_type: FontType::Color,
       -            }),
       -            Box::new(TdfFontTemplate {
       -                font_type: FontType::Block,
       -            }),
       -            Box::new(TdfFontTemplate {
       -                font_type: FontType::Outline,
       -            }),
       +            Box::new(BitFontTemplate { width: 8, height: 16 }),
       +            Box::new(TdfFontTemplate { font_type: FontType::Color }),
       +            Box::new(TdfFontTemplate { font_type: FontType::Block }),
       +            Box::new(TdfFontTemplate { font_type: FontType::Outline }),
                ];
        
                Self {
       @@ -509,99 +440,62 @@ impl crate::ModalDialog for NewFileDialog {
                            .resizable(false)
                            .show_inside(ui, |ui| {
                                let row_height = 58.0;
       -                        egui::ScrollArea::vertical()
       -                            .id_source("bitfont_scroll_area")
       -                            .show(ui, |ui| {
       -                                for (i, template) in self.templates.iter().enumerate() {
       -                                    let is_selected = i == self.selected;
       -
       -                                    let (id, rect) = ui
       -                                        .allocate_space([ui.available_width(), row_height].into());
       -                                    let response = ui.interact(rect, id, Sense::click());
       -                                    if response.hovered() {
       -                                        ui.painter().rect_filled(
       -                                            rect.expand(1.0),
       -                                            Rounding::same(4.0),
       -                                            ui.style().visuals.widgets.active.bg_fill,
       -                                        );
       -                                    } else if is_selected {
       -                                        ui.painter().rect_filled(
       -                                            rect.expand(1.0),
       -                                            Rounding::same(4.0),
       -                                            ui.style().visuals.extreme_bg_color,
       -                                        );
       -                                    }
       -                                    let image = template.image();
       -
       -                                    let r = Rect::from_min_size(
       -                                        Pos2::new(
       -                                            (rect.left() + 4.0).floor(),
       -                                            (rect.top() + 4.0).floor(),
       -                                        ),
       -                                        Vec2::new(32.0, 32.0),
       -                                    );
       -
       -                                    ui.painter().image(
       -                                        image.texture_id(ui.ctx()),
       -                                        r,
       -                                        Rect::from_min_max(
       -                                            Pos2::new(0.0, 0.0),
       -                                            Pos2::new(1.0, 1.0),
       -                                        ),
       -                                        Color32::WHITE,
       -                                    );
       -
       -                                    let font_id =
       -                                        FontId::new(20.0, eframe::epaint::FontFamily::Proportional);
       -                                    let text: WidgetText = template.title().into();
       -                                    let galley =
       -                                        text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       -                                    let mut title_rect = rect;
       -                                    title_rect.set_left(title_rect.left() + 40.0);
       -                                    ui.painter().galley_with_color(
       -                                        egui::Align2::LEFT_TOP
       -                                            .align_size_within_rect(
       -                                                galley.size(),
       -                                                title_rect.shrink(4.0),
       -                                            )
       -                                            .min,
       -                                        galley.galley,
       -                                        ui.style().visuals.strong_text_color(),
       -                                    );
       -
       -                                    let font_id =
       -                                        FontId::new(14.0, eframe::epaint::FontFamily::Proportional);
       -                                    let text: WidgetText = template
       -                                        .description()
       -                                        .lines()
       -                                        .next()
       -                                        .unwrap_or_default()
       -                                        .into();
       -                                    let galley =
       -                                        text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       -                                    let mut descr_rect = rect;
       -                                    descr_rect.set_top(descr_rect.top() + 34.0);
       -                                    ui.painter().galley_with_color(
       -                                        egui::Align2::LEFT_TOP
       -                                            .align_size_within_rect(
       -                                                galley.size(),
       -                                                descr_rect.shrink(4.0),
       -                                            )
       -                                            .min,
       -                                        galley.galley,
       -                                        ui.style().visuals.text_color(),
       -                                    );
       -
       -                                    if response.clicked() {
       -                                        self.selected = i;
       -                                    }
       -                                    if response.double_clicked() {
       -                                        self.selected = i;
       -                                        self.create = true;
       -                                        result = true;
       -                                    }
       +                        egui::ScrollArea::vertical().id_source("bitfont_scroll_area").show(ui, |ui| {
       +                            for (i, template) in self.templates.iter().enumerate() {
       +                                let is_selected = i == self.selected;
       +
       +                                let (id, rect) = ui.allocate_space([ui.available_width(), row_height].into());
       +                                let response = ui.interact(rect, id, Sense::click());
       +                                if response.hovered() {
       +                                    ui.painter()
       +                                        .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +                                } else if is_selected {
       +                                    ui.painter()
       +                                        .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
       +                                }
       +                                let image = template.image();
       +
       +                                let r = Rect::from_min_size(Pos2::new((rect.left() + 4.0).floor(), (rect.top() + 4.0).floor()), Vec2::new(32.0, 32.0));
       +
       +                                ui.painter().image(
       +                                    image.texture_id(ui.ctx()),
       +                                    r,
       +                                    Rect::from_min_max(Pos2::new(0.0, 0.0), Pos2::new(1.0, 1.0)),
       +                                    Color32::WHITE,
       +                                );
       +
       +                                let font_id = FontId::new(20.0, eframe::epaint::FontFamily::Proportional);
       +                                let text: WidgetText = template.title().into();
       +                                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       +                                let mut title_rect = rect;
       +                                title_rect.set_left(title_rect.left() + 40.0);
       +                                ui.painter().galley_with_color(
       +                                    egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), title_rect.shrink(4.0)).min,
       +                                    galley.galley,
       +                                    ui.style().visuals.strong_text_color(),
       +                                );
       +
       +                                let font_id = FontId::new(14.0, eframe::epaint::FontFamily::Proportional);
       +                                let text: WidgetText = template.description().lines().next().unwrap_or_default().into();
       +                                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
       +                                let mut descr_rect = rect;
       +                                descr_rect.set_top(descr_rect.top() + 34.0);
       +                                ui.painter().galley_with_color(
       +                                    egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), descr_rect.shrink(4.0)).min,
       +                                    galley.galley,
       +                                    ui.style().visuals.text_color(),
       +                                );
       +
       +                                if response.clicked() {
       +                                    self.selected = i;
       +                                }
       +                                if response.double_clicked() {
       +                                    self.selected = i;
       +                                    self.create = true;
       +                                    result = true;
                                        }
       -                            });
       +                            }
       +                        });
                            });
        
                        egui::CentralPanel::default().show_inside(ui, |ui| {
       @@ -613,17 +507,11 @@ impl crate::ModalDialog for NewFileDialog {
                    ui.separator();
                    ui.add_space(4.0);
                    ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-create"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-create")).clicked() {
                            self.create = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/resize_layer_dialog.rs b/src/ui/dialogs/resize_layer_dialog.rs
       @@ -35,45 +35,36 @@ impl ModalDialog for ResizeLayerDialog {
                    modal.title(ui, fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-title"));
        
                    modal.frame(ui, |ui| {
       -                egui::Grid::new("some_unique_id")
       -                    .num_columns(2)
       -                    .spacing([4.0, 8.0])
       -                    .show(ui, |ui| {
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-width-label"));
       -                        });
       -                        let mut tmp_str = self.width.to_string();
       -                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -                        if let Ok(new_width) = tmp_str.parse::<i32>() {
       -                            self.width = new_width;
       -                        }
       -                        ui.end_row();
       +                egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-width-label"));
       +                    });
       +                    let mut tmp_str = self.width.to_string();
       +                    ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +                    if let Ok(new_width) = tmp_str.parse::<i32>() {
       +                        self.width = new_width;
       +                    }
       +                    ui.end_row();
        
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-height-label"));
       -                        });
       -                        let mut tmp_str = self.height.to_string();
       -                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -                        if let Ok(new_height) = tmp_str.parse::<i32>() {
       -                            self.height = new_height;
       -                        }
       -                        ui.end_row();
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-height-label"));
                            });
       +                    let mut tmp_str = self.height.to_string();
       +                    ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +                    if let Ok(new_height) = tmp_str.parse::<i32>() {
       +                        self.height = new_height;
       +                    }
       +                    ui.end_row();
       +                });
                        ui.add_space(4.0);
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-resize"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-resize")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/select_character_dialog.rs b/src/ui/dialogs/select_character_dialog.rs
       @@ -41,10 +41,7 @@ impl ModalDialog for SelectCharacterDialog {
                    //   ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
                    modal.frame(ui, |ui| {
                        if let Some(font) = self.buf.lock().get_buffer().get_font(font_page) {
       -                    let (_id, stroke_rect) = ui.allocate_space(Vec2::new(
       -                        scale * font.size.width as f32,
       -                        scale * font.size.height as f32,
       -                    ));
       +                    let (_id, stroke_rect) = ui.allocate_space(Vec2::new(scale * font.size.width as f32, scale * font.size.height as f32));
                            let painter = ui.painter_at(stroke_rect);
                            painter.rect_filled(stroke_rect, Rounding::none(), Color32::BLACK);
                            let s = font.size;
       @@ -57,10 +54,7 @@ impl ModalDialog for SelectCharacterDialog {
                                        if glyph.data[y as usize] & (128 >> x) != 0 {
                                            painter.rect_filled(
                                                Rect::from_min_size(
       -                                            egui::Pos2::new(
       -                                                stroke_rect.left() + x as f32 * scale,
       -                                                stroke_rect.top() + y as f32 * scale,
       -                                            ),
       +                                            egui::Pos2::new(stroke_rect.left() + x as f32 * scale, stroke_rect.top() + y as f32 * scale),
                                                    Vec2::new(scale, scale),
                                                ),
                                                Rounding::none(),
       @@ -75,20 +69,13 @@ impl ModalDialog for SelectCharacterDialog {
        
                    ui.horizontal(|ui| {
                        ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-char-label")).small());
       -                ui.label(
       -                    RichText::new(format!("{0}/0x{0:02X}", self.selected_ch as i32))
       -                        .small()
       -                        .color(Color32::WHITE),
       -                );
       +                ui.label(RichText::new(format!("{0}/0x{0:02X}", self.selected_ch as i32)).small().color(Color32::WHITE));
                    });
                    let scale = 2.;
        
                    modal.frame(ui, |ui| {
                        if let Some(font) = self.buf.lock().get_buffer().get_font(font_page) {
       -                    let (_id, stroke_rect) = ui.allocate_space(Vec2::new(
       -                        scale * font.size.width as f32 * 256. / 8.,
       -                        scale * font.size.height as f32 * 8.,
       -                    ));
       +                    let (_id, stroke_rect) = ui.allocate_space(Vec2::new(scale * font.size.width as f32 * 256. / 8., scale * font.size.height as f32 * 8.));
        
                            let painter = ui.painter_at(stroke_rect);
                            painter.rect_filled(stroke_rect, Rounding::none(), Color32::BLACK);
       @@ -98,20 +85,12 @@ impl ModalDialog for SelectCharacterDialog {
        
                            if let Some(hover_pos) = ui.input(|i| i.pointer.hover_pos()) {
                                if stroke_rect.contains(hover_pos) {
       -                            let char_x = ((hover_pos.x - stroke_rect.left())
       -                                / scale
       -                                / font.size.width as f32)
       -                                as i32;
       -                            let char_y = ((hover_pos.y - stroke_rect.top())
       -                                / scale
       -                                / font.size.height as f32)
       -                                as i32;
       +                            let char_x = ((hover_pos.x - stroke_rect.left()) / scale / font.size.width as f32) as i32;
       +                            let char_y = ((hover_pos.y - stroke_rect.top()) / scale / font.size.height as f32) as i32;
                                    hovered_char = char_x + 32 * char_y;
                                }
                            }
       -                    if hovered_char > 0
       -                        && ui.input(|i| i.pointer.button_pressed(egui::PointerButton::Primary))
       -                    {
       +                    if hovered_char > 0 && ui.input(|i| i.pointer.button_pressed(egui::PointerButton::Primary)) {
                                self.selected_ch = unsafe { char::from_u32_unchecked(hovered_char as u32) };
                            }
        
       @@ -134,10 +113,7 @@ impl ModalDialog for SelectCharacterDialog {
                                            if glyph.data[y as usize] & (128 >> x) != 0 {
                                                painter.rect_filled(
                                                    Rect::from_min_size(
       -                                                egui::Pos2::new(
       -                                                    xs + stroke_rect.left() + x as f32 * scale,
       -                                                    ys + stroke_rect.top() + y as f32 * scale,
       -                                                ),
       +                                                egui::Pos2::new(xs + stroke_rect.left() + x as f32 * scale, ys + stroke_rect.top() + y as f32 * scale),
                                                        Vec2::new(scale, scale),
                                                    ),
                                                    Rounding::none(),
       @@ -149,37 +125,20 @@ impl ModalDialog for SelectCharacterDialog {
                                }
                            }
        
       -                    let xs =
       -                        ((self.selected_ch as i32 % 32) as f32) * scale * font.size.width as f32;
       -                    let ys =
       -                        ((self.selected_ch as i32 / 32) as f32) * scale * font.size.height as f32;
       +                    let xs = ((self.selected_ch as i32 % 32) as f32) * scale * font.size.width as f32;
       +                    let ys = ((self.selected_ch as i32 / 32) as f32) * scale * font.size.height as f32;
        
                            let selected_rect = Rect::from_min_size(
                                egui::Pos2::new(stroke_rect.left() + xs, stroke_rect.top() + ys),
       -                        Vec2::new(
       -                            scale * font.size.width as f32,
       -                            scale * font.size.height as f32,
       -                        ),
       +                        Vec2::new(scale * font.size.width as f32, scale * font.size.height as f32),
                            );
        
       -                    painter.rect(
       -                        selected_rect,
       -                        Rounding::none(),
       -                        Color32::TRANSPARENT,
       -                        (2.0, Color32::LIGHT_BLUE),
       -                    );
       +                    painter.rect(selected_rect, Rounding::none(), Color32::TRANSPARENT, (2.0, Color32::LIGHT_BLUE));
        
                            ui.horizontal(|ui| {
                                if hovered_char >= 0 {
       -                            ui.label(
       -                                RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-char-label"))
       -                                    .small(),
       -                            );
       -                            ui.label(
       -                                RichText::new(format!("{0}/0x{0:02X}", hovered_char))
       -                                    .small()
       -                                    .color(Color32::WHITE),
       -                            );
       +                            ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "glyph-char-label")).small());
       +                            ui.label(RichText::new(format!("{0}/0x{0:02X}", hovered_char)).small().color(Color32::WHITE));
                                } else {
                                    ui.label("");
                                }
       @@ -188,17 +147,11 @@ impl ModalDialog for SelectCharacterDialog {
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/select_outline_dialog.rs b/src/ui/dialogs/select_outline_dialog.rs
       @@ -56,10 +56,7 @@ impl SelectOutlineDialog {
                        if ui.input(|i| i.pointer.primary_clicked()) {
                            self.selected_outline = outline_style;
                        }
       -                if ui.input(|i| {
       -                    i.pointer
       -                        .button_double_clicked(egui::PointerButton::Primary)
       -                }) {
       +                if ui.input(|i| i.pointer.button_double_clicked(egui::PointerButton::Primary)) {
                            self.selected_outline = outline_style;
                            self.should_commit = true;
                        }
       @@ -70,10 +67,7 @@ impl SelectOutlineDialog {
        
                for h in 0..OUTLINE_HEIGHT {
                    for w in 0..OUTLINE_WIDTH {
       -                let ch = TheDrawFont::transform_outline(
       -                    outline_style,
       -                    OUTLINE_FONT_CHAR[w + h * OUTLINE_WIDTH],
       -                );
       +                let ch = TheDrawFont::transform_outline(outline_style, OUTLINE_FONT_CHAR[w + h * OUTLINE_WIDTH]);
                        let ch = unsafe { char::from_u32_unchecked(ch as u32) };
        
                        let xs = w as f32 * scale * self.font.size.width as f32;
       @@ -121,8 +115,8 @@ impl SelectOutlineDialog {
        const OUTLINE_WIDTH: usize = 8;
        const OUTLINE_HEIGHT: usize = 6;
        const OUTLINE_FONT_CHAR: [u8; 48] = [
       -    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, 68, 75, 66, 76, 64, 64, 75, 66, 76,
       +    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,
       +    68, 75, 66, 76, 64, 64, 75, 66, 76,
        ];
        
        impl ModalDialog for SelectOutlineDialog {
       @@ -131,10 +125,7 @@ impl ModalDialog for SelectOutlineDialog {
                let modal = Modal::new(ctx, "select_outline_dialog");
        
                modal.show(|ui| {
       -            modal.title(
       -                ui,
       -                fl!(crate::LANGUAGE_LOADER, "select-outline-style-title"),
       -            );
       +            modal.title(ui, fl!(crate::LANGUAGE_LOADER, "select-outline-style-title"));
        
                    modal.frame(ui, |ui| {
                        ui.add_space(8.0);
       @@ -142,17 +133,11 @@ impl ModalDialog for SelectOutlineDialog {
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
   DIR diff --git a/src/ui/dialogs/select_palette_dialog.rs b/src/ui/dialogs/select_palette_dialog.rs
       @@ -7,10 +7,7 @@ use eframe::{
        use egui_file::FileDialog;
        use egui_modal::Modal;
        use i18n_embed_fl::fl;
       -use icy_engine::{
       -    Palette, PaletteFormat, PaletteMode, C64_DEFAULT_PALETTE, DOS_DEFAULT_PALETTE, EGA_PALETTE,
       -    VIEWDATA_PALETTE, XTERM_256_PALETTE,
       -};
       +use icy_engine::{Palette, PaletteFormat, PaletteMode, C64_DEFAULT_PALETTE, DOS_DEFAULT_PALETTE, EGA_PALETTE, VIEWDATA_PALETTE, XTERM_256_PALETTE};
        use walkdir::WalkDir;
        
        use crate::{to_message, AnsiEditor, Message, Settings, TerminalResult};
       @@ -42,45 +39,27 @@ impl SelectPaletteDialog {
                let mode = editor.buffer_view.lock().get_buffer().palette_mode;
        
                let mut dos = Palette::from_colors(DOS_DEFAULT_PALETTE.to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-dos_default_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-dos_default_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut dos = Palette::from_colors(DOS_DEFAULT_PALETTE[0..8].to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-dos_default_low_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-dos_default_low_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut dos = Palette::from_colors(C64_DEFAULT_PALETTE.to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-c64_default_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-c64_default_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut dos = Palette::from_colors(EGA_PALETTE.to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-ega_default_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-ega_default_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut dos = Palette::from_colors(XTERM_256_PALETTE.map(|p| p.1).to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-xterm_default_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-xterm_default_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut dos = Palette::from_colors(VIEWDATA_PALETTE[0..8].to_vec());
       -        dos.title = fl!(
       -            crate::LANGUAGE_LOADER,
       -            "palette_selector-viewdata_default_palette"
       -        );
       +        dos.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-viewdata_default_palette");
                add_palette(&mut palettes, mode, (dos, PaletteSource::BuiltIn));
        
                let mut pal = editor.buffer_view.lock().get_buffer().palette.clone();
       @@ -89,10 +68,7 @@ impl SelectPaletteDialog {
                    selected_palette = idx as i32;
                } else {
                    if pal.title.is_empty() {
       -                pal.title = fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "palette_selector-extracted_from_buffer_default_label"
       -                );
       +                pal.title = fl!(crate::LANGUAGE_LOADER, "palette_selector-extracted_from_buffer_default_label");
                    }
                    palettes.insert(0, (pal, PaletteSource::File));
                }
       @@ -115,10 +91,7 @@ impl SelectPaletteDialog {
                })
            }
        
       -    fn load_palettes(
       -        tdf_dir: &Path,
       -        mode: PaletteMode,
       -    ) -> anyhow::Result<Vec<(Palette, PaletteSource)>> {
       +    fn load_palettes(tdf_dir: &Path, mode: PaletteMode) -> anyhow::Result<Vec<(Palette, PaletteSource)>> {
                let mut palettes = Vec::new();
                let walker = WalkDir::new(tdf_dir).into_iter();
                for entry in walker.filter_entry(|e| !crate::model::font_imp::FontTool::is_hidden(e)) {
       @@ -163,11 +136,7 @@ impl SelectPaletteDialog {
                Ok(palettes)
            }
        
       -    fn read_zip_archive(
       -        data: Vec<u8>,
       -        palettes: &mut Vec<(Palette, PaletteSource)>,
       -        mode: PaletteMode,
       -    ) {
       +    fn read_zip_archive(data: Vec<u8>, palettes: &mut Vec<(Palette, PaletteSource)>, mode: PaletteMode) {
                let file = std::io::Cursor::new(data);
                match zip::ZipArchive::new(file) {
                    Ok(mut archive) => {
       @@ -176,16 +145,13 @@ impl SelectPaletteDialog {
                                Ok(mut file) => {
                                    if let Some(name) = file.enclosed_name() {
                                        let file_name_buf = name.to_path_buf();
       -                                let file_name =
       -                                    file_name_buf.to_string_lossy().to_ascii_lowercase();
       +                                let file_name = file_name_buf.to_string_lossy().to_ascii_lowercase();
                                        let mut data = Vec::new();
                                        file.read_to_end(&mut data).unwrap_or_default();
        
                                        if file_name.ends_with(".zip") {
                                            SelectPaletteDialog::read_zip_archive(data, palettes, mode);
       -                                } else if let Ok(palette) =
       -                                    Palette::import_palette(&file_name_buf, &data)
       -                                {
       +                                } else if let Ok(palette) = Palette::import_palette(&file_name_buf, &data) {
                                            add_palette(palettes, mode, (palette, PaletteSource::Library));
                                        }
                                    }
       @@ -202,29 +168,17 @@ impl SelectPaletteDialog {
                }
            }
        
       -    pub fn draw_palette_row(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_pal: usize,
       -        row_height: f32,
       -        is_selected: bool,
       -    ) -> Response {
       +    pub fn draw_palette_row(&mut self, ui: &mut egui::Ui, cur_pal: usize, row_height: f32, is_selected: bool) -> Response {
                let palette = &self.palettes[cur_pal];
                let (id, rect) = ui.allocate_space([ui.available_width(), row_height].into());
                let response = ui.interact(rect, id, Sense::click());
        
                if response.hovered() {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.widgets.active.bg_fill,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
                } else if is_selected {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.extreme_bg_color,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
                }
        
                let text_color = if is_selected {
       @@ -237,9 +191,7 @@ impl SelectPaletteDialog {
                let text: WidgetText = palette.0.title.clone().into();
                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
                ui.painter().galley_with_color(
       -            egui::Align2::LEFT_TOP
       -                .align_size_within_rect(galley.size(), rect.shrink(4.0))
       -                .min,
       +            egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), rect.shrink(4.0)).min,
                    galley.galley,
                    text_color,
                );
       @@ -259,23 +211,16 @@ impl SelectPaletteDialog {
                for i in 0..palette.0.len() {
                    let (r, g, b) = palette.0.get_rgb(i);
                    let rect = Rect::from_min_size(
       -                Pos2::new(
       -                    color_rect.left() + (i % num_colors) as f32 * w,
       -                    color_rect.top() + (i / num_colors) as f32 * h,
       -                ),
       +                Pos2::new(color_rect.left() + (i % num_colors) as f32 * w, color_rect.top() + (i / num_colors) as f32 * h),
                        Vec2::new(w, h),
                    );
       -            ui.painter()
       -                .rect_filled(rect, Rounding::none(), Color32::from_rgb(r, g, b))
       +            ui.painter().rect_filled(rect, Rounding::none(), Color32::from_rgb(r, g, b))
                }
        
                // paint palette tag
                let font_type = match palette.1 {
                    PaletteSource::BuiltIn => {
       -                fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "select-palette-dialog-builtin_palette"
       -                )
       +                fl!(crate::LANGUAGE_LOADER, "select-palette-dialog-builtin_palette")
                    }
                    PaletteSource::Library => {
                        fl!(crate::LANGUAGE_LOADER, "font_selector-library_font")
       @@ -290,25 +235,16 @@ impl SelectPaletteDialog {
                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
        
                let rect = Rect::from_min_size(
       -            Pos2::new(
       -                (rect.right() - galley.size().x - 10.0).floor(),
       -                (rect.top() + 8.0).floor(),
       -            ),
       +            Pos2::new((rect.right() - galley.size().x - 10.0).floor(), (rect.top() + 8.0).floor()),
                    galley.size(),
                );
       -        ui.painter().rect_filled(
       -            rect.expand(2.0),
       -            Rounding::same(4.0),
       -            ui.style().visuals.widgets.active.bg_fill,
       -        );
       -
                ui.painter()
       -            .rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
       +            .rect_filled(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +
       +        ui.painter().rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
        
                ui.painter().galley_with_color(
       -            egui::Align2::CENTER_CENTER
       -                .align_size_within_rect(galley.size(), rect)
       -                .min,
       +            egui::Align2::CENTER_CENTER.align_size_within_rect(galley.size(), rect).min,
                    galley.galley,
                    text_color,
                );
       @@ -323,11 +259,7 @@ impl SelectPaletteDialog {
            }
        }
        
       -fn add_palette(
       -    palettes: &mut Vec<(Palette, PaletteSource)>,
       -    mode: icy_engine::PaletteMode,
       -    mut palette: (Palette, PaletteSource),
       -) {
       +fn add_palette(palettes: &mut Vec<(Palette, PaletteSource)>, mode: icy_engine::PaletteMode, mut palette: (Palette, PaletteSource)) {
            match mode {
                icy_engine::PaletteMode::RGB => {}
                icy_engine::PaletteMode::Free16 | icy_engine::PaletteMode::Fixed16 => palette.0.resize(16),
       @@ -360,44 +292,25 @@ impl crate::ModalDialog for SelectPaletteDialog {
                let modal = Modal::new(ctx, "select_font_dialog2");
                let palette_count = self.palettes.len();
                modal.show(|ui| {
       -            modal.title(
       -                ui,
       -                fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "select-palette-dialog-title",
       -                    count = palette_count
       -                ),
       -            );
       +            modal.title(ui, fl!(crate::LANGUAGE_LOADER, "select-palette-dialog-title", count = palette_count));
                    modal.frame(ui, |ui| {
                        let row_height = 200.0 / 2.0;
                        ui.horizontal(|ui: &mut egui::Ui| {
                            ui.add_sized(
                                [250.0, 20.0],
       -                        TextEdit::singleline(&mut self.filter).hint_text(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-filter-text"
       -                        )),
       +                        TextEdit::singleline(&mut self.filter).hint_text(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-filter-text")),
                            );
                            let response = ui.button("🗙");
                            if response.clicked() {
                                self.filter.clear();
                            }
        
       -                    let response = ui.selectable_label(
       -                        self.show_library,
       -                        fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"),
       -                    );
       +                    let response = ui.selectable_label(self.show_library, fl!(crate::LANGUAGE_LOADER, "font_selector-library_font"));
                            if response.clicked() {
                                self.show_library = !self.show_library;
                            }
        
       -                    let response = ui.selectable_label(
       -                        self.show_builtin,
       -                        fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-palette-dialog-builtin_palette"
       -                        ),
       -                    );
       +                    let response = ui.selectable_label(self.show_builtin, fl!(crate::LANGUAGE_LOADER, "select-palette-dialog-builtin_palette"));
                            if response.clicked() {
                                self.show_builtin = !self.show_builtin;
                            }
       @@ -414,43 +327,23 @@ impl crate::ModalDialog for SelectPaletteDialog {
                                PaletteSource::File => self.show_file,
                            };
        
       -                    if palette
       -                        .0
       -                        .title
       -                        .to_lowercase()
       -                        .contains(&self.filter.to_lowercase())
       -                        && match_filter
       -                    {
       +                    if palette.0.title.to_lowercase().contains(&self.filter.to_lowercase()) && match_filter {
                                filtered_fonts.push(i);
                            }
                        }
                        if filtered_fonts.is_empty() {
                            if palette_count == 0 {
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-no-fonts-installed"
       -                        ));
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-no-fonts-installed"));
                            } else {
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-palette-dialog-no-matching-palettes"
       -                        ));
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "select-palette-dialog-no-matching-palettes"));
                            }
                        } else {
       -                    egui::ScrollArea::vertical().max_height(300.).show_rows(
       -                        ui,
       -                        row_height,
       -                        filtered_fonts.len(),
       -                        |ui, range| {
       +                    egui::ScrollArea::vertical()
       +                        .max_height(300.)
       +                        .show_rows(ui, row_height, filtered_fonts.len(), |ui, range| {
                                    for row in range {
       -                                let is_selected =
       -                                    self.selected_palette == filtered_fonts[row] as i32;
       -                                let response = self.draw_palette_row(
       -                                    ui,
       -                                    filtered_fonts[row],
       -                                    row_height,
       -                                    is_selected,
       -                                );
       +                                let is_selected = self.selected_palette == filtered_fonts[row] as i32;
       +                                let response = self.draw_palette_row(ui, filtered_fonts[row], row_height, is_selected);
        
                                        if response.clicked() {
                                            self.selected_palette = filtered_fonts[row] as i32;
       @@ -461,30 +354,20 @@ impl crate::ModalDialog for SelectPaletteDialog {
                                            result = true;
                                        }
                                    }
       -                        },
       -                    );
       +                        });
                        }
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-select"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-select")).clicked() {
                            self.do_select = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
        
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "export-button-title"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "export-button-title")).clicked() {
                            let mut initial_path = None;
                            crate::set_default_initial_directory_opt(&mut initial_path);
                            let mut dialog = FileDialog::save_file(initial_path);
       @@ -503,13 +386,7 @@ impl crate::ModalDialog for SelectPaletteDialog {
        
            fn commit(&self, editor: &mut AnsiEditor) -> TerminalResult<Option<Message>> {
                if let Some((palette, _)) = self.palettes.get(self.selected_palette as usize) {
       -            Ok(to_message(
       -                editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .switch_to_palette(palette.clone()),
       -            ))
       +            Ok(to_message(editor.buffer_view.lock().get_edit_state_mut().switch_to_palette(palette.clone())))
                } else {
                    Ok(None)
                }
   DIR diff --git a/src/ui/dialogs/select_tdf_font_dialog.rs b/src/ui/dialogs/select_tdf_font_dialog.rs
       @@ -5,9 +5,7 @@ use std::{
        
        use eframe::{
            egui::{self, Response, Sense, TextEdit, TextStyle, WidgetText},
       -    epaint::{
       -        ahash::HashMap, Color32, ColorImage, FontFamily, FontId, Pos2, Rect, Rounding, Stroke, Vec2,
       -    },
       +    epaint::{ahash::HashMap, Color32, ColorImage, FontFamily, FontId, Pos2, Rect, Rounding, Stroke, Vec2},
        };
        use egui_extras::RetainedImage;
        use egui_file::FileDialog;
       @@ -52,28 +50,16 @@ impl SelectFontDialog {
                }
            }
        
       -    pub fn draw_font_row(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_font: usize,
       -        row_height: f32,
       -        is_selected: bool,
       -    ) -> Response {
       +    pub fn draw_font_row(&mut self, ui: &mut egui::Ui, cur_font: usize, row_height: f32, is_selected: bool) -> Response {
                let font = &self.fonts.lock().unwrap()[cur_font];
                let (id, rect) = ui.allocate_space([ui.available_width(), row_height].into());
                let response = ui.interact(rect, id, Sense::click());
                if response.hovered() {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.widgets.active.bg_fill,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
                } else if is_selected {
       -            ui.painter().rect_filled(
       -                rect.expand(1.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.extreme_bg_color,
       -            );
       +            ui.painter()
       +                .rect_filled(rect.expand(1.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
                }
        
                let text_color = if is_selected {
       @@ -86,9 +72,7 @@ impl SelectFontDialog {
                let text: WidgetText = font.name.clone().into();
                let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
                ui.painter().galley_with_color(
       -            egui::Align2::LEFT_TOP
       -                .align_size_within_rect(galley.size(), rect.shrink(4.0))
       -                .min,
       +            egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), rect.shrink(4.0)).min,
                    galley.galley,
                    text_color,
                );
       @@ -117,13 +101,8 @@ impl SelectFontDialog {
                        x = 0.;
                        cnt = 0;
                    }
       -            ui.painter().galley_with_color(
       -                egui::Align2::LEFT_TOP
       -                    .align_size_within_rect(galley.size(), rect)
       -                    .min,
       -                galley.galley,
       -                color,
       -            );
       +            ui.painter()
       +                .galley_with_color(egui::Align2::LEFT_TOP.align_size_within_rect(galley.size(), rect).min, galley.galley, color);
                }
        
                #[allow(clippy::map_entry)]
       @@ -155,10 +134,7 @@ impl SelectFontDialog {
                    let w = (image.width() as f32 / 2.0).floor();
                    let h = (image.height() as f32 / 2.0).floor();
                    let r = Rect::from_min_size(
       -                Pos2::new(
       -                    (rect.right() - w - 4.0).floor(),
       -                    (rect.top() + ((rect.height() - h) / 2.0)).floor(),
       -                ),
       +                Pos2::new((rect.right() - w - 4.0).floor(), (rect.top() + ((rect.height() - h) / 2.0)).floor()),
                        Vec2::new(w, h),
                    );
                    ui.painter().image(
       @@ -185,26 +161,17 @@ impl SelectFontDialog {
                    let galley = text.into_galley(ui, Some(false), f32::INFINITY, font_id);
        
                    let rect = Rect::from_min_size(
       -                Pos2::new(
       -                    (rect.right() - galley.size().x - 10.0).floor(),
       -                    (rect.top() + 8.0).floor(),
       -                ),
       +                Pos2::new((rect.right() - galley.size().x - 10.0).floor(), (rect.top() + 8.0).floor()),
                        galley.size(),
                    );
        
       -            ui.painter().rect_filled(
       -                rect.expand(2.0),
       -                Rounding::same(4.0),
       -                ui.style().visuals.widgets.active.bg_fill,
       -            );
       -
                    ui.painter()
       -                .rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
       +                .rect_filled(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +
       +            ui.painter().rect_stroke(rect.expand(2.0), 4.0, Stroke::new(1.0, text_color));
        
                    ui.painter().galley_with_color(
       -                egui::Align2::CENTER_CENTER
       -                    .align_size_within_rect(galley.size(), rect)
       -                    .min,
       +                egui::Align2::CENTER_CENTER.align_size_within_rect(galley.size(), rect).min,
                        galley.galley,
                        text_color,
                    );
       @@ -236,49 +203,30 @@ impl crate::ModalDialog for SelectFontDialog {
                let font_count = self.fonts.lock().unwrap().len();
                modal.show(|ui| {
                    ui.set_width(700.);
       -            modal.title(
       -                ui,
       -                fl!(
       -                    crate::LANGUAGE_LOADER,
       -                    "select-font-dialog-title",
       -                    fontcount = font_count
       -                ),
       -            );
       +            modal.title(ui, fl!(crate::LANGUAGE_LOADER, "select-font-dialog-title", fontcount = font_count));
                    modal.frame(ui, |ui| {
                        let row_height = 200.0 / 2.0;
                        ui.horizontal(|ui: &mut egui::Ui| {
                            ui.add_sized(
                                [250.0, 20.0],
       -                        TextEdit::singleline(&mut self.filter).hint_text(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-filter-text"
       -                        )),
       +                        TextEdit::singleline(&mut self.filter).hint_text(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-filter-text")),
                            );
                            let response = ui.button("🗙");
                            if response.clicked() {
                                self.filter.clear();
                            }
        
       -                    let response = ui.selectable_label(
       -                        self.show_color,
       -                        fl!(crate::LANGUAGE_LOADER, "select-font-dialog-color-font"),
       -                    );
       +                    let response = ui.selectable_label(self.show_color, fl!(crate::LANGUAGE_LOADER, "select-font-dialog-color-font"));
                            if response.clicked() {
                                self.show_color = !self.show_color;
                            }
        
       -                    let response = ui.selectable_label(
       -                        self.show_block,
       -                        fl!(crate::LANGUAGE_LOADER, "select-font-dialog-block-font"),
       -                    );
       +                    let response = ui.selectable_label(self.show_block, fl!(crate::LANGUAGE_LOADER, "select-font-dialog-block-font"));
                            if response.clicked() {
                                self.show_block = !self.show_block;
                            }
        
       -                    let response = ui.selectable_label(
       -                        self.show_outline,
       -                        fl!(crate::LANGUAGE_LOADER, "select-font-dialog-outline-font"),
       -                    );
       +                    let response = ui.selectable_label(self.show_outline, fl!(crate::LANGUAGE_LOADER, "select-font-dialog-outline-font"));
                            if response.clicked() {
                                self.show_outline = !self.show_outline;
                            }
       @@ -289,43 +237,27 @@ impl crate::ModalDialog for SelectFontDialog {
        
                        for i in 0..font_count {
                            let font = &self.fonts.lock().unwrap()[i];
       -                    if font
       -                        .name
       -                        .to_lowercase()
       -                        .contains(&self.filter.to_lowercase())
       -                        && (self.show_outline
       -                            && matches!(font.font_type, icy_engine::FontType::Outline)
       -                            || self.show_block
       -                                && matches!(font.font_type, icy_engine::FontType::Block)
       -                            || self.show_color
       -                                && matches!(font.font_type, icy_engine::FontType::Color))
       +                    if font.name.to_lowercase().contains(&self.filter.to_lowercase())
       +                        && (self.show_outline && matches!(font.font_type, icy_engine::FontType::Outline)
       +                            || self.show_block && matches!(font.font_type, icy_engine::FontType::Block)
       +                            || self.show_color && matches!(font.font_type, icy_engine::FontType::Color))
                            {
                                filtered_fonts.push(i);
                            }
                        }
                        if filtered_fonts.is_empty() {
                            if font_count == 0 {
       -                        ui.label(fl!(
       -                            crate::LANGUAGE_LOADER,
       -                            "select-font-dialog-no-fonts-installed"
       -                        ));
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-no-fonts-installed"));
                            } else {
                                ui.label(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-no-fonts"));
                            }
                        } else {
       -                    egui::ScrollArea::vertical().max_height(300.).show_rows(
       -                        ui,
       -                        row_height,
       -                        filtered_fonts.len(),
       -                        |ui, range| {
       +                    egui::ScrollArea::vertical()
       +                        .max_height(300.)
       +                        .show_rows(ui, row_height, filtered_fonts.len(), |ui, range| {
                                    for row in range {
                                        let is_selected = self.selected_font == filtered_fonts[row] as i32;
       -                                let response = self.draw_font_row(
       -                                    ui,
       -                                    filtered_fonts[row],
       -                                    row_height,
       -                                    is_selected,
       -                                );
       +                                let response = self.draw_font_row(ui, filtered_fonts[row], row_height, is_selected);
        
                                        if response.clicked() {
                                            self.selected_font = filtered_fonts[row] as i32;
       @@ -336,30 +268,20 @@ impl crate::ModalDialog for SelectFontDialog {
                                            result = true;
                                        }
                                    }
       -                        },
       -                    );
       +                        });
                        }
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-select"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "select-font-dialog-select")).clicked() {
                            self.do_select = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
        
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "export-button-title"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "export-button-title")).clicked() {
                            match self.fonts.lock().unwrap()[self.selected_font as usize].as_tdf_bytes() {
                                Ok(data) => {
                                    let mut initial_path = None;
       @@ -391,8 +313,7 @@ impl crate::ModalDialog for SelectFontDialog {
        }
        
        pub fn create_retained_image(buf: &Buffer) -> RetainedImage {
       -    let (size, pixels) =
       -        buf.render_to_rgba(Rectangle::from(0, 0, buf.get_width(), buf.get_height()));
       +    let (size, pixels) = buf.render_to_rgba(Rectangle::from(0, 0, buf.get_width(), buf.get_height()));
            RetainedImage::from_color_image(
                "buf_img",
                ColorImage::from_rgba_premultiplied([size.width as usize, size.height as usize], &pixels),
   DIR diff --git a/src/ui/dialogs/set_canvas_size_dialog.rs b/src/ui/dialogs/set_canvas_size_dialog.rs
       @@ -34,55 +34,40 @@ impl ModalDialog for SetCanvasSizeDialog {
                    modal.title(ui, fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-title"));
        
                    modal.frame(ui, |ui| {
       -                egui::Grid::new("some_unique_id")
       -                    .num_columns(2)
       -                    .spacing([4.0, 8.0])
       -                    .show(ui, |ui| {
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-width-label"));
       -                        });
       -                        let mut tmp_str = self.width.to_string();
       -                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -                        if let Ok(new_width) = tmp_str.parse::<i32>() {
       -                            self.width = new_width;
       -                        }
       -                        ui.end_row();
       -
       -                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-height-label"));
       -                        });
       -                        let mut tmp_str = self.height.to_string();
       -                        ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       -                        if let Ok(new_height) = tmp_str.parse::<i32>() {
       -                            self.height = new_height;
       -                        }
       -                        ui.end_row();
       +                egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-width-label"));
       +                    });
       +                    let mut tmp_str = self.width.to_string();
       +                    ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +                    if let Ok(new_width) = tmp_str.parse::<i32>() {
       +                        self.width = new_width;
       +                    }
       +                    ui.end_row();
        
       -                        ui.label("");
       -                        ui.checkbox(
       -                            &mut self.resize_layer,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "edit-canvas-size-resize_layers-label"
       -                            ),
       -                        );
       -                        ui.end_row();
       +                    ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-height-label"));
                            });
       +                    let mut tmp_str = self.height.to_string();
       +                    ui.add(egui::TextEdit::singleline(&mut tmp_str).char_limit(35));
       +                    if let Ok(new_height) = tmp_str.parse::<i32>() {
       +                        self.height = new_height;
       +                    }
       +                    ui.end_row();
       +
       +                    ui.label("");
       +                    ui.checkbox(&mut self.resize_layer, fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-resize_layers-label"));
       +                    ui.end_row();
       +                });
                        ui.add_space(4.0);
                    });
        
                    modal.buttons(ui, |ui| {
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-resize"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "edit-canvas-size-resize")).clicked() {
                            self.should_commit = true;
                            result = true;
                        }
       -                if ui
       -                    .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                    .clicked()
       -                {
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                            result = true;
                        }
                    });
       @@ -96,10 +81,6 @@ impl ModalDialog for SetCanvasSizeDialog {
            }
        
            fn commit(&self, _editor: &mut AnsiEditor) -> TerminalResult<Option<Message>> {
       -        Ok(Some(Message::ResizeBuffer(
       -            self.resize_layer,
       -            self.width,
       -            self.height,
       -        )))
       +        Ok(Some(Message::ResizeBuffer(self.resize_layer, self.width, self.height)))
            }
        }
   DIR diff --git a/src/ui/dialogs/settings_dialog.rs b/src/ui/dialogs/settings_dialog.rs
       @@ -6,9 +6,7 @@ use eframe::{
        };
        use i18n_embed_fl::fl;
        use icy_engine::{AttributedChar, Buffer, Color, Size, TextAttribute};
       -use icy_engine_egui::{
       -    show_monitor_settings, show_terminal_area, BufferView, MarkerSettings, MonitorSettings,
       -};
       +use icy_engine_egui::{show_monitor_settings, show_terminal_area, BufferView, MarkerSettings, MonitorSettings};
        
        use crate::{CharTableToolWindow, CharacterSet, Commands, SelectOutlineDialog, SETTINGS};
        pub struct SettingsDialog {
       @@ -81,49 +79,34 @@ impl SettingsDialog {
                            let settings_category = self.settings_category;
        
                            if ui
       -                        .selectable_label(
       -                            settings_category == MONITOR_CAT,
       -                            fl!(crate::LANGUAGE_LOADER, "settings-monitor-category"),
       -                        )
       +                        .selectable_label(settings_category == MONITOR_CAT, fl!(crate::LANGUAGE_LOADER, "settings-monitor-category"))
                                .clicked()
                            {
                                self.settings_category = MONITOR_CAT;
                            }
        
                            if ui
       -                        .selectable_label(
       -                            settings_category == MARKER_CAT,
       -                            fl!(crate::LANGUAGE_LOADER, "settings-markers-guides-category"),
       -                        )
       +                        .selectable_label(settings_category == MARKER_CAT, fl!(crate::LANGUAGE_LOADER, "settings-markers-guides-category"))
                                .clicked()
                            {
                                self.settings_category = MARKER_CAT;
                            }
        
                            if ui
       -                        .selectable_label(
       -                            settings_category == OUTLINE_CAT,
       -                            fl!(crate::LANGUAGE_LOADER, "settings-font-outline-category"),
       -                        )
       +                        .selectable_label(settings_category == OUTLINE_CAT, fl!(crate::LANGUAGE_LOADER, "settings-font-outline-category"))
                                .clicked()
                            {
                                self.settings_category = OUTLINE_CAT;
                            }
                            if ui
       -                        .selectable_label(
       -                            settings_category == CHAR_SET_CAT,
       -                            fl!(crate::LANGUAGE_LOADER, "settings-char-set-category"),
       -                        )
       +                        .selectable_label(settings_category == CHAR_SET_CAT, fl!(crate::LANGUAGE_LOADER, "settings-char-set-category"))
                                .clicked()
                            {
                                self.settings_category = CHAR_SET_CAT;
                            }
        
                            if ui
       -                        .selectable_label(
       -                            settings_category == KEYBIND_CAT,
       -                            fl!(crate::LANGUAGE_LOADER, "settings-keybindings-category"),
       -                        )
       +                        .selectable_label(settings_category == KEYBIND_CAT, fl!(crate::LANGUAGE_LOADER, "settings-keybindings-category"))
                                .clicked()
                            {
                                self.settings_category = KEYBIND_CAT;
       @@ -132,18 +115,14 @@ impl SettingsDialog {
                        ui.separator();
                        match self.settings_category {
                            MONITOR_CAT => unsafe {
       -                        if let Some(new_settings) =
       -                            show_monitor_settings(ui, &SETTINGS.monitor_settings)
       -                        {
       +                        if let Some(new_settings) = show_monitor_settings(ui, &SETTINGS.monitor_settings) {
                                    SETTINGS.monitor_settings = new_settings;
                                }
                            },
                            MARKER_CAT => {
                                ui.add_space(8.0);
                                unsafe {
       -                            if let Some(new_settings) =
       -                                show_marker_settings(ui, &SETTINGS.marker_settings)
       -                            {
       +                            if let Some(new_settings) = show_marker_settings(ui, &SETTINGS.marker_settings) {
                                        SETTINGS.marker_settings = new_settings;
                                    }
                                }
       @@ -156,8 +135,7 @@ impl SettingsDialog {
        
                            OUTLINE_CAT => {
                                ui.add_space(8.0);
       -                        self.select_outline_dialog
       -                            .show_outline_ui(ui, 4, Vec2::new(8.0, 8.0));
       +                        self.select_outline_dialog.show_outline_ui(ui, 4, Vec2::new(8.0, 8.0));
                            }
        
                            KEYBIND_CAT => {
       @@ -177,10 +155,7 @@ impl SettingsDialog {
                        ui.separator();
                        ui.add_space(4.0);
                        ui.with_layout(Layout::right_to_left(egui::Align::TOP), |ui| {
       -                    if ui
       -                        .button(fl!(crate::LANGUAGE_LOADER, "new-file-ok"))
       -                        .clicked()
       -                    {
       +                    if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-ok")).clicked() {
                                unsafe {
                                    SETTINGS.key_bindings = self.key_bindings.clone();
                                    SETTINGS.character_sets.clear();
       @@ -189,10 +164,7 @@ impl SettingsDialog {
                                dialog_open = false;
                            }
        
       -                    if ui
       -                        .button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel"))
       -                        .clicked()
       -                    {
       +                    if ui.button(fl!(crate::LANGUAGE_LOADER, "new-file-cancel")).clicked() {
                                unsafe {
                                    SETTINGS.monitor_settings = self.monitor_settings.clone();
                                    SETTINGS.marker_settings = self.marker_settings.clone();
       @@ -205,9 +177,7 @@ impl SettingsDialog {
                                || self.settings_category == MARKER_CAT
                                || self.settings_category == CHAR_SET_CAT
                                || self.settings_category == KEYBIND_CAT)
       -                        && ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "settings-reset_button"))
       -                            .clicked()
       +                        && ui.button(fl!(crate::LANGUAGE_LOADER, "settings-reset_button")).clicked()
                            {
                                unsafe {
                                    match self.settings_category {
       @@ -231,66 +201,53 @@ impl SettingsDialog {
                ui.set_height(540.);
                let mut id = 0;
                ui.add_space(48.0);
       -        egui::Grid::new("paste_mode_grid")
       -            .num_columns(6)
       -            .spacing([8.0, 8.0])
       -            .show(ui, |ui| {
       -                for view in &self.views {
       -                    let opt = icy_engine_egui::TerminalOptions {
       -                        stick_to_bottom: false,
       -                        scale: Some(Vec2::new(2.0, 2.0)),
       -                        id: Some(egui::Id::new(200 + id)),
       -                        terminal_size: Some(Vec2::new(8. * 10. * 2.0, 16.0 * 2.0)),
       -                        ..Default::default()
       -                    };
       -
       -                    for x in 0..10 {
       -                        let ch = self.char_set.table[id][x];
       -                        view.lock().get_buffer_mut().layers[0]
       -                            .set_char((x, 0), AttributedChar::new(ch, TextAttribute::default()));
       -                    }
       -                    if id % 3 == 0 {
       -                        ui.end_row();
       -                    }
       -                    id += 1;
       -
       -                    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                        if view.lock().calc.has_focus {
       -                            ui.strong(fl!(crate::LANGUAGE_LOADER, "settings-set-label", set = id));
       -                        } else {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "settings-set-label", set = id));
       -                        }
       -                    });
       -                    show_terminal_area(ui, view.clone(), opt);
       +        egui::Grid::new("paste_mode_grid").num_columns(6).spacing([8.0, 8.0]).show(ui, |ui| {
       +            for view in &self.views {
       +                let opt = icy_engine_egui::TerminalOptions {
       +                    stick_to_bottom: false,
       +                    scale: Some(Vec2::new(2.0, 2.0)),
       +                    id: Some(egui::Id::new(200 + id)),
       +                    terminal_size: Some(Vec2::new(8. * 10. * 2.0, 16.0 * 2.0)),
       +                    ..Default::default()
       +                };
       +
       +                for x in 0..10 {
       +                    let ch = self.char_set.table[id][x];
       +                    view.lock().get_buffer_mut().layers[0].set_char((x, 0), AttributedChar::new(ch, TextAttribute::default()));
                        }
       -            });
       +                if id % 3 == 0 {
       +                    ui.end_row();
       +                }
       +                id += 1;
       +
       +                ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                    if view.lock().calc.has_focus {
       +                        ui.strong(fl!(crate::LANGUAGE_LOADER, "settings-set-label", set = id));
       +                    } else {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "settings-set-label", set = id));
       +                    }
       +                });
       +                show_terminal_area(ui, view.clone(), opt);
       +            }
       +        });
                self.char_view.show_plain_char_table(ui);
            }
        }
        
       -pub fn show_marker_settings(
       -    ui: &mut egui::Ui,
       -    old_settings: &MarkerSettings,
       -) -> Option<MarkerSettings> {
       +pub fn show_marker_settings(ui: &mut egui::Ui, old_settings: &MarkerSettings) -> Option<MarkerSettings> {
            let mut result = None;
        
            let mut marker_settings = old_settings.clone();
        
            ui.horizontal(|ui| {
       -        ui.label(fl!(
       -            crate::LANGUAGE_LOADER,
       -            "settings-background_color-label"
       -        ));
       +        ui.label(fl!(crate::LANGUAGE_LOADER, "settings-background_color-label"));
                let (r, g, b) = marker_settings.border_color.get_rgb();
                let mut color = Color32::from_rgb(r, g, b);
                color_picker::color_edit_button_srgba(ui, &mut color, color_picker::Alpha::Opaque);
                marker_settings.border_color = Color::new(r, g, b);
            });
        
       -    ui.add(
       -        egui::Slider::new(&mut marker_settings.reference_image_alpha, 0.1..=0.9)
       -            .text(fl!(crate::LANGUAGE_LOADER, "settings-reference-alpha")),
       -    );
       +    ui.add(egui::Slider::new(&mut marker_settings.reference_image_alpha, 0.1..=0.9).text(fl!(crate::LANGUAGE_LOADER, "settings-reference-alpha")));
        
            ui.horizontal(|ui| {
                ui.label(fl!(crate::LANGUAGE_LOADER, "settings-raster-label"));
       @@ -299,10 +256,7 @@ pub fn show_marker_settings(
        
                color_picker::color_edit_button_srgba(ui, &mut color, color_picker::Alpha::Opaque);
                marker_settings.raster_color = Color::new(r, g, b);
       -        ui.add(
       -            egui::Slider::new(&mut marker_settings.raster_alpha, 0.1..=0.9)
       -                .text(fl!(crate::LANGUAGE_LOADER, "settings-alpha")),
       -        );
       +        ui.add(egui::Slider::new(&mut marker_settings.raster_alpha, 0.1..=0.9).text(fl!(crate::LANGUAGE_LOADER, "settings-alpha")));
            });
        
            ui.horizontal(|ui| {
       @@ -313,10 +267,7 @@ pub fn show_marker_settings(
                color_picker::color_edit_button_srgba(ui, &mut color, color_picker::Alpha::Opaque);
                marker_settings.guide_color = Color::new(r, g, b);
        
       -        ui.add(
       -            egui::Slider::new(&mut marker_settings.guide_alpha, 0.1..=0.9)
       -                .text(fl!(crate::LANGUAGE_LOADER, "settings-alpha")),
       -        );
       +        ui.add(egui::Slider::new(&mut marker_settings.guide_alpha, 0.1..=0.9).text(fl!(crate::LANGUAGE_LOADER, "settings-alpha")));
            });
        
            if marker_settings != *old_settings {
   DIR diff --git a/src/ui/document.rs b/src/ui/document.rs
       @@ -55,13 +55,7 @@ pub trait Document: UndoHandler + ClipboardHandler {
        
            fn get_bytes(&mut self, path: &Path) -> TerminalResult<Vec<u8>>;
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_tool: &mut Box<dyn Tool>,
       -        selected_tool: usize,
       -        options: &DocumentOptions,
       -    ) -> Option<Message>;
       +    fn show_ui(&mut self, ui: &mut egui::Ui, cur_tool: &mut Box<dyn Tool>, selected_tool: usize, options: &DocumentOptions) -> Option<Message>;
        
            fn destroy(&self, gl: &glow::Context) -> Option<Message>;
        
   DIR diff --git a/src/ui/document_docking.rs b/src/ui/document_docking.rs
       @@ -56,12 +56,7 @@ impl DocumentTab {
                match doc.get_bytes(path) {
                    Ok(bytes) => {
                        let mut tmp_file = path.clone();
       -                let ext = path
       -                    .extension()
       -                    .unwrap_or_default()
       -                    .to_str()
       -                    .unwrap()
       -                    .to_ascii_lowercase();
       +                let ext = path.extension().unwrap_or_default().to_str().unwrap().to_ascii_lowercase();
        
                        tmp_file.with_extension(format!("{}~", ext));
                        let mut num = 1;
       @@ -199,12 +194,7 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                title.into()
            }
        
       -    fn pane_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        _tile_id: egui_tiles::TileId,
       -        pane: &mut DocumentTab,
       -    ) -> egui_tiles::UiResponse {
       +    fn pane_ui(&mut self, ui: &mut egui::Ui, _tile_id: egui_tiles::TileId, pane: &mut DocumentTab) -> egui_tiles::UiResponse {
                if pane.is_destroyed() {
                    return egui_tiles::UiResponse::None;
                }
       @@ -238,39 +228,22 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                egui_tiles::UiResponse::None
            }
        
       -    fn on_tab_button(
       -        &mut self,
       -        tiles: &Tiles<DocumentTab>,
       -        tile_id: TileId,
       -        button_response: eframe::egui::Response,
       -    ) -> Response {
       +    fn on_tab_button(&mut self, tiles: &Tiles<DocumentTab>, tile_id: TileId, button_response: eframe::egui::Response) -> Response {
                button_response.context_menu(|ui| {
       -            if ui
       -                .button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close"))
       -                .clicked()
       -            {
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close")).clicked() {
                        self.on_close_requested(tiles, tile_id);
                        ui.close_menu();
                    }
       -            if ui
       -                .button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close_others"))
       -                .clicked()
       -            {
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close_others")).clicked() {
                        self.request_close_others = Some(tile_id);
                        ui.close_menu();
                    }
       -            if ui
       -                .button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close_all"))
       -                .clicked()
       -            {
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-close_all")).clicked() {
                        self.request_close_all = Some(tile_id);
                        ui.close_menu();
                    }
                    ui.separator();
       -            if ui
       -                .button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-copy_path"))
       -                .clicked()
       -            {
       +            if ui.button(fl!(crate::LANGUAGE_LOADER, "tab-context-menu-copy_path")).clicked() {
                        if let Some(egui_tiles::Tile::Pane(pane)) = tiles.get(tile_id) {
                            if let Some(path) = &pane.full_path {
                                let text = path.to_str().unwrap().to_string();
       @@ -297,13 +270,7 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                true
            }
        
       -    fn top_bar_rtl_ui(
       -        &mut self,
       -        tiles: &Tiles<DocumentTab>,
       -        ui: &mut Ui,
       -        _tile_id: TileId,
       -        tabs: &Tabs,
       -    ) {
       +    fn top_bar_rtl_ui(&mut self, tiles: &Tiles<DocumentTab>, ui: &mut Ui, _tile_id: TileId, tabs: &Tabs) {
                if let Some(id) = tabs.active {
                    if let Some(egui_tiles::Tile::Pane(pane)) = tiles.get(id) {
                        if let Ok(doc) = &mut pane.doc.lock() {
       @@ -311,21 +278,16 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                                ui.add_space(4.0);
                                let mut buffer = Buffer::new((48, 1));
                                let font_page = editor.buffer_view.lock().get_caret().get_font_page();
       -                        if let Some(font) =
       -                            editor.buffer_view.lock().get_buffer().get_font(font_page)
       -                        {
       +                        if let Some(font) = editor.buffer_view.lock().get_buffer().get_font(font_page) {
                                    buffer.set_font(1, font.clone());
                                }
        
                                let char_set = Settings::get_character_set();
       -                        if self.cur_char_set != char_set
       -                            || self.dark_mode != ui.style().visuals.dark_mode
       -                        {
       +                        if self.cur_char_set != char_set || self.dark_mode != ui.style().visuals.dark_mode {
                                    let c = if ui.style().visuals.dark_mode {
                                        ui.style().visuals.extreme_bg_color
                                    } else {
       -                                (Rgba::from(ui.style().visuals.panel_fill) * Rgba::from_gray(0.8))
       -                                    .into()
       +                                (Rgba::from(ui.style().visuals.panel_fill) * Rgba::from_gray(0.8)).into()
                                    };
        
                                    let bg_color = buffer.palette.insert_color_rgb(c.r(), c.g(), c.b());
       @@ -361,10 +323,7 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                                        }
                                        attr.set_foreground(15);
                                        attr.set_font_page(1);
       -                                buffer.layers[0].set_char(
       -                                    (i, 0),
       -                                    AttributedChar::new(editor.get_char_set_key(j), attr),
       -                                );
       +                                buffer.layers[0].set_char((i, 0), AttributedChar::new(editor.get_char_set_key(j), attr));
                                        attr.set_font_page(0);
                                        i += 1;
                                    }
       @@ -376,11 +335,8 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                                    img.show(ui);
                                }
        
       -                        let txt = self.tools.lock().unwrap()[self.selected_tool]
       -                            .get_toolbar_location_text(editor);
       -                        if txt != self.cur_line_col_txt
       -                            || self.dark_mode != ui.style().visuals.dark_mode
       -                        {
       +                        let txt = self.tools.lock().unwrap()[self.selected_tool].get_toolbar_location_text(editor);
       +                        if txt != self.cur_line_col_txt || self.dark_mode != ui.style().visuals.dark_mode {
                                    self.cur_line_col_txt = txt;
                                    self.dark_mode = ui.style().visuals.dark_mode;
                                    let mut txt2 = String::new();
       @@ -398,8 +354,7 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
                                    let c = if ui.style().visuals.dark_mode {
                                        ui.style().visuals.extreme_bg_color
                                    } else {
       -                                (Rgba::from(ui.style().visuals.panel_fill) * Rgba::from_gray(0.8))
       -                                    .into()
       +                                (Rgba::from(ui.style().visuals.panel_fill) * Rgba::from_gray(0.8)).into()
                                    };
        
                                    let bg_color = buffer.palette.insert_color_rgb(c.r(), c.g(), c.b());
       @@ -428,11 +383,7 @@ impl egui_tiles::Behavior<DocumentTab> for DocumentBehavior {
            }
        }
        
       -pub fn add_child(
       -    tree: &mut egui_tiles::Tree<DocumentTab>,
       -    full_path: Option<PathBuf>,
       -    doc: Box<dyn Document>,
       -) {
       +pub fn add_child(tree: &mut egui_tiles::Tree<DocumentTab>, full_path: Option<PathBuf>, doc: Box<dyn Document>) {
            let tile = DocumentTab {
                full_path,
                doc: Arc::new(Mutex::new(doc)),
       @@ -446,15 +397,11 @@ pub fn add_child(
        
            if tree.root.is_none() {
                tree.root = Some(new_child);
       -    } else if let Some(egui_tiles::Tile::Container(egui_tiles::Container::Tabs(tabs))) =
       -        tree.tiles.get_mut(tree.root.unwrap())
       -    {
       +    } else if let Some(egui_tiles::Tile::Container(egui_tiles::Container::Tabs(tabs))) = tree.tiles.get_mut(tree.root.unwrap()) {
                tabs.add_child(new_child);
                tabs.set_active(new_child);
            } else if let Some(egui_tiles::Tile::Pane(_)) = tree.tiles.get(tree.root.unwrap()) {
       -        let new_id = tree
       -            .tiles
       -            .insert_tab_tile(vec![new_child, tree.root.unwrap()]);
       +        let new_id = tree.tiles.insert_tab_tile(vec![new_child, tree.root.unwrap()]);
                tree.root = Some(new_id);
            } else {
                tree.root = Some(new_child);
   DIR diff --git a/src/ui/editor/animation/highlighting.rs b/src/ui/editor/animation/highlighting.rs
       @@ -9,12 +9,10 @@ pub fn lua() -> Syntax {
                comment: "--",
                comment_multiline: ["--[[", "]]"],
                keywords: HashSet::from([
       -            "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in",
       -            "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while",
       -        ]),
       -        types: HashSet::from([
       -            "nil", "boolean", "number", "string", "nil", "function", "userdata", "thread", "table",
       +            "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then",
       +            "true", "until", "while",
                ]),
       +        types: HashSet::from(["nil", "boolean", "number", "string", "nil", "function", "userdata", "thread", "table"]),
                special: HashSet::from([
                    "new_buffer",
                    "load_buffer",
   DIR diff --git a/src/ui/editor/animation/mod.rs b/src/ui/editor/animation/mod.rs
       @@ -15,10 +15,7 @@ use i18n_embed_fl::fl;
        use icy_engine::{Buffer, EngineResult, SaveOptions, Size, TextPane};
        use icy_engine_egui::{animations::Animator, show_terminal_area, BufferView, MonitorSettings};
        
       -use crate::{
       -    model::Tool, AnsiEditor, ClipboardHandler, Document, DocumentOptions, Message, TerminalResult,
       -    UndoHandler,
       -};
       +use crate::{model::Tool, AnsiEditor, ClipboardHandler, Document, DocumentOptions, Message, TerminalResult, UndoHandler};
        
        mod highlighting;
        
       @@ -84,8 +81,7 @@ impl AnimationEditor {
                                let width = (size.width * dim.width) as u16;
                                let height = (size.height * dim.height) as u16;
        
       -                        let Ok(mut encoder) = ::gif::Encoder::new(&mut image, width, height, &[])
       -                        else {
       +                        let Ok(mut encoder) = ::gif::Encoder::new(&mut image, width, height, &[]) else {
                                    return Err(anyhow::anyhow!("Could not create encoder"));
                                };
                                encoder.set_repeat(::gif::Repeat::Infinite).unwrap();
       @@ -93,15 +89,8 @@ impl AnimationEditor {
                                let frame_count = self.animator.lock().unwrap().frames.len();
        
                                for frame in 0..frame_count {
       -                            self.animator
       -                                .lock()
       -                                .unwrap()
       -                                .set_cur_frame(frame);
       -                            let monitor_settings = self
       -                                .animator
       -                                .lock()
       -                                .unwrap()
       -                                .display_frame(self.buffer_view.clone());
       +                            self.animator.lock().unwrap().set_cur_frame(frame);
       +                            let monitor_settings = self.animator.lock().unwrap().display_frame(self.buffer_view.clone());
                                    let opt = icy_engine_egui::TerminalOptions {
                                        stick_to_bottom: false,
                                        scale: Some(Vec2::new(1.0, 1.0)),
       @@ -111,11 +100,9 @@ impl AnimationEditor {
                                        ..Default::default()
                                    };
        
       -                            let (size, mut data) =
       -                                self.buffer_view.lock().render_buffer(&self.gl, &opt);
       +                            let (size, mut data) = self.buffer_view.lock().render_buffer(&self.gl, &opt);
        
       -                            let gif_frame =
       -                                ::gif::Frame::from_rgba(size.x as u16, size.y as u16, &mut data);
       +                            let gif_frame = ::gif::Frame::from_rgba(size.x as u16, size.y as u16, &mut data);
                                    encoder.write_frame(&gif_frame)?;
                                }
                            } else {
       @@ -195,13 +182,7 @@ impl Document for AnimationEditor {
                self.undostack
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut eframe::egui::Ui,
       -        _cur_tool: &mut Box<dyn Tool>,
       -        _selected_tool: usize,
       -        options: &DocumentOptions,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut eframe::egui::Ui, _cur_tool: &mut Box<dyn Tool>, _selected_tool: usize, options: &DocumentOptions) -> Option<Message> {
                let mut message = None;
        
                if self.first_frame && self.animator.lock().unwrap().success() {
       @@ -217,129 +198,90 @@ impl Document for AnimationEditor {
                    .exact_width(ui.available_width() / 2.0)
                    .resizable(false)
                    .show_inside(ui, |ui| {
       -                TopBottomPanel::top("move_top_panel")
       -                    .exact_height(24.)
       -                    .show_inside(ui, |ui| {
       -                        ui.horizontal(|ui| {
       -                            if !self.animator.lock().unwrap().error.is_empty() {
       -                                ui.set_enabled(false);
       -                            }
       -                            let size_points = Vec2::new(22.0, 22.0);
       -                            if self.animator.lock().unwrap().success() {
       -                                let animator = &mut self.animator.lock().unwrap();
       -                                let frame_count = animator.frames.len();
       -                                if animator.is_playing() {
       -                                    if ui
       -                                        .add(ImageButton::new(
       -                                            crate::PAUSE_SVG.texture_id(ui.ctx()),
       -                                            size_points,
       -                                        ))
       -                                        .clicked()
       -                                    {
       -                                        animator.set_is_playing(false);
       -                                    }
       -                                } else {
       -                                    let id = if animator.get_cur_frame() + 1 < frame_count {
       -                                        crate::PLAY_SVG.texture_id(ui.ctx())
       -                                    } else {
       -                                        crate::REPLAY_SVG.texture_id(ui.ctx())
       -                                    };
       -                                    if ui.add(ImageButton::new(id, size_points)).clicked() {
       -                                        animator.start_playback(self.buffer_view.clone());
       -                                    }
       -                                }
       -                                if ui
       -                                    .add_enabled(
       -                                        animator.get_cur_frame() + 1 < frame_count,
       -                                        ImageButton::new(
       -                                            crate::SKIP_NEXT_SVG.texture_id(ui.ctx()),
       -                                            size_points,
       -                                        ),
       -                                    )
       -                                    .clicked()
       -                                {
       -                                    animator.set_cur_frame(frame_count - 1);
       -                                    animator.display_frame(self.buffer_view.clone());
       -                                }
       -                                let is_loop = animator.get_is_loop();
       -                                if ui
       -                                    .add(
       -                                        ImageButton::new(
       -                                            crate::REPEAT_SVG.texture_id(ui.ctx()),
       -                                            size_points,
       -                                        )
       -                                        .selected(is_loop),
       -                                    )
       -                                    .clicked()
       -                                {
       -                                    animator.set_is_loop(!is_loop);
       +                TopBottomPanel::top("move_top_panel").exact_height(24.).show_inside(ui, |ui| {
       +                    ui.horizontal(|ui| {
       +                        if !self.animator.lock().unwrap().error.is_empty() {
       +                            ui.set_enabled(false);
       +                        }
       +                        let size_points = Vec2::new(22.0, 22.0);
       +                        if self.animator.lock().unwrap().success() {
       +                            let animator = &mut self.animator.lock().unwrap();
       +                            let frame_count = animator.frames.len();
       +                            if animator.is_playing() {
       +                                if ui.add(ImageButton::new(crate::PAUSE_SVG.texture_id(ui.ctx()), size_points)).clicked() {
       +                                    animator.set_is_playing(false);
                                        }
       -
       -                                let mut cf = animator.get_cur_frame() + 1;
       -                                if frame_count > 0
       -                                    && ui
       -                                        .add(
       -                                            Slider::new(&mut cf, 1..=frame_count)
       -                                                .text(format!("of {}", frame_count)),
       -                                        )
       -                                        .changed()
       -                                {
       -                                    animator.set_cur_frame(cf - 1);
       -                                    animator.display_frame(self.buffer_view.clone());
       +                            } else {
       +                                let id = if animator.get_cur_frame() + 1 < frame_count {
       +                                    crate::PLAY_SVG.texture_id(ui.ctx())
       +                                } else {
       +                                    crate::REPLAY_SVG.texture_id(ui.ctx())
       +                                };
       +                                if ui.add(ImageButton::new(id, size_points)).clicked() {
       +                                    animator.start_playback(self.buffer_view.clone());
                                        }
                                    }
       -                        });
       -                    });
       -
       -                TopBottomPanel::bottom("export_panel")
       -                    .exact_height(100.)
       -                    .show_inside(ui, |ui| {
       -                        ui.horizontal(|ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "animation_editor_path_label"));
       -                            let mut path_edit = self.export_path.to_str().unwrap().to_string();
       -                            let response = ui.add(
       -                                //    ui.available_size(),
       -                                TextEdit::singleline(&mut path_edit),
       -                            );
       -                            if response.changed() {
       -                                self.export_path = path_edit.into();
       -                            }
       -
                                    if ui
       -                                .selectable_label(
       -                                    self.export_type == ExportType::Gif,
       -                                    fl!(crate::LANGUAGE_LOADER, "animation_editor_gif_label"),
       +                                .add_enabled(
       +                                    animator.get_cur_frame() + 1 < frame_count,
       +                                    ImageButton::new(crate::SKIP_NEXT_SVG.texture_id(ui.ctx()), size_points),
                                        )
                                        .clicked()
                                    {
       -                                self.export_type = ExportType::Gif;
       -                                self.export_path.set_extension("gif");
       +                                animator.set_cur_frame(frame_count - 1);
       +                                animator.display_frame(self.buffer_view.clone());
                                    }
       +                            let is_loop = animator.get_is_loop();
                                    if ui
       -                                .selectable_label(
       -                                    self.export_type == ExportType::Ansi,
       -                                    fl!(crate::LANGUAGE_LOADER, "animation_editor_ansi_label"),
       -                                )
       +                                .add(ImageButton::new(crate::REPEAT_SVG.texture_id(ui.ctx()), size_points).selected(is_loop))
                                        .clicked()
                                    {
       -                                self.export_type = ExportType::Ansi;
       -                                self.export_path.set_extension("ans");
       +                                animator.set_is_loop(!is_loop);
                                    }
       -                        });
       -                        ui.add_space(8.0);
       +
       +                            let mut cf = animator.get_cur_frame() + 1;
       +                            if frame_count > 0 && ui.add(Slider::new(&mut cf, 1..=frame_count).text(format!("of {}", frame_count))).changed() {
       +                                animator.set_cur_frame(cf - 1);
       +                                animator.display_frame(self.buffer_view.clone());
       +                            }
       +                        }
       +                    });
       +                });
       +
       +                TopBottomPanel::bottom("export_panel").exact_height(100.).show_inside(ui, |ui| {
       +                    ui.horizontal(|ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "animation_editor_path_label"));
       +                        let mut path_edit = self.export_path.to_str().unwrap().to_string();
       +                        let response = ui.add(
       +                            //    ui.available_size(),
       +                            TextEdit::singleline(&mut path_edit),
       +                        );
       +                        if response.changed() {
       +                            self.export_path = path_edit.into();
       +                        }
       +
                                if ui
       -                            .button(fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "animation_editor_export_button"
       -                            ))
       +                            .selectable_label(self.export_type == ExportType::Gif, fl!(crate::LANGUAGE_LOADER, "animation_editor_gif_label"))
                                    .clicked()
                                {
       -                            if let Err(err) = self.export() {
       -                                message =
       -                                    Some(Message::ShowError(format!("Could not export: {}", err)));
       -                            }
       +                            self.export_type = ExportType::Gif;
       +                            self.export_path.set_extension("gif");
       +                        }
       +                        if ui
       +                            .selectable_label(self.export_type == ExportType::Ansi, fl!(crate::LANGUAGE_LOADER, "animation_editor_ansi_label"))
       +                            .clicked()
       +                        {
       +                            self.export_type = ExportType::Ansi;
       +                            self.export_path.set_extension("ans");
                                }
                            });
       +                    ui.add_space(8.0);
       +                    if ui.button(fl!(crate::LANGUAGE_LOADER, "animation_editor_export_button")).clicked() {
       +                        if let Err(err) = self.export() {
       +                            message = Some(Message::ShowError(format!("Could not export: {}", err)));
       +                        }
       +                    }
       +                });
        
                        /*
                        if ui.button("Export").clicked() {
       @@ -358,9 +300,7 @@ impl Document for AnimationEditor {
                            if self.animator.lock().unwrap().success() {
                                let cur_frame = self.animator.lock().unwrap().get_cur_frame();
        
       -                        let monitor_settings = if let Some((_, settings, _)) =
       -                            self.animator.lock().unwrap().frames.get(cur_frame)
       -                        {
       +                        let monitor_settings = if let Some((_, settings, _)) = self.animator.lock().unwrap().frames.get(cur_frame) {
                                    settings.clone()
                                } else {
                                    MonitorSettings::default()
       @@ -393,14 +333,9 @@ impl Document for AnimationEditor {
                        .with_numlines(true)
                        .show(ui, &mut self.txt);
                    if !self.animator.lock().unwrap().error.is_empty() {
       -                TopBottomPanel::bottom("code_error_bottom_panel")
       -                    .exact_height(100.)
       -                    .show_inside(ui, |ui| {
       -                        ui.colored_label(
       -                            ui.style().visuals.error_fg_color,
       -                            RichText::new(&self.animator.lock().unwrap().error).small(),
       -                        );
       -                    });
       +                TopBottomPanel::bottom("code_error_bottom_panel").exact_height(100.).show_inside(ui, |ui| {
       +                    ui.colored_label(ui.style().visuals.error_fg_color, RichText::new(&self.animator.lock().unwrap().error).small());
       +                });
                    }
        
                    if self.shedule_update && self.last_update.elapsed().as_millis() > 1000 {
   DIR diff --git a/src/ui/editor/ansi/mod.rs b/src/ui/editor/ansi/mod.rs
       @@ -15,16 +15,14 @@ use i18n_embed_fl::fl;
        use icy_engine::{
            editor::{AtomicUndoGuard, UndoState},
            util::{pop_data, pop_sixel_image, push_data, BUFFER_DATA},
       -    AttributedChar, Buffer, EngineResult, Line, Position, Rectangle, SaveOptions, TextAttribute,
       -    TextPane,
       +    AttributedChar, Buffer, EngineResult, Line, Position, Rectangle, SaveOptions, TextAttribute, TextPane,
        };
        
        use icy_engine_egui::{show_terminal_area, BufferView, TerminalCalc};
        
        use crate::{
            model::{DragPos, MKey, MModifiers, Tool},
       -    ClipboardHandler, Commands, Document, DocumentOptions, Message, SavingError, TerminalResult,
       -    UndoHandler, SETTINGS,
       +    ClipboardHandler, Commands, Document, DocumentOptions, Message, SavingError, TerminalResult, UndoHandler, SETTINGS,
        };
        
        pub enum Event {
       @@ -88,10 +86,7 @@ impl ClipboardHandler for AnsiEditor {
            fn cut(&mut self) -> EngineResult<()> {
                let _cut = self.begin_atomic_undo(fl!(crate::LANGUAGE_LOADER, "undo-cut"));
                self.copy()?;
       -        self.buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .erase_selection()?;
       +        self.buffer_view.lock().get_edit_state_mut().erase_selection()?;
                Ok(())
            }
        
       @@ -100,12 +95,7 @@ impl ClipboardHandler for AnsiEditor {
            }
        
            fn copy(&mut self) -> EngineResult<()> {
       -        if let Some(data) = self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_clipboard_data()
       -        {
       +        if let Some(data) = self.buffer_view.lock().get_edit_state_mut().get_clipboard_data() {
                    push_data(BUFFER_DATA, &data)?;
                } else {
                    log::error!("can't get clipboard data!");
       @@ -118,25 +108,14 @@ impl ClipboardHandler for AnsiEditor {
            }
        
            fn paste(&mut self) -> EngineResult<()> {
       -        if self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .has_floating_layer()
       -        {
       +        if self.buffer_view.lock().get_edit_state_mut().has_floating_layer() {
                    return Ok(());
                }
        
                if let Some(data) = pop_data(BUFFER_DATA) {
       -            self.buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .paste_clipboard_data(&data)?;
       +            self.buffer_view.lock().get_edit_state_mut().paste_clipboard_data(&data)?;
                } else if let Some(sixel) = pop_sixel_image() {
       -            self.buffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .paste_sixel(sixel)?;
       +            self.buffer_view.lock().get_edit_state_mut().paste_sixel(sixel)?;
                }
                Ok(())
            }
       @@ -149,13 +128,7 @@ impl Document for AnsiEditor {
            }
        
            fn undo_stack_len(&self) -> usize {
       -        if let Ok(stack) = self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .get_undo_stack()
       -            .lock()
       -        {
       +        if let Ok(stack) = self.buffer_view.lock().get_edit_state().get_undo_stack().lock() {
                    for i in (0..stack.len()).rev() {
                        if stack[i].changes_data() {
                            return i + 1;
       @@ -172,21 +145,11 @@ impl Document for AnsiEditor {
                    ICED_EXT.to_string()
                };
                let options = SaveOptions::new();
       -        let bytes = self
       -            .buffer_view
       -            .lock()
       -            .get_buffer()
       -            .to_bytes(&ext, &options)?;
       +        let bytes = self.buffer_view.lock().get_buffer().to_bytes(&ext, &options)?;
                Ok(bytes)
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_tool: &mut Box<dyn Tool>,
       -        _selected_tool: usize,
       -        options: &DocumentOptions,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut egui::Ui, cur_tool: &mut Box<dyn Tool>, _selected_tool: usize, options: &DocumentOptions) -> Option<Message> {
                let mut message = None;
        
                let mut scale = options.get_scale();
       @@ -259,17 +222,11 @@ impl AnsiEditor {
            }
        
            pub fn get_cur_layer_index(&self) -> usize {
       -        self.buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .get_current_layer()
       +        self.buffer_view.lock().get_edit_state_mut().get_current_layer()
            }
        
            pub fn set_cur_layer_index(&self, layer: usize) {
       -        self.buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .set_current_layer(layer);
       +        self.buffer_view.lock().get_edit_state_mut().set_current_layer(layer);
            }
        
            pub fn output_string(&mut self, str: &str) {
       @@ -305,11 +262,7 @@ impl AnsiEditor {
            pub fn join_overlay(&mut self, description: impl Into<String>) {
                let _undo = self.begin_atomic_undo(description.into());
                let opt_layer = self.buffer_view.lock().get_buffer_mut().remove_overlay();
       -        let use_selection = self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .is_something_selected();
       +        let use_selection = self.buffer_view.lock().get_edit_state().is_something_selected();
        
                if let Some(layer) = &opt_layer {
                    for y in 0..layer.lines.len() {
       @@ -317,14 +270,7 @@ impl AnsiEditor {
                        for x in 0..line.chars.len() {
                            let ch = line.chars[x];
                            let pos = Position::new(x as i32, y as i32);
       -                    if ch.is_visible()
       -                        && (!use_selection
       -                            || self
       -                                .buffer_view
       -                                .lock()
       -                                .get_edit_state()
       -                                .get_is_selected(pos + layer.get_offset()))
       -                    {
       +                    if ch.is_visible() && (!use_selection || self.buffer_view.lock().get_edit_state().get_is_selected(pos + layer.get_offset())) {
                                self.set_char(pos, ch);
                            }
                        }
       @@ -353,10 +299,7 @@ impl AnsiEditor {
            pub fn pickup_color(&mut self, pos: Position) {
                let ch = self.buffer_view.lock().get_buffer().get_char(pos);
                if ch.is_visible() {
       -            self.buffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_attr(ch.attribute);
       +            self.buffer_view.lock().get_caret_mut().set_attr(ch.attribute);
                }
            }
        
       @@ -406,15 +349,9 @@ impl AnsiEditor {
                    Ok(mut f) => {
                        let content = if let Some(ext) = file_name.extension() {
                            let ext = OsStr::to_str(ext).unwrap().to_lowercase();
       -                    self.buffer_view
       -                        .lock()
       -                        .get_buffer()
       -                        .to_bytes(ext.as_str(), options)?
       +                    self.buffer_view.lock().get_buffer().to_bytes(ext.as_str(), options)?
                        } else {
       -                    self.buffer_view
       -                        .lock()
       -                        .get_buffer()
       -                        .to_bytes(ICED_EXT, options)?
       +                    self.buffer_view.lock().get_buffer().to_bytes(ICED_EXT, options)?
                        };
                        if let Err(err) = f.write_all(&content) {
                            return Err(SavingError::ErrorWritingFile(format!("{err}")).into());
       @@ -451,19 +388,12 @@ impl AnsiEditor {
            }
        
            pub fn set_char(&mut self, pos: impl Into<Position>, attributed_char: AttributedChar) {
       -        let _ = self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .set_char(pos, attributed_char);
       +        let _ = self.buffer_view.lock().get_edit_state_mut().set_char(pos, attributed_char);
            }
        
            #[must_use]
            pub fn begin_atomic_undo(&mut self, description: impl Into<String>) -> AtomicUndoGuard {
       -        self.buffer_view
       -            .lock()
       -            .get_edit_state_mut()
       -            .begin_atomic_undo(description.into())
       +        self.buffer_view.lock().get_edit_state_mut().begin_atomic_undo(description.into())
            }
        
            pub fn fill(&mut self, rect: Rectangle, dos_char: AttributedChar) {
       @@ -576,23 +506,15 @@ impl AnsiEditor {
                            }
        
                            egui::Event::CompositionEnd(text) | egui::Event::Text(text) => {
       -                        if !ui.input(|i| i.modifiers.ctrl || i.modifiers.command || i.modifiers.alt)
       -                        {
       +                        if !ui.input(|i| i.modifiers.ctrl || i.modifiers.command || i.modifiers.alt) {
                                    for c in text.chars() {
       -                                cur_tool.handle_key(
       -                                    self,
       -                                    MKey::Character(c as u16),
       -                                    MModifiers::None,
       -                                );
       +                                cur_tool.handle_key(self, MKey::Character(c as u16), MModifiers::None);
                                    }
                                }
                            }
        
                            egui::Event::Key {
       -                        key,
       -                        pressed: true,
       -                        modifiers,
       -                        ..
       +                        key, pressed: true, modifiers, ..
                            } => {
                                let mut key_code = *key as u32;
                                if modifiers.shift {
       @@ -625,19 +547,13 @@ impl AnsiEditor {
        
                if response.clicked_by(egui::PointerButton::Primary) {
                    if let Some(mouse_pos) = response.interact_pointer_pos() {
       -                if calc.buffer_rect.contains(mouse_pos)
       -                    && !calc.vert_scrollbar_rect.contains(mouse_pos)
       -                    && !calc.horiz_scrollbar_rect.contains(mouse_pos)
       -                {
       +                if calc.buffer_rect.contains(mouse_pos) && !calc.vert_scrollbar_rect.contains(mouse_pos) && !calc.horiz_scrollbar_rect.contains(mouse_pos) {
                            let click_pos = calc.calc_click_pos(mouse_pos);
                            let cp_abs = Position::new(click_pos.x as i32, click_pos.y as i32);
                            let layer_offset = self.get_cur_click_offset();
                            let cp = cp_abs - layer_offset;
                            let click_pos2 = calc.calc_click_pos_half_block(mouse_pos);
       -                    self.half_block_click_pos = Position::new(
       -                        click_pos2.x as i32 - layer_offset.x,
       -                        click_pos2.y as i32 - layer_offset.y,
       -                    );
       +                    self.half_block_click_pos = Position::new(click_pos2.x as i32 - layer_offset.x, click_pos2.y as i32 - layer_offset.y);
        
                            /*
                            let b: i32 = match responsee.b {
       @@ -657,10 +573,7 @@ impl AnsiEditor {
        
                if response.drag_started_by(egui::PointerButton::Primary) {
                    if let Some(mouse_pos) = response.interact_pointer_pos() {
       -                if calc.buffer_rect.contains(mouse_pos)
       -                    && !calc.vert_scrollbar_rect.contains(mouse_pos)
       -                    && !calc.horiz_scrollbar_rect.contains(mouse_pos)
       -                {
       +                if calc.buffer_rect.contains(mouse_pos) && !calc.vert_scrollbar_rect.contains(mouse_pos) && !calc.horiz_scrollbar_rect.contains(mouse_pos) {
                            let click_pos = calc.calc_click_pos(mouse_pos);
                            let cp_abs = Position::new(click_pos.x as i32, click_pos.y as i32);
        
       @@ -708,10 +621,7 @@ impl AnsiEditor {
                }
                if response.hovered() {
                    if let Some(mouse_pos) = response.hover_pos() {
       -                if calc.buffer_rect.contains(mouse_pos)
       -                    && !calc.vert_scrollbar_rect.contains(mouse_pos)
       -                    && !calc.horiz_scrollbar_rect.contains(mouse_pos)
       -                {
       +                if calc.buffer_rect.contains(mouse_pos) && !calc.vert_scrollbar_rect.contains(mouse_pos) && !calc.horiz_scrollbar_rect.contains(mouse_pos) {
                            let click_pos = calc.calc_click_pos(mouse_pos);
                            let cp_abs = Position::new(click_pos.x as i32, click_pos.y as i32);
                            let cp = cp_abs - self.get_cur_click_offset();
       @@ -746,13 +656,7 @@ impl AnsiEditor {
            }
        
            pub(crate) fn clear_overlay_layer(&self) {
       -        let cur_offset = self
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .get_cur_layer()
       -            .unwrap()
       -            .get_offset();
       +        let cur_offset = self.buffer_view.lock().get_edit_state().get_cur_layer().unwrap().get_offset();
        
                if let Some(layer) = self.buffer_view.lock().get_buffer_mut().get_overlay_layer() {
                    layer.set_offset(cur_offset);
       @@ -812,11 +716,7 @@ pub const DEFAULT_CHAR_SET_TABLE: [[u8; 10]; 15] = [
            [147, 148, 149, 162, 167, 150, 129, 151, 163, 154],
        ];
        
       -pub fn terminal_context_menu(
       -    editor: &AnsiEditor,
       -    commands: &Commands,
       -    ui: &mut egui::Ui,
       -) -> Option<Message> {
       +pub fn terminal_context_menu(editor: &AnsiEditor, commands: &Commands, ui: &mut egui::Ui) -> Option<Message> {
            ui.style_mut().wrap = Some(false);
            let mut result = None;
            ui.input_mut(|i| i.events.clear());
   DIR diff --git a/src/ui/editor/bitfont/mod.rs b/src/ui/editor/bitfont/mod.rs
       @@ -14,10 +14,7 @@ use icy_engine::{
        };
        use icy_engine_egui::{show_terminal_area, BufferView};
        
       -use crate::{
       -    model::Tool, to_message, AnsiEditor, ClipboardHandler, Document, DocumentOptions, Message,
       -    TerminalResult, UndoHandler, SETTINGS,
       -};
       +use crate::{model::Tool, to_message, AnsiEditor, ClipboardHandler, Document, DocumentOptions, Message, TerminalResult, UndoHandler, SETTINGS};
        
        use self::undo::UndoOperation;
        
       @@ -71,17 +68,9 @@ impl BitFontEditor {
                }
            }
        
       -    pub fn draw_glyph(
       -        ui: &mut egui::Ui,
       -        font: &BitFont,
       -        style: DrawGlyphStyle,
       -        ch: char,
       -    ) -> egui::Response {
       +    pub fn draw_glyph(ui: &mut egui::Ui, font: &BitFont, style: DrawGlyphStyle, ch: char) -> egui::Response {
                let scale = 3.;
       -        let (id, stroke_rect) = ui.allocate_space(Vec2::new(
       -            scale * font.size.width as f32,
       -            scale * font.size.height as f32,
       -        ));
       +        let (id, stroke_rect) = ui.allocate_space(Vec2::new(scale * font.size.width as f32, scale * font.size.height as f32));
                let response = ui.interact(stroke_rect, id, Sense::click());
                let col = if response.hovered() {
                    match style {
       @@ -106,10 +95,7 @@ impl BitFontEditor {
                            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,
       -                                ),
       +                                Pos2::new(stroke_rect.left() + x as f32 * scale, stroke_rect.top() + y as f32 * scale),
                                        Vec2::new(scale, scale),
                                    ),
                                    Rounding::none(),
       @@ -182,15 +168,11 @@ impl BitFontEditor {
                            }
                        }
                    } else { */
       -            if response.drag_started_by(egui::PointerButton::Primary)
       -                || response.drag_started_by(egui::PointerButton::Secondary)
       -            {
       +            if response.drag_started_by(egui::PointerButton::Primary) || response.drag_started_by(egui::PointerButton::Secondary) {
                        self.start_edit();
                    }
        
       -            if response.drag_released_by(egui::PointerButton::Primary)
       -                || response.drag_released_by(egui::PointerButton::Secondary)
       -            {
       +            if response.drag_released_by(egui::PointerButton::Primary) || response.drag_released_by(egui::PointerButton::Secondary) {
                        self.end_edit();
                    }
        
       @@ -198,10 +180,8 @@ impl BitFontEditor {
                        if let Some(pos) = response.interact_pointer_pos() {
                            if let Some(number) = self.selected_char_opt {
                                if let Some(glyph) = self.font.get_glyph_mut(number) {
       -                            let y = ((pos.y - left_ruler - stroke_rect.top()) / (scale + border))
       -                                as usize;
       -                            let x = ((pos.x - top_ruler - stroke_rect.left()) / (scale + border))
       -                                as usize;
       +                            let y = ((pos.y - left_ruler - stroke_rect.top()) / (scale + border)) as usize;
       +                            let x = ((pos.x - top_ruler - stroke_rect.left()) / (scale + border)) as usize;
                                    if y < glyph.data.len() && x < 8 {
                                        glyph.data[y] |= 128 >> x;
                                        self.update_tile_area();
       @@ -216,10 +196,8 @@ impl BitFontEditor {
                        if let Some(pos) = response.interact_pointer_pos() {
                            if let Some(number) = self.selected_char_opt {
                                if let Some(glyph) = self.font.get_glyph_mut(number) {
       -                            let y = ((pos.y - left_ruler - stroke_rect.top()) / (scale + border))
       -                                as usize;
       -                            let x = ((pos.x - top_ruler - stroke_rect.left()) / (scale + border))
       -                                as usize;
       +                            let y = ((pos.y - left_ruler - stroke_rect.top()) / (scale + border)) as usize;
       +                            let x = ((pos.x - top_ruler - stroke_rect.left()) / (scale + border)) as usize;
                                    if y < glyph.data.len() && x < 8 {
                                        glyph.data[y] &= !(128 >> x);
                                        self.update_tile_area();
       @@ -245,15 +223,11 @@ impl BitFontEditor {
        
                            for x in 0..s.width {
                                let pos = Pos2::new(
       -                            2. + left_ruler
       -                                + stroke_rect.left()
       -                                + (x as f32 + 0.5) * (border + scale),
       +                            2. + left_ruler + stroke_rect.left() + (x as f32 + 0.5) * (border + scale),
                                    2. + top_ruler / 2. + stroke_rect.top(),
                                );
                                let col = if let Some(pos) = response.hover_pos() {
       -                            if x == ((pos.x - (2. + left_ruler + stroke_rect.left()))
       -                                / (border + scale)) as i32
       -                            {
       +                            if x == ((pos.x - (2. + left_ruler + stroke_rect.left())) / (border + scale)) as i32 {
                                        ui.style().visuals.strong_text_color()
                                    } else {
                                        ui.style().visuals.text_color()
       @@ -273,14 +247,10 @@ impl BitFontEditor {
                            for y in 0..s.height {
                                let pos = Pos2::new(
                                    2. + left_ruler / 2. + stroke_rect.left(),
       -                            2. + top_ruler
       -                                + stroke_rect.top()
       -                                + (y as f32 + 0.5) * (border + scale),
       +                            2. + top_ruler + stroke_rect.top() + (y as f32 + 0.5) * (border + scale),
                                );
                                let col = if let Some(pos) = response.hover_pos() {
       -                            if y == ((pos.y - (2. + top_ruler + stroke_rect.top()))
       -                                / (border + scale)) as i32
       -                            {
       +                            if y == ((pos.y - (2. + top_ruler + stroke_rect.top())) / (border + scale)) as i32 {
                                        ui.style().visuals.strong_text_color()
                                    } else {
                                        ui.style().visuals.text_color()
       @@ -302,12 +272,8 @@ impl BitFontEditor {
                                for x in 0..s.width {
                                    let rect = Rect::from_min_size(
                                        Pos2::new(
       -                                    2. + left_ruler
       -                                        + stroke_rect.left()
       -                                        + x as f32 * (border + scale),
       -                                    2. + top_ruler
       -                                        + stroke_rect.top()
       -                                        + y as f32 * (border + scale),
       +                                    2. + left_ruler + stroke_rect.left() + x as f32 * (border + scale),
       +                                    2. + top_ruler + stroke_rect.top() + y as f32 * (border + scale),
                                        ),
                                        Vec2::new(scale, scale),
                                    );
       @@ -531,13 +497,7 @@ impl Document for BitFontEditor {
                self.undo_stack.lock().len()
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut eframe::egui::Ui,
       -        _cur_tool: &mut Box<dyn Tool>,
       -        _selected_tool: usize,
       -        options: &DocumentOptions,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut eframe::egui::Ui, _cur_tool: &mut Box<dyn Tool>, _selected_tool: usize, options: &DocumentOptions) -> Option<Message> {
                let mut message = None;
                ui.add_space(16.);
                ui.vertical_centered(|ui| {
       @@ -548,16 +508,10 @@ impl Document for BitFontEditor {
                        ui.vertical(|ui| {
                            ui.add_space(20.);
                            ui.horizontal(|ui| {
       -                        if ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "font-editor-clear"))
       -                            .clicked()
       -                        {
       +                        if ui.button(fl!(crate::LANGUAGE_LOADER, "font-editor-clear")).clicked() {
                                    message = to_message(self.clear_selected_glyph());
                                }
       -                        if ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "font-editor-inverse"))
       -                            .clicked()
       -                        {
       +                        if ui.button(fl!(crate::LANGUAGE_LOADER, "font-editor-inverse")).clicked() {
                                    message = to_message(self.inverse_selected_glyph());
                                }
                            });
       @@ -590,41 +544,30 @@ impl Document for BitFontEditor {
                            ui.add_space(8.);
        
                            ui.horizontal(|ui| {
       -                        if ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "font-editor-flip_x"))
       -                            .clicked()
       -                        {
       +                        if ui.button(fl!(crate::LANGUAGE_LOADER, "font-editor-flip_x")).clicked() {
                                    message = to_message(self.flip_x_selected_glyph());
                                }
        
       -                        if ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "font-editor-flip_y"))
       -                            .clicked()
       -                        {
       +                        if ui.button(fl!(crate::LANGUAGE_LOADER, "font-editor-flip_y")).clicked() {
                                    message = to_message(self.flip_y_selected_glyph());
                                }
                            });
        
       -                    egui::Grid::new("some_unique_id")
       -                        .num_columns(2)
       -                        .spacing([4.0, 8.0])
       -                        .show(ui, |ui| {
       -                            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       -                            });
       -                            ui.add(egui::Slider::new(&mut self.width, 2..=8));
       -                            ui.end_row();
       -
       -                            ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       -                                ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
       -                            });
       -                            ui.add(egui::Slider::new(&mut self.height, 2..=19));
       -                            ui.end_row();
       +                    egui::Grid::new("some_unique_id").num_columns(2).spacing([4.0, 8.0]).show(ui, |ui| {
       +                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                            ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-width"));
       +                        });
       +                        ui.add(egui::Slider::new(&mut self.width, 2..=8));
       +                        ui.end_row();
       +
       +                        ui.with_layout(Layout::right_to_left(egui::Align::Center), |ui| {
       +                            ui.label(fl!(crate::LANGUAGE_LOADER, "new-file-height"));
                                });
       +                        ui.add(egui::Slider::new(&mut self.height, 2..=19));
       +                        ui.end_row();
       +                    });
        
       -                    if (self.width != self.font.size.width || self.height != self.font.size.height)
       -                        && ui.button("Resize").clicked()
       -                    {
       +                    if (self.width != self.font.size.width || self.height != self.font.size.height) && ui.button("Resize").clicked() {
                                message = to_message(self.resize_font());
                            }
                        });
       @@ -649,11 +592,7 @@ impl Document for BitFontEditor {
                    });
                });
        
       -        ui.label(fl!(
       -            crate::LANGUAGE_LOADER,
       -            "font-editor-table",
       -            length = (self.font.length - 1).to_string()
       -        ));
       +        ui.label(fl!(crate::LANGUAGE_LOADER, "font-editor-table", length = (self.font.length - 1).to_string()));
                egui::ScrollArea::vertical().show(ui, |ui| {
                    ui.horizontal_wrapped(|ui| {
                        for i in 0..self.font.length {
       @@ -672,27 +611,15 @@ impl Document for BitFontEditor {
        
                            response.on_hover_ui(|ui| {
                                ui.horizontal(|ui| {
       -                            ui.label(
       -                                RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-char_label"))
       -                                    .small(),
       -                            );
       -                            ui.label(
       -                                RichText::new(format!("{0}/0x{0:02X}", i))
       -                                    .small()
       -                                    .color(Color32::WHITE),
       -                            );
       +                            ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-char_label")).small());
       +                            ui.label(RichText::new(format!("{0}/0x{0:02X}", i)).small().color(Color32::WHITE));
                                });
                                ui.horizontal(|ui| {
       +                            ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-ascii_label")).small());
                                    ui.label(
       -                                RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-ascii_label"))
       -                                    .small(),
       -                            );
       -                            ui.label(
       -                                RichText::new(format!("'{0}'", unsafe {
       -                                    char::from_u32_unchecked(i as u32)
       -                                }))
       -                                .small()
       -                                .color(Color32::WHITE),
       +                                RichText::new(format!("'{0}'", unsafe { char::from_u32_unchecked(i as u32) }))
       +                                    .small()
       +                                    .color(Color32::WHITE),
                                    );
                                });
                            });
       @@ -701,10 +628,7 @@ impl Document for BitFontEditor {
                });
        
                if message.is_none() && self.send_update_message {
       -            message = Some(Message::UpdateFont(Box::new((
       -                self.last_updated_font.clone(),
       -                self.font.clone(),
       -            ))));
       +            message = Some(Message::UpdateFont(Box::new((self.last_updated_font.clone(), self.font.clone()))));
                    self.last_updated_font = self.font.clone();
                    self.send_update_message = false;
                }
       @@ -730,9 +654,6 @@ impl Document for BitFontEditor {
        
            fn destroy(&self, gl: &glow::Context) -> Option<Message> {
                self.buffer_view.lock().destroy(gl);
       -        Some(Message::UpdateFont(Box::new((
       -            self.last_updated_font.clone(),
       -            self.original_font.clone(),
       -        ))))
       +        Some(Message::UpdateFont(Box::new((self.last_updated_font.clone(), self.original_font.clone()))))
            }
        }
   DIR diff --git a/src/ui/editor/bitfont/undo.rs b/src/ui/editor/bitfont/undo.rs
       @@ -132,10 +132,7 @@ pub struct DownGlyph {
        
        impl DownGlyph {
            pub(crate) fn new(ch: char) -> Self {
       -        Self {
       -            ch,
       -            old_data: Vec::new(),
       -        }
       +        Self { ch, old_data: Vec::new() }
            }
        }
        
       @@ -168,10 +165,7 @@ pub struct UpGlyph {
        
        impl UpGlyph {
            pub(crate) fn new(ch: char) -> Self {
       -        Self {
       -            ch,
       -            old_data: Vec::new(),
       -        }
       +        Self { ch, old_data: Vec::new() }
            }
        }
        
       @@ -204,10 +198,7 @@ pub struct RightGlyph {
        
        impl RightGlyph {
            pub(crate) fn new(ch: char) -> Self {
       -        Self {
       -            ch,
       -            old_data: Vec::new(),
       -        }
       +        Self { ch, old_data: Vec::new() }
            }
        }
        
       @@ -241,10 +232,7 @@ pub struct LeftGlyph {
        
        impl LeftGlyph {
            pub(crate) fn new(ch: char) -> Self {
       -        Self {
       -            ch,
       -            old_data: Vec::new(),
       -        }
       +        Self { ch, old_data: Vec::new() }
            }
        }
        
       @@ -278,10 +266,7 @@ pub struct ClearGlyph {
        
        impl ClearGlyph {
            pub(crate) fn new(ch: char) -> Self {
       -        Self {
       -            ch,
       -            old_data: Vec::new(),
       -        }
       +        Self { ch, old_data: Vec::new() }
            }
        }
        
   DIR diff --git a/src/ui/editor/charfont/mod.rs b/src/ui/editor/charfont/mod.rs
       @@ -6,16 +6,13 @@ use eframe::{
        };
        use egui_extras::RetainedImage;
        use i18n_embed_fl::fl;
       -use icy_engine::{
       -    AttributedChar, BitFont, Buffer, EngineResult, FontGlyph, Layer, Size, TextAttribute, TextPane,
       -    TheDrawFont,
       -};
       +use icy_engine::{AttributedChar, BitFont, Buffer, EngineResult, FontGlyph, Layer, Size, TextAttribute, TextPane, TheDrawFont};
        use icy_engine_egui::{show_terminal_area, BufferView};
        
        use crate::{
            model::{click_imp::VALID_OUTLINE_CHARS, Tool},
       -    AnsiEditor, BitFontEditor, ClipboardHandler, Document, DocumentOptions, DrawGlyphStyle,
       -    Message, SelectOutlineDialog, TerminalResult, UndoHandler, SETTINGS,
       +    AnsiEditor, BitFontEditor, ClipboardHandler, Document, DocumentOptions, DrawGlyphStyle, Message, SelectOutlineDialog, TerminalResult, UndoHandler,
       +    SETTINGS,
        };
        
        pub struct CharFontEditor {
       @@ -105,165 +102,134 @@ impl Document for CharFontEditor {
                TheDrawFont::create_font_bundle(&self.fonts)
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        cur_tool: &mut Box<dyn Tool>,
       -        selected_tool: usize,
       -        options: &DocumentOptions,
       -    ) -> Option<Message> {
       -        SidePanel::left("side_panel")
       -            .default_width(200.0)
       -            .show_inside(ui, |ui| {
       -                ui.add_space(4.0);
       +    fn show_ui(&mut self, ui: &mut egui::Ui, cur_tool: &mut Box<dyn Tool>, selected_tool: usize, options: &DocumentOptions) -> Option<Message> {
       +        SidePanel::left("side_panel").default_width(200.0).show_inside(ui, |ui| {
       +            ui.add_space(4.0);
        
       -                if self.selected_font < self.fonts.len() {
       -                    ScrollArea::vertical().show(ui, |ui| {
       -                        ui.style_mut().wrap = Some(false);
       -
       -                        for i in 0..self.fonts.len() {
       -                            if ui
       -                                .selectable_value(&mut self.selected_font, i, &self.fonts[i].name)
       -                                .clicked()
       -                            {
       -                                self.save_old_selected_char();
       -                                self.selected_font = i;
       -                                self.old_selected_char_opt = None;
       -                                self.selected_char_opt = None;
       -                                self.show_selected_char();
       -                            }
       +            if self.selected_font < self.fonts.len() {
       +                ScrollArea::vertical().show(ui, |ui| {
       +                    ui.style_mut().wrap = Some(false);
       +
       +                    for i in 0..self.fonts.len() {
       +                        if ui.selectable_value(&mut self.selected_font, i, &self.fonts[i].name).clicked() {
       +                            self.save_old_selected_char();
       +                            self.selected_font = i;
       +                            self.old_selected_char_opt = None;
       +                            self.selected_char_opt = None;
       +                            self.show_selected_char();
                                }
       -                    });
       +                    }
       +                });
       +            }
       +            ui.separator();
       +
       +            ui.horizontal(|ui| {
       +                /*if ui.button("+").clicked() {
       +                    self.fonts.push(TheDrawFont::new(
       +                        "New Font",
       +                        icy_engine::FontType::Color,
       +                        1,
       +                    ));
       +                    self.selected_font = self.fonts.len() - 1;
       +                    self.selected_char_opt = None;
       +                    self.old_selected_char_opt = None;
       +                    self.show_selected_char();
       +                    self.undostack_len += 1;
       +                }*/
       +
       +                if ui.add_enabled(self.fonts.len() > 1, Button::new("🗑")).clicked() {
       +                    self.fonts.remove(self.selected_font);
       +                    self.selected_font = 0;
       +                    self.selected_char_opt = None;
       +                    self.old_selected_char_opt = None;
       +                    self.show_selected_char();
       +                    self.undostack_len += 1;
                        }
       -                ui.separator();
       -
       -                ui.horizontal(|ui| {
       -                    /*if ui.button("+").clicked() {
       -                        self.fonts.push(TheDrawFont::new(
       -                            "New Font",
       -                            icy_engine::FontType::Color,
       -                            1,
       -                        ));
       -                        self.selected_font = self.fonts.len() - 1;
       -                        self.selected_char_opt = None;
       -                        self.old_selected_char_opt = None;
       -                        self.show_selected_char();
       -                        self.undostack_len += 1;
       -                    }*/
        
       -                    if ui
       -                        .add_enabled(self.fonts.len() > 1, Button::new("🗑"))
       -                        .clicked()
       -                    {
       -                        self.fonts.remove(self.selected_font);
       -                        self.selected_font = 0;
       -                        self.selected_char_opt = None;
       -                        self.old_selected_char_opt = None;
       -                        self.show_selected_char();
       -                        self.undostack_len += 1;
       -                    }
       +                if ui.button(fl!(crate::LANGUAGE_LOADER, "tdf-editor-clone_button")).clicked() {
       +                    self.fonts.push(self.fonts[self.selected_font].clone());
       +                    self.selected_font = self.fonts.len() - 1;
       +                    self.selected_char_opt = None;
       +                    self.old_selected_char_opt = None;
       +                    self.show_selected_char();
       +                    self.undostack_len += 1;
       +                }
       +            });
       +        });
        
       +        TopBottomPanel::top("char_top_panel").exact_height(60.).show_inside(ui, |ui| {
       +            ui.add_space(4.0);
       +            if self.selected_font < self.fonts.len() {
       +                egui::Grid::new(
       +                    "font_grid
       +                    ",
       +                )
       +                .num_columns(4)
       +                .spacing([4.0, 4.0])
       +                .show(ui, |ui| {
       +                    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_name_label"));
       +                    });
                            if ui
       -                        .button(fl!(crate::LANGUAGE_LOADER, "tdf-editor-clone_button"))
       -                        .clicked()
       +                        .add(
       +                            TextEdit::singleline(&mut self.fonts[self.selected_font].name)
       +                                .min_size(Vec2::new(200.0, 22.))
       +                                .char_limit(12),
       +                        )
       +                        .changed()
                            {
       -                        self.fonts.push(self.fonts[self.selected_font].clone());
       -                        self.selected_font = self.fonts.len() - 1;
       -                        self.selected_char_opt = None;
       -                        self.old_selected_char_opt = None;
       -                        self.show_selected_char();
                                self.undostack_len += 1;
                            }
       -                });
       -            });
       -
       -        TopBottomPanel::top("char_top_panel")
       -            .exact_height(60.)
       -            .show_inside(ui, |ui| {
       -                ui.add_space(4.0);
       -                if self.selected_font < self.fonts.len() {
       -                    egui::Grid::new(
       -                        "font_grid
       -                    ",
       -                    )
       -                    .num_columns(4)
       -                    .spacing([4.0, 4.0])
       -                    .show(ui, |ui| {
       -                        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_name_label"));
       -                        });
       -                        if ui
       -                            .add(
       -                                TextEdit::singleline(&mut self.fonts[self.selected_font].name)
       -                                    .min_size(Vec2::new(200.0, 22.))
       -                                    .char_limit(12),
       -                            )
       -                            .changed()
       -                        {
       -                            self.undostack_len += 1;
       -                        }
       -
       -                        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_label"));
       -                        });
        
       -                        let text = match self.fonts[self.selected_font].font_type {
       -                            icy_engine::FontType::Outline => {
       -                                fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_outline")
       -                            }
       -                            icy_engine::FontType::Block => {
       -                                fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_block")
       -                            }
       -                            icy_engine::FontType::Color => {
       -                                fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_color")
       -                            }
       -                        };
       -                        ui.label(text);
       +                    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_label"));
       +                    });
        
       -                        ui.end_row();
       -                        ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       -                            ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-spacing_label"));
       -                        });
       -                        if ui
       -                            .add(
       -                                egui::DragValue::new(&mut self.fonts[self.selected_font].spaces)
       -                                    .clamp_range(0.0..=40.0),
       -                            )
       -                            .changed()
       -                        {
       -                            self.undostack_len += 1;
       +                    let text = match self.fonts[self.selected_font].font_type {
       +                        icy_engine::FontType::Outline => {
       +                            fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_outline")
                                }
       -                        ui.label("");
       -                        ui.label("");
       -                        ui.end_row();
       -                    });
       -                } else {
       -                    ui.heading(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "tdf-editor-no_font_selected_label"
       -                    ));
       -                }
       -            });
       +                        icy_engine::FontType::Block => {
       +                            fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_block")
       +                        }
       +                        icy_engine::FontType::Color => {
       +                            fl!(crate::LANGUAGE_LOADER, "tdf-editor-font_type_color")
       +                        }
       +                    };
       +                    ui.label(text);
        
       -        TopBottomPanel::bottom("char_bottom_panel")
       -            .exact_height(150.)
       -            .show_inside(ui, |ui| {
       -                if self.selected_font < self.fonts.len() {
       -                    self.show_char_selector(ui);
       -                    ui.add_space(4.0);
       -                    if self.selected_char_opt.is_some()
       -                        && ui
       -                            .button(fl!(crate::LANGUAGE_LOADER, "tdf-editor-clear_char_button"))
       -                            .clicked()
       +                    ui.end_row();
       +                    ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
       +                        ui.label(fl!(crate::LANGUAGE_LOADER, "tdf-editor-spacing_label"));
       +                    });
       +                    if ui
       +                        .add(egui::DragValue::new(&mut self.fonts[self.selected_font].spaces).clamp_range(0.0..=40.0))
       +                        .changed()
                            {
       -                        self.fonts[self.selected_font].clear_glyph(self.selected_char_opt.unwrap());
       -                        self.selected_char_opt = None;
       -                        self.old_selected_char_opt = None;
       -                        self.show_selected_char();
                                self.undostack_len += 1;
                            }
       +                    ui.label("");
       +                    ui.label("");
       +                    ui.end_row();
       +                });
       +            } else {
       +                ui.heading(fl!(crate::LANGUAGE_LOADER, "tdf-editor-no_font_selected_label"));
       +            }
       +        });
       +
       +        TopBottomPanel::bottom("char_bottom_panel").exact_height(150.).show_inside(ui, |ui| {
       +            if self.selected_font < self.fonts.len() {
       +                self.show_char_selector(ui);
       +                ui.add_space(4.0);
       +                if self.selected_char_opt.is_some() && ui.button(fl!(crate::LANGUAGE_LOADER, "tdf-editor-clear_char_button")).clicked() {
       +                    self.fonts[self.selected_font].clear_glyph(self.selected_char_opt.unwrap());
       +                    self.selected_char_opt = None;
       +                    self.old_selected_char_opt = None;
       +                    self.show_selected_char();
       +                    self.undostack_len += 1;
                        }
       -            });
       +            }
       +        });
        
                egui::CentralPanel::default().show_inside(ui, |ui| {
                    if self.selected_font < self.fonts.len() {
       @@ -413,19 +379,8 @@ impl Document for CharFontEditor {
                        }
                    }
                });
       -        let u = self
       -            .ansi_editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .undo_stack_len();
       -        let attr = self
       -            .ansi_editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .get_caret()
       -            .get_attribute();
       +        let u = self.ansi_editor.buffer_view.lock().get_edit_state().undo_stack_len();
       +        let attr = self.ansi_editor.buffer_view.lock().get_edit_state().get_caret().get_attribute();
                if self.last_update_preview != u || self.last_update_preview_attr != attr {
                    self.last_update_preview = u;
                    self.last_update_preview_attr = attr;
       @@ -526,42 +481,23 @@ impl CharFontEditor {
                    let lock = &mut self.ansi_editor.buffer_view.lock();
                    let mut attr = lock.get_caret().get_attribute();
        
       -            let _ = self
       -                .outline_previewbuffer_view
       -                .lock()
       -                .get_edit_state_mut()
       -                .clear_layer(0);
       -            self.outline_previewbuffer_view
       -                .lock()
       -                .get_caret_mut()
       -                .set_attr(attr);
       +            let _ = self.outline_previewbuffer_view.lock().get_edit_state_mut().clear_layer(0);
       +            self.outline_previewbuffer_view.lock().get_caret_mut().set_attr(attr);
                    if let Some(ch) = self.selected_char_opt {
       -                let size = self
       -                    .outline_previewbuffer_view
       -                    .lock()
       -                    .get_edit_state_mut()
       -                    .get_buffer()
       -                    .get_size();
       +                let size = self.outline_previewbuffer_view.lock().get_edit_state_mut().get_buffer().get_size();
        
                        if self.draw_outline_bg {
                            attr.set_foreground(8);
                            attr.set_background(0);
                            for y in 0..size.height {
                                for x in 0..size.width {
       -                            self.outline_previewbuffer_view
       -                                .lock()
       -                                .get_edit_state_mut()
       -                                .get_buffer_mut()
       -                                .layers[0]
       +                            self.outline_previewbuffer_view.lock().get_edit_state_mut().get_buffer_mut().layers[0]
                                        .set_char((x, y), AttributedChar::new('\u{B1}', attr));
                                }
                            }
                        }
        
       -                font.render(
       -                    self.outline_previewbuffer_view.lock().get_edit_state_mut(),
       -                    ch as u8,
       -                );
       +                font.render(self.outline_previewbuffer_view.lock().get_edit_state_mut(), ch as u8);
                    }
                }
            }
       @@ -570,8 +506,7 @@ impl CharFontEditor {
                {
                    self.save_old_selected_char();
                    let font = &self.fonts[self.selected_font];
       -            self.ansi_editor.outline_font_mode =
       -                matches!(font.font_type, icy_engine::FontType::Outline);
       +            self.ansi_editor.outline_font_mode = matches!(font.font_type, icy_engine::FontType::Outline);
                    let lock = &mut self.ansi_editor.buffer_view.lock();
        
                    let edit_state = &mut lock.get_edit_state_mut();
       @@ -591,14 +526,7 @@ impl CharFontEditor {
            }
        
            fn save_old_selected_char(&mut self) {
       -        if self
       -            .ansi_editor
       -            .buffer_view
       -            .lock()
       -            .get_edit_state()
       -            .undo_stack_len()
       -            == 0
       -        {
       +        if self.ansi_editor.buffer_view.lock().get_edit_state().undo_stack_len() == 0 {
                    return;
                }
                self.undostack_len += 1;
       @@ -626,13 +554,7 @@ impl CharFontEditor {
                                    h = y;
                                }
        
       -                        font.set_glyph(
       -                            ch,
       -                            FontGlyph {
       -                                size: Size::new(w, h),
       -                                data,
       -                            },
       -                        );
       +                        font.set_glyph(ch, FontGlyph { size: Size::new(w, h), data });
                            }
                            icy_engine::FontType::Block => {
                                let lock = &mut self.ansi_editor.buffer_view.lock();
       @@ -653,13 +575,7 @@ impl CharFontEditor {
                                    h = y;
                                }
        
       -                        font.set_glyph(
       -                            ch,
       -                            FontGlyph {
       -                                size: Size::new(w, h),
       -                                data,
       -                            },
       -                        );
       +                        font.set_glyph(ch, FontGlyph { size: Size::new(w, h), data });
                            }
                            icy_engine::FontType::Color => {
                                let lock = &mut self.ansi_editor.buffer_view.lock();
       @@ -681,13 +597,7 @@ impl CharFontEditor {
                                    h = y;
                                }
        
       -                        font.set_glyph(
       -                            ch,
       -                            FontGlyph {
       -                                size: Size::new(w, h),
       -                                data,
       -                            },
       -                        );
       +                        font.set_glyph(ch, FontGlyph { size: Size::new(w, h), data });
                            }
                        }
                    }
   DIR diff --git a/src/ui/main_window.rs b/src/ui/main_window.rs
       @@ -6,10 +6,9 @@ use std::{
        };
        
        use crate::{
       -    add_child, model::Tool, util::autosave, AnsiEditor, AskCloseFileDialog, BitFontEditor,
       -    ChannelToolWindow, CharFontEditor, CharTableToolWindow, Commands, Document, DocumentBehavior,
       -    DocumentTab, LayerToolWindow, Message, MinimapToolWindow, ModalDialog, Settings,
       -    SettingsDialog, ToolBehavior, ToolTab, TopBar, SETTINGS,
       +    add_child, model::Tool, util::autosave, AnsiEditor, AskCloseFileDialog, BitFontEditor, ChannelToolWindow, CharFontEditor, CharTableToolWindow, Commands,
       +    Document, DocumentBehavior, DocumentTab, LayerToolWindow, Message, MinimapToolWindow, ModalDialog, Settings, SettingsDialog, ToolBehavior, ToolTab, TopBar,
       +    SETTINGS,
        };
        use directories::UserDirs;
        use eframe::egui::{Button, PointerButton};
       @@ -116,25 +115,15 @@ impl MainWindow {
                let gl = cc.gl.clone().unwrap();
        
                let mut tool_tree = egui_tiles::Tree::<ToolTab>::empty("tool_tree");
       -        let layers = tool_tree
       -            .tiles
       -            .insert_pane(ToolTab::new(LayerToolWindow::default()));
       -        let channels = tool_tree
       -            .tiles
       -            .insert_pane(ToolTab::new(ChannelToolWindow::default()));
       -        let minimap = tool_tree
       -            .tiles
       -            .insert_pane(ToolTab::new(MinimapToolWindow::new(gl.clone())));
       -        let char_table = tool_tree
       -            .tiles
       -            .insert_pane(ToolTab::new(CharTableToolWindow::new(16)));
       +        let layers = tool_tree.tiles.insert_pane(ToolTab::new(LayerToolWindow::default()));
       +        let channels = tool_tree.tiles.insert_pane(ToolTab::new(ChannelToolWindow::default()));
       +        let minimap = tool_tree.tiles.insert_pane(ToolTab::new(MinimapToolWindow::new(gl.clone())));
       +        let char_table = tool_tree.tiles.insert_pane(ToolTab::new(CharTableToolWindow::new(16)));
        
                let tab = tool_tree.tiles.insert_tab_tile(vec![minimap, char_table]);
                let tab2 = tool_tree.tiles.insert_tab_tile(vec![layers, channels]);
                let vert_id = tool_tree.tiles.insert_vertical_tile(vec![tab, tab2]);
       -        if let Some(egui_tiles::Tile::Container(Container::Linear(linear))) =
       -            tool_tree.tiles.get_mut(vert_id)
       -        {
       +        if let Some(egui_tiles::Tile::Container(Container::Linear(linear))) = tool_tree.tiles.get_mut(vert_id) {
                    linear.shares.set_share(tab, 3.0);
                    linear.shares.set_share(tab2, 1.25);
                }
       @@ -185,11 +174,7 @@ impl MainWindow {
                        let file_name_str = file_name.unwrap().to_str().unwrap().to_string();
                        if let Ok(font) = BitFont::from_bytes(file_name_str, data) {
                            let id = self.create_id();
       -                    add_child(
       -                        &mut self.document_tree,
       -                        Some(full_path),
       -                        Box::new(BitFontEditor::new(&self.gl, id, font)),
       -                    );
       +                    add_child(&mut self.document_tree, Some(full_path), Box::new(BitFontEditor::new(&self.gl, id, font)));
                            return;
                        }
                    }
       @@ -212,11 +197,7 @@ impl MainWindow {
                        }
                        if let Ok(fonts) = TheDrawFont::from_tdf_bytes(data) {
                            let id = self.create_id();
       -                    add_child(
       -                        &mut self.document_tree,
       -                        Some(full_path),
       -                        Box::new(CharFontEditor::new(&self.gl, id, fonts)),
       -                    );
       +                    add_child(&mut self.document_tree, Some(full_path), Box::new(CharFontEditor::new(&self.gl, id, fonts)));
                            return;
                        }
                    }
       @@ -232,11 +213,7 @@ impl MainWindow {
                    Err(err) => {
                        log::error!("Error loading file: {}", err);
                        self.toasts
       -                    .error(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "error-load-file",
       -                        error = err.to_string()
       -                    ))
       +                    .error(fl!(crate::LANGUAGE_LOADER, "error-load-file", error = err.to_string()))
                            .set_duration(Some(Duration::from_secs(5)));
                    }
                }
       @@ -272,9 +249,7 @@ impl MainWindow {
                    }
                    Err(err) => {
                        log::error!("error loading file {path:?}: {err}");
       -                self.toasts
       -                    .error(format!("{err}"))
       -                    .set_duration(Some(Duration::from_secs(5)));
       +                self.toasts.error(format!("{err}")).set_duration(Some(Duration::from_secs(5)));
                    }
                }
            }
       @@ -442,11 +417,7 @@ impl MainWindow {
                self.modal_dialog = Some(Box::new(dialog));
            }
        
       -    pub(crate) fn run_editor_command<T>(
       -        &mut self,
       -        param: T,
       -        func: fn(&mut MainWindow, &mut AnsiEditor, T) -> Option<Message>,
       -    ) {
       +    pub(crate) fn run_editor_command<T>(&mut self, param: T, func: fn(&mut MainWindow, &mut AnsiEditor, T) -> Option<Message>) {
                let mut msg = None;
                if let Some(doc) = self.get_active_document() {
                    if let Ok(mut doc) = doc.lock() {
       @@ -463,11 +434,7 @@ impl MainWindow {
                    Err(err) => {
                        log::error!("Error: {}", err);
                        self.toasts
       -                    .error(fl!(
       -                        crate::LANGUAGE_LOADER,
       -                        "error-load-file",
       -                        error = err.to_string()
       -                    ))
       +                    .error(fl!(crate::LANGUAGE_LOADER, "error-load-file", error = err.to_string()))
                            .set_duration(Some(Duration::from_secs(5)));
                        None
                    }
       @@ -480,9 +447,7 @@ impl MainWindow {
                let mut msg = None;
                if let Some(egui_tiles::Tile::Pane(pane)) = self.document_tree.tiles.get(close_id) {
                    if !pane.is_dirty() {
       -                if let Some(egui_tiles::Tile::Pane(pane)) =
       -                    self.document_tree.tiles.get_mut(close_id)
       -                {
       +                if let Some(egui_tiles::Tile::Pane(pane)) = self.document_tree.tiles.get_mut(close_id) {
                            msg = pane.destroy(&self.gl);
                        }
                        self.document_tree.tiles.remove(close_id);
       @@ -496,11 +461,7 @@ impl MainWindow {
            }
        
            pub fn update_title(&mut self, frame: &mut eframe::Frame) {
       -        let id = if let Some((id, _)) = self.get_active_pane() {
       -            Some(id)
       -        } else {
       -            None
       -        };
       +        let id = if let Some((id, _)) = self.get_active_pane() { Some(id) } else { None };
        
                if let Some(id) = id {
                    if self.current_id == Some(id) {
       @@ -533,17 +494,11 @@ impl MainWindow {
                                    }
                                }
                                if root {
       -                            format!(
       -                                "/{}/",
       -                                parents.into_iter().rev().collect::<Vec<String>>().join("/")
       -                            )
       +                            format!("/{}/", parents.into_iter().rev().collect::<Vec<String>>().join("/"))
                                } else if parents.is_empty() {
                                    "~/".to_string()
                                } else {
       -                            format!(
       -                                "~/{}/",
       -                                parents.into_iter().rev().collect::<Vec<String>>().join("/")
       -                            )
       +                            format!("~/{}/", parents.into_iter().rev().collect::<Vec<String>>().join("/"))
                                }
                            } else {
                                parent.to_string_lossy().to_string()
       @@ -556,11 +511,7 @@ impl MainWindow {
                                &crate::VERSION
                            ));
                        } else {
       -                    frame.set_window_title(&format!(
       -                        "{} - iCY DRAW {}",
       -                        path.file_name().unwrap().to_str().unwrap(),
       -                        &crate::VERSION
       -                    ));
       +                    frame.set_window_title(&format!("{} - iCY DRAW {}", path.file_name().unwrap().to_str().unwrap(), &crate::VERSION));
                        }
                    }
                }
       @@ -591,12 +542,7 @@ pub fn is_font_extensions(ext: &str) -> bool {
                || "fon" == ext
        }
        
       -pub fn button_with_shortcut(
       -    ui: &mut Ui,
       -    enabled: bool,
       -    label: impl Into<String>,
       -    shortcut: impl Into<String>,
       -) -> Response {
       +pub fn button_with_shortcut(ui: &mut Ui, enabled: bool, label: impl Into<String>, shortcut: impl Into<String>) -> Response {
            let title = label.into();
            let button = Button::new(title).shortcut_text(shortcut.into());
            ui.add_enabled(enabled, button)
       @@ -616,10 +562,7 @@ impl eframe::App for MainWindow {
                                    if let Some(dir) = user.document_dir() {
                                        path = dir.join(path);
                                        while path.exists() {
       -                                    path = path.with_extension(format!(
       -                                        "1.{}",
       -                                        file.path.extension().unwrap().to_str().unwrap()
       -                                    ));
       +                                    path = path.with_extension(format!("1.{}", file.path.extension().unwrap().to_str().unwrap()));
                                        }
                                    }
                                }
       @@ -681,20 +624,13 @@ impl eframe::App for MainWindow {
        
                        if ice_mode.has_blink()
                            && ui
       -                        .selectable_label(
       -                            caret_attr.is_blinking(),
       -                            fl!(crate::LANGUAGE_LOADER, "color-is_blinking"),
       -                        )
       +                        .selectable_label(caret_attr.is_blinking(), fl!(crate::LANGUAGE_LOADER, "color-is_blinking"))
                                .clicked()
                        {
                            if let Some(doc) = self.get_active_document() {
                                if let Some(editor) = doc.lock().unwrap().get_ansi_editor() {
                                    caret_attr.set_is_blinking(!caret_attr.is_blinking());
       -                            editor
       -                                .buffer_view
       -                                .lock()
       -                                .get_caret_mut()
       -                                .set_attr(caret_attr);
       +                            editor.buffer_view.lock().get_caret_mut().set_attr(caret_attr);
                                }
                            }
                        }
       @@ -766,13 +702,9 @@ impl eframe::App for MainWindow {
                                let lock = &mut editor.buffer_view.lock();
                                let last = lock.get_buffer().layers.len().saturating_sub(1);
                                if let Some(layer) = lock.get_buffer().layers.last() {
       -                            if layer.role.is_paste()
       -                                && self.document_behavior.get_selected_tool() != PASTE_TOOL
       -                            {
       +                            if layer.role.is_paste() && self.document_behavior.get_selected_tool() != PASTE_TOOL {
                                        self.document_behavior.tools.lock().unwrap()[PASTE_TOOL] =
       -                                    Box::new(crate::model::paste_tool::PasteTool::new(
       -                                        self.document_behavior.get_selected_tool(),
       -                                    ));
       +                                    Box::new(crate::model::paste_tool::PasteTool::new(self.document_behavior.get_selected_tool()));
                                        self.document_behavior.set_selected_tool(PASTE_TOOL);
        
                                        lock.get_edit_state_mut().set_current_layer(last);
       @@ -796,9 +728,7 @@ impl eframe::App for MainWindow {
                                        }
                                        Err(err) => {
                                            log::error!("Error: {}", err);
       -                                    self.toasts
       -                                        .error(format!("{err}"))
       -                                        .set_duration(Some(Duration::from_secs(5)));
       +                                    self.toasts.error(format!("{err}")).set_duration(Some(Duration::from_secs(5)));
                                        }
                                    }
                                }
       @@ -811,9 +741,7 @@ impl eframe::App for MainWindow {
                                }
                                Err(err) => {
                                    log::error!("Error: {}", err);
       -                            self.toasts
       -                                .error(format!("{err}"))
       -                                .set_duration(Some(Duration::from_secs(5)));
       +                            self.toasts.error(format!("{err}")).set_duration(Some(Duration::from_secs(5)));
                                }
                            }
                        }
       @@ -949,19 +877,13 @@ fn read_outline_keys(ctx: &egui::Context) -> Option<Message> {
                result = Some(Message::SelectOutline(11));
            }
        
       -    if ctx.input(|i| {
       -        i.key_pressed(Key::F1) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)
       -    }) {
       +    if ctx.input(|i| i.key_pressed(Key::F1) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)) {
                result = Some(Message::SelectOutline(12));
            }
       -    if ctx.input(|i| {
       -        i.key_pressed(Key::F2) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)
       -    }) {
       +    if ctx.input(|i| i.key_pressed(Key::F2) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)) {
                result = Some(Message::SelectOutline(13));
            }
       -    if ctx.input(|i| {
       -        i.key_pressed(Key::F3) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)
       -    }) {
       +    if ctx.input(|i| i.key_pressed(Key::F3) && i.modifiers.shift && (i.modifiers.ctrl || i.modifiers.alt)) {
                result = Some(Message::SelectOutline(14));
            }
        
   DIR diff --git a/src/ui/messages.rs b/src/ui/messages.rs
       @@ -10,15 +10,11 @@ use eframe::{
            egui::{self},
            epaint::Vec2,
        };
       -use icy_engine::{
       -    util::pop_data, BitFont, EngineResult, IceMode, Layer, PaletteMode, SauceData, Size,
       -    TextAttribute, TextPane, TheDrawFont,
       -};
       +use icy_engine::{util::pop_data, BitFont, EngineResult, IceMode, Layer, PaletteMode, SauceData, Size, TextAttribute, TextPane, TheDrawFont};
        
        use crate::{
            util::autosave::{self},
       -    AnsiEditor, DocumentOptions, MainWindow, NewFileDialog, SaveFileDialog, SelectCharacterDialog,
       -    SelectOutlineDialog, Settings, PLUGINS, SETTINGS,
       +    AnsiEditor, DocumentOptions, MainWindow, NewFileDialog, SaveFileDialog, SelectCharacterDialog, SelectOutlineDialog, Settings, PLUGINS, SETTINGS,
        };
        
        #[derive(Clone)]
       @@ -178,11 +174,7 @@ impl MainWindow {
                        self.open_dialog(NewFileDialog::default());
                    }
                    Message::OpenFileDialog => {
       -                let mut initial_directory = if let Some(d) = self.get_active_pane_mut() {
       -                    d.get_path()
       -                } else {
       -                    None
       -                };
       +                let mut initial_directory = if let Some(d) = self.get_active_pane_mut() { d.get_path() } else { None };
                        set_default_initial_directory_opt(&mut initial_directory);
                        if let Some(mut path) = initial_directory {
                            while path.parent().is_some() && !path.is_dir() {
       @@ -231,13 +223,7 @@ impl MainWindow {
                            window.open_dialog(crate::ExportFileDialog::new(view.lock().get_buffer()));
                            None
                        });
       -                if let Some(editor) = self
       -                    .get_active_document()
       -                    .unwrap()
       -                    .lock()
       -                    .unwrap()
       -                    .get_ansi_editor()
       -                {
       +                if let Some(editor) = self.get_active_document().unwrap().lock().unwrap().get_ansi_editor() {
                            let view = editor.buffer_view.clone();
                            self.open_dialog(crate::ExportFileDialog::new(view.lock().get_buffer()));
                        }
       @@ -248,18 +234,14 @@ impl MainWindow {
                    Message::Undo => {
                        let mut msg = None;
                        if let Some(editor) = self.get_active_document() {
       -                    msg = self
       -                        .handle_result(editor.lock().unwrap().undo())
       -                        .unwrap_or(None);
       +                    msg = self.handle_result(editor.lock().unwrap().undo()).unwrap_or(None);
                        }
                        self.handle_message(msg);
                    }
                    Message::Redo => {
                        let mut msg = None;
                        if let Some(editor) = self.get_active_document() {
       -                    msg = self
       -                        .handle_result(editor.lock().unwrap().redo())
       -                        .unwrap_or(None);
       +                    msg = self.handle_result(editor.lock().unwrap().redo()).unwrap_or(None);
                        }
                        self.handle_message(msg);
                    }
       @@ -275,25 +257,11 @@ impl MainWindow {
                        });
                    }
                    Message::SelectNothing => {
       -                self.run_editor_command(0, |_, editor, _| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .clear_selection(),
       -                    )
       -                });
       +                self.run_editor_command(0, |_, editor, _| to_message(editor.buffer_view.lock().get_edit_state_mut().clear_selection()));
                    }
                    Message::DeleteSelection => {
                        self.run_editor_command(0, |_, editor: &mut AnsiEditor, _| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .erase_selection(),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().erase_selection())
                        });
                    }
                    Message::ShowCharacterSelectionDialog(ch) => {
       @@ -307,51 +275,27 @@ impl MainWindow {
                        self.open_dialog(crate::SelectFontDialog::new(fonts, selected_font));
                    }
                    Message::EditSauce => {
       -                if let Some(editor) = self
       -                    .get_active_document()
       -                    .unwrap()
       -                    .lock()
       -                    .unwrap()
       -                    .get_ansi_editor()
       -                {
       +                if let Some(editor) = self.get_active_document().unwrap().lock().unwrap().get_ansi_editor() {
                            let view = editor.buffer_view.clone();
                            self.open_dialog(crate::EditSauceDialog::new(view.lock().get_buffer()));
                        }
                    }
        
                    Message::SetCanvasSize => {
       -                if let Some(editor) = self
       -                    .get_active_document()
       -                    .unwrap()
       -                    .lock()
       -                    .unwrap()
       -                    .get_ansi_editor()
       -                {
       +                if let Some(editor) = self.get_active_document().unwrap().lock().unwrap().get_ansi_editor() {
                            let view = editor.buffer_view.clone();
                            self.open_dialog(crate::SetCanvasSizeDialog::new(view.lock().get_buffer()));
                        }
                    }
        
                    Message::EditLayer(i) => {
       -                if let Some(editor) = self
       -                    .get_active_document()
       -                    .unwrap()
       -                    .lock()
       -                    .unwrap()
       -                    .get_ansi_editor()
       -                {
       +                if let Some(editor) = self.get_active_document().unwrap().lock().unwrap().get_ansi_editor() {
                            let view = editor.buffer_view.clone();
                            self.open_dialog(crate::EditLayerDialog::new(view.lock().get_buffer(), i));
                        }
                    }
                    Message::ResizeLayer(i) => {
       -                if let Some(editor) = self
       -                    .get_active_document()
       -                    .unwrap()
       -                    .lock()
       -                    .unwrap()
       -                    .get_ansi_editor_mut()
       -                {
       +                if let Some(editor) = self.get_active_document().unwrap().lock().unwrap().get_ansi_editor_mut() {
                            let view = editor.buffer_view.clone();
                            self.open_dialog(crate::ResizeLayerDialog::new(view.lock().get_buffer(), i));
                        }
       @@ -375,13 +319,10 @@ impl MainWindow {
                        });
                    }
                    Message::RemoveLayer(cur_layer) => {
       -                self.run_editor_command(
       -                    cur_layer,
       -                    |_, editor: &mut crate::AnsiEditor, cur_layer| {
       -                        let mut lock = editor.buffer_view.lock();
       -                        to_message(lock.get_edit_state_mut().remove_layer(cur_layer))
       -                    },
       -                );
       +                self.run_editor_command(cur_layer, |_, editor: &mut crate::AnsiEditor, cur_layer| {
       +                    let mut lock = editor.buffer_view.lock();
       +                    to_message(lock.get_edit_state_mut().remove_layer(cur_layer))
       +                });
        
                        self.run_editor_command(0, |_, editor: &mut crate::AnsiEditor, _| {
                            let mut lock = editor.buffer_view.lock();
       @@ -413,32 +354,23 @@ impl MainWindow {
                        });
                    }
                    Message::DuplicateLayer(cur_layer) => {
       -                self.run_editor_command(
       -                    cur_layer,
       -                    |_, editor: &mut crate::AnsiEditor, cur_layer| {
       -                        let mut lock = editor.buffer_view.lock();
       -                        to_message(lock.get_edit_state_mut().duplicate_layer(cur_layer))
       -                    },
       -                );
       +                self.run_editor_command(cur_layer, |_, editor: &mut crate::AnsiEditor, cur_layer| {
       +                    let mut lock = editor.buffer_view.lock();
       +                    to_message(lock.get_edit_state_mut().duplicate_layer(cur_layer))
       +                });
                    }
                    Message::MergeLayerDown(cur_layer) => {
       -                self.run_editor_command(
       -                    cur_layer,
       -                    |_, editor: &mut crate::AnsiEditor, cur_layer| {
       -                        let mut lock = editor.buffer_view.lock();
       -                        to_message(lock.get_edit_state_mut().merge_layer_down(cur_layer))
       -                    },
       -                );
       +                self.run_editor_command(cur_layer, |_, editor: &mut crate::AnsiEditor, cur_layer| {
       +                    let mut lock = editor.buffer_view.lock();
       +                    to_message(lock.get_edit_state_mut().merge_layer_down(cur_layer))
       +                });
                    }
        
                    Message::ToggleLayerVisibility(cur_layer) => {
       -                self.run_editor_command(
       -                    cur_layer,
       -                    |_, editor: &mut crate::AnsiEditor, cur_layer| {
       -                        let mut lock = editor.buffer_view.lock();
       -                        to_message(lock.get_edit_state_mut().toggle_layer_visibility(cur_layer))
       -                    },
       -                );
       +                self.run_editor_command(cur_layer, |_, editor: &mut crate::AnsiEditor, cur_layer| {
       +                    let mut lock = editor.buffer_view.lock();
       +                    to_message(lock.get_edit_state_mut().toggle_layer_visibility(cur_layer))
       +                });
                    }
        
                    Message::SelectLayer(cur_layer) => {
       @@ -450,35 +382,19 @@ impl MainWindow {
        
                    Message::AnchorLayer => {
                        self.run_editor_command(0, |_, editor: &mut crate::AnsiEditor, _| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .anchor_layer(),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().anchor_layer())
                        });
                    }
        
                    Message::AddFloatingLayer => {
                        self.run_editor_command(0, |_, editor: &mut crate::AnsiEditor, _| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .add_floating_layer(),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().add_floating_layer())
                        });
                    }
        
                    Message::SetFontPage(page) => {
                        self.run_editor_command(page, |_, editor, page| {
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_font_page(page);
       +                    editor.buffer_view.lock().get_caret_mut().set_font_page(page);
        
                            let lock = &mut editor.buffer_view.lock();
                            let buf = &mut lock.get_buffer_mut();
       @@ -581,10 +497,7 @@ impl MainWindow {
                    Message::ResizeBuffer(resize_layer, w, h) => {
                        self.run_editor_command((resize_layer, w, h), |_, editor, (resize_layer, w, h)| {
                            let mut lock = editor.buffer_view.lock();
       -                    to_message(
       -                        lock.get_edit_state_mut()
       -                            .resize_buffer(resize_layer, Size::new(w, h)),
       -                    )
       +                    to_message(lock.get_edit_state_mut().resize_buffer(resize_layer, Size::new(w, h)))
                        });
                    }
        
       @@ -745,12 +658,11 @@ impl MainWindow {
        
                    Message::SetReferenceImage => {
                        self.run_editor_command(0, |window, editor, _| {
       -                    let mut initial_directory =
       -                        if let Some(d) = editor.buffer_view.lock().get_reference_image_path() {
       -                            d.parent().map(|p| p.to_path_buf())
       -                        } else {
       -                            None
       -                        };
       +                    let mut initial_directory = if let Some(d) = editor.buffer_view.lock().get_reference_image_path() {
       +                        d.parent().map(|p| p.to_path_buf())
       +                    } else {
       +                        None
       +                    };
                            set_default_initial_directory_opt(&mut initial_directory);
        
                            window.open_dialog(crate::OpenReferenceImageDialog::new(initial_directory));
       @@ -766,10 +678,7 @@ impl MainWindow {
                    }
                    Message::ClearReferenceImage => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let mut lock: eframe::epaint::mutex::MutexGuard<
       -                        '_,
       -                        icy_engine_egui::BufferView,
       -                    > = editor.buffer_view.lock();
       +                    let mut lock: eframe::epaint::mutex::MutexGuard<'_, icy_engine_egui::BufferView> = editor.buffer_view.lock();
                            lock.clear_reference_image();
                            None
                        });
       @@ -827,9 +736,7 @@ impl MainWindow {
                    }
        
                    Message::ZoomReset => {
       -                self.document_behavior
       -                    .document_options
       -                    .set_scale(DocumentOptions::default().get_scale());
       +                self.document_behavior.document_options.set_scale(DocumentOptions::default().get_scale());
                    }
        
                    Message::ZoomIn => {
       @@ -847,9 +754,7 @@ impl MainWindow {
                    Message::OpenFontDirectory => match Settings::get_font_diretory() {
                        Ok(dir) => {
                            if let Err(err) = open::that(dir) {
       -                        self.handle_message(Some(Message::ShowError(format!(
       -                            "Can't open font directory: {err}"
       -                        ))));
       +                        self.handle_message(Some(Message::ShowError(format!("Can't open font directory: {err}"))));
                            }
                        }
                        Err(err) => {
       @@ -860,9 +765,7 @@ impl MainWindow {
                    Message::OpenTdfDirectory => match Settings::get_tdf_diretory() {
                        Ok(dir) => {
                            if let Err(err) = open::that(dir) {
       -                        self.handle_message(Some(Message::ShowError(format!(
       -                            "Can't open font directory: {err}"
       -                        ))));
       +                        self.handle_message(Some(Message::ShowError(format!("Can't open font directory: {err}"))));
                            }
                        }
                        Err(err) => {
       @@ -873,9 +776,7 @@ impl MainWindow {
                    Message::OpenPalettesDirectory => match Settings::get_palettes_diretory() {
                        Ok(dir) => {
                            if let Err(err) = open::that(dir) {
       -                        self.handle_message(Some(Message::ShowError(format!(
       -                            "Can't open font directory: {err}"
       -                        ))));
       +                        self.handle_message(Some(Message::ShowError(format!("Can't open font directory: {err}"))));
                            }
                        }
                        Err(err) => {
       @@ -925,16 +826,8 @@ impl MainWindow {
        
                    Message::ToggleMirrorMode => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let mode = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state_mut()
       -                        .get_mirror_mode();
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_edit_state_mut()
       -                        .set_mirror_mode(!mode);
       +                    let mode = editor.buffer_view.lock().get_edit_state_mut().get_mirror_mode();
       +                    editor.buffer_view.lock().get_edit_state_mut().set_mirror_mode(!mode);
                            None
                        });
                    }
       @@ -944,67 +837,33 @@ impl MainWindow {
                    }
        
                    Message::InverseSelection => {
       -                self.run_editor_command(0, |_, editor, _| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .inverse_selection(),
       -                    )
       -                });
       +                self.run_editor_command(0, |_, editor, _| to_message(editor.buffer_view.lock().get_edit_state_mut().inverse_selection()));
                    }
        
                    Message::SetForeground(color) => {
                        self.run_editor_command(color, |_, editor, color| {
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_foreground(color);
       +                    editor.buffer_view.lock().get_caret_mut().set_foreground(color);
                            None
                        });
                    }
                    Message::SetForegroundRgb(r, g, b) => {
                        self.run_editor_command((r, g, b), |_, editor, (r, g, b)| {
       -                    let color = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer_mut()
       -                        .palette
       -                        .insert_color_rgb(r, g, b);
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_foreground(color);
       +                    let color = editor.buffer_view.lock().get_buffer_mut().palette.insert_color_rgb(r, g, b);
       +                    editor.buffer_view.lock().get_caret_mut().set_foreground(color);
                            None
                        });
                    }
        
                    Message::SetBackground(color) => {
                        self.run_editor_command(color, |_, editor, color| {
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_background(color);
       +                    editor.buffer_view.lock().get_caret_mut().set_background(color);
                            None
                        });
                    }
                    Message::SetBackgroundRgb(r, g, b) => {
                        self.run_editor_command((r, g, b), |_, editor, (r, g, b)| {
       -                    let color = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer_mut()
       -                        .palette
       -                        .insert_color_rgb(r, g, b);
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_background(color);
       +                    let color = editor.buffer_view.lock().get_buffer_mut().palette.insert_color_rgb(r, g, b);
       +                    editor.buffer_view.lock().get_caret_mut().set_background(color);
                            None
                        });
                    }
       @@ -1013,16 +872,11 @@ impl MainWindow {
                        let (old, new) = font_box.as_ref();
                        self.enumerate_documents(|_, pane| {
                            if let Some(editor) = pane.doc.lock().unwrap().get_ansi_editor() {
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_buffer_mut()
       -                            .font_iter_mut()
       -                            .for_each(|(_, font)| {
       -                                if font.glyphs == old.glyphs {
       -                                    *font = new.clone();
       -                                }
       -                            });
       +                        editor.buffer_view.lock().get_buffer_mut().font_iter_mut().for_each(|(_, font)| {
       +                            if font.glyphs == old.glyphs {
       +                                *font = new.clone();
       +                            }
       +                        });
                                editor.buffer_view.lock().redraw_font();
                            }
                        });
       @@ -1065,9 +919,7 @@ impl MainWindow {
                    Message::OpenPluginDirectory => match Settings::get_plugin_directory() {
                        Ok(dir) => {
                            if let Err(err) = open::that(dir) {
       -                        self.handle_message(Some(Message::ShowError(format!(
       -                            "Can't open font directory: {err}"
       -                        ))));
       +                        self.handle_message(Some(Message::ShowError(format!("Can't open font directory: {err}"))));
                            }
                        }
                        Err(err) => {
       @@ -1077,77 +929,37 @@ impl MainWindow {
        
                    Message::NextFgColor => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let palette_len =
       -                        editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       -                    let fg = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .get_attribute()
       -                        .get_foreground();
       -
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_foreground((fg + 1) % palette_len);
       +                    let palette_len = editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       +                    let fg = editor.buffer_view.lock().get_caret_mut().get_attribute().get_foreground();
       +
       +                    editor.buffer_view.lock().get_caret_mut().set_foreground((fg + 1) % palette_len);
                            None
                        });
                    }
                    Message::PreviousFgColor => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let palette_len =
       -                        editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       -                    let fg = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .get_attribute()
       -                        .get_foreground();
       -
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_foreground((fg + palette_len - 1) % palette_len);
       +                    let palette_len = editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       +                    let fg = editor.buffer_view.lock().get_caret_mut().get_attribute().get_foreground();
       +
       +                    editor.buffer_view.lock().get_caret_mut().set_foreground((fg + palette_len - 1) % palette_len);
                            None
                        });
                    }
                    Message::NextBgColor => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let palette_len =
       -                        editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       -                    let bg = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .get_attribute()
       -                        .get_background();
       -
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_background((bg + 1) % palette_len);
       +                    let palette_len = editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       +                    let bg = editor.buffer_view.lock().get_caret_mut().get_attribute().get_background();
       +
       +                    editor.buffer_view.lock().get_caret_mut().set_background((bg + 1) % palette_len);
                            None
                        });
                    }
                    Message::PreviousBgColor => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let palette_len =
       -                        editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       -                    let bg = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .get_attribute()
       -                        .get_background();
       -
       -                    editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_caret_mut()
       -                        .set_background((bg + palette_len - 1) % palette_len);
       +                    let palette_len = editor.buffer_view.lock().get_buffer_mut().palette.len() as u32;
       +                    let bg = editor.buffer_view.lock().get_caret_mut().get_attribute().get_background();
       +
       +                    editor.buffer_view.lock().get_caret_mut().set_background((bg + palette_len - 1) % palette_len);
                            None
                        });
                    }
       @@ -1158,146 +970,70 @@ impl MainWindow {
        
                    Message::ToggleLGAFont => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let use_lga = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer_mut()
       -                        .use_letter_spacing();
       -                    let mut sauce_data = if let Some(data) =
       -                        &editor.buffer_view.lock().get_buffer_mut().get_sauce()
       -                    {
       +                    let use_lga = editor.buffer_view.lock().get_buffer_mut().use_letter_spacing();
       +                    let mut sauce_data = if let Some(data) = &editor.buffer_view.lock().get_buffer_mut().get_sauce() {
                                data.clone()
                            } else {
                                SauceData::default()
                            };
                            sauce_data.use_letter_spacing = !use_lga;
        
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .update_sauce_data(Some(sauce_data)),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().update_sauce_data(Some(sauce_data)))
                        });
                    }
        
                    Message::ToggleAspectRatio => {
                        self.run_editor_command(0, |_, editor, _| {
       -                    let use_ar = editor
       -                        .buffer_view
       -                        .lock()
       -                        .get_buffer_mut()
       -                        .use_aspect_ratio();
       -                    let mut sauce_data = if let Some(data) =
       -                        &editor.buffer_view.lock().get_buffer_mut().get_sauce()
       -                    {
       +                    let use_ar = editor.buffer_view.lock().get_buffer_mut().use_aspect_ratio();
       +                    let mut sauce_data = if let Some(data) = &editor.buffer_view.lock().get_buffer_mut().get_sauce() {
                                data.clone()
                            } else {
                                SauceData::default()
                            };
                            sauce_data.use_aspect_ratio = !use_ar;
        
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .update_sauce_data(Some(sauce_data)),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().update_sauce_data(Some(sauce_data)))
                        });
                    }
        
                    Message::SwitchToFontPage(page) => {
                        self.run_editor_command(page, |_, editor, page| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .switch_to_font_page(page),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().switch_to_font_page(page))
                        });
                    }
                    Message::SetAnsiFont(page) => {
                        self.run_editor_command(page, |_, editor, page| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .set_ansi_font(page),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().set_ansi_font(page))
                        });
                    }
        
                    Message::SetSauceFont(name) => {
                        self.run_editor_command(name, |_, editor, name| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .set_sauce_font(&name),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().set_sauce_font(&name))
                        });
                    }
        
                    Message::SetFont(fnt) => {
       -                self.run_editor_command(fnt, |_, editor, fnt| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .set_font(*fnt),
       -                    )
       -                });
       +                self.run_editor_command(fnt, |_, editor, fnt| to_message(editor.buffer_view.lock().get_edit_state_mut().set_font(*fnt)));
                    }
                    Message::AddAnsiFont(page) => {
                        self.run_editor_command(page, |_, editor, page| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .add_ansi_font(page),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().add_ansi_font(page))
                        });
                    }
                    Message::AddFont(fnt) => {
       -                self.run_editor_command(fnt, |_, editor, fnt| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .add_font(*fnt),
       -                    )
       -                });
       +                self.run_editor_command(fnt, |_, editor, fnt| to_message(editor.buffer_view.lock().get_edit_state_mut().add_font(*fnt)));
                    }
        
                    Message::SwitchPaletteMode(mode) => {
                        self.run_editor_command(mode, |_, editor, mode| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .set_palette_mode(mode),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().set_palette_mode(mode))
                        });
                    }
        
                    Message::SwitchIceMode(mode) => {
                        self.run_editor_command(mode, |_, editor, mode| {
       -                    to_message(
       -                        editor
       -                            .buffer_view
       -                            .lock()
       -                            .get_edit_state_mut()
       -                            .set_ice_mode(mode),
       -                    )
       +                    to_message(editor.buffer_view.lock().get_edit_state_mut().set_ice_mode(mode))
                        });
                    }
                }
   DIR diff --git a/src/ui/palette_editor.rs b/src/ui/palette_editor.rs
       @@ -4,12 +4,7 @@ use eframe::epaint::{Color32, Pos2, Rect, Rounding, Stroke, Vec2};
        use icy_engine::{Palette, TextAttribute};
        use std::cmp::min;
        
       -pub fn palette_switcher(
       -    ctx: &egui::Context,
       -    ui: &mut egui::Ui,
       -    caret_attr: &TextAttribute,
       -    palette: &Palette,
       -) -> Option<Message> {
       +pub fn palette_switcher(ctx: &egui::Context, ui: &mut egui::Ui, caret_attr: &TextAttribute, palette: &Palette) -> Option<Message> {
            let mut result = None;
        
            let tex_id = SWAP_SVG.texture_id(ctx);
       @@ -32,8 +27,7 @@ pub fn palette_switcher(
        
            painter.rect_filled(
                Rect::from_min_size(
       -            Pos2::new(height - rect_height + 1., height - rect_height + 1.)
       -                + rect.left_top().to_vec2(),
       +            Pos2::new(height - rect_height + 1., height - rect_height + 1.) + rect.left_top().to_vec2(),
                    Vec2::new(rect_height - 2., rect_height - 2.),
                ),
                Rounding::none(),
       @@ -43,8 +37,7 @@ pub fn palette_switcher(
            let (r, g, b) = palette.get_rgb(caret_attr.get_background() as usize);
            painter.rect_filled(
                Rect::from_min_size(
       -            Pos2::new(height - rect_height + 2., height - rect_height + 2.)
       -                + rect.left_top().to_vec2(),
       +            Pos2::new(height - rect_height + 2., height - rect_height + 2.) + rect.left_top().to_vec2(),
                    Vec2::new(rect_height - 4., rect_height - 4.),
                ),
                Rounding::none(),
       @@ -52,29 +45,20 @@ pub fn palette_switcher(
            );
        
            painter.rect_filled(
       -        Rect::from_min_size(
       -            Pos2::new(0., 0.) + rect.left_top().to_vec2(),
       -            Vec2::new(rect_height, rect_height),
       -        ),
       +        Rect::from_min_size(Pos2::new(0., 0.) + rect.left_top().to_vec2(), Vec2::new(rect_height, rect_height)),
                Rounding::none(),
                Color32::BLACK,
            );
        
            painter.rect_filled(
       -        Rect::from_min_size(
       -            Pos2::new(1., 1.) + rect.left_top().to_vec2(),
       -            Vec2::new(rect_height - 2., rect_height - 2.),
       -        ),
       +        Rect::from_min_size(Pos2::new(1., 1.) + rect.left_top().to_vec2(), Vec2::new(rect_height - 2., rect_height - 2.)),
                Rounding::none(),
                Color32::WHITE,
            );
        
            let (r, g, b) = palette.get_rgb(caret_attr.get_foreground() as usize);
            painter.rect_filled(
       -        Rect::from_min_size(
       -            Pos2::new(2., 2.) + rect.left_top().to_vec2(),
       -            Vec2::new(rect_height - 4., rect_height - 4.),
       -        ),
       +        Rect::from_min_size(Pos2::new(2., 2.) + rect.left_top().to_vec2(), Vec2::new(rect_height - 4., rect_height - 4.)),
                Rounding::none(),
                Color32::from_rgb(r, g, b),
            );
       @@ -86,10 +70,7 @@ pub fn palette_switcher(
            let overlap = 2.0;
        
            painter.rect_filled(
       -        Rect::from_min_size(
       -            Pos2::new(rh - overlap, height - rh - overlap) + rect.left_top().to_vec2(),
       -            Vec2::new(rh, rh),
       -        ),
       +        Rect::from_min_size(Pos2::new(rh - overlap, height - rh - overlap) + rect.left_top().to_vec2(), Vec2::new(rh, rh)),
                Rounding::none(),
                Color32::from_rgb(r ^ 0xFF, g ^ 0xFF, b ^ 0xFF),
            );
       @@ -162,8 +143,7 @@ pub fn palette_editor_16(
                let right_border = 4.0;
                let items_per_row = if palette.len() < 64 { 8 } else { 16 };
        
       -        let upper_limit =
       -            (palette.len() as f32 / items_per_row as f32).ceil() as usize * items_per_row;
       +        let upper_limit = (palette.len() as f32 / items_per_row as f32).ceil() as usize * items_per_row;
        
                let height = (ui.available_width() - right_border) / items_per_row as f32;
        
       @@ -193,69 +173,38 @@ pub fn palette_editor_16(
                // paint fg marker
                let stroke = Stroke::new(1., Color32::WHITE);
                let origin = Pos2::new(
       -            stroke_rect.left()
       -                + (caret_attr.get_foreground() % items_per_row as u32) as f32 * height,
       -            stroke_rect.top()
       -                + (caret_attr.get_foreground() / items_per_row as u32) as f32 * height,
       +            stroke_rect.left() + (caret_attr.get_foreground() % items_per_row as u32) as f32 * height,
       +            stroke_rect.top() + (caret_attr.get_foreground() / items_per_row as u32) as f32 * height,
                );
                painter.line_segment([origin, origin + Vec2::new(marker_len, 0.)], stroke);
                painter.line_segment([origin, origin + Vec2::new(0., marker_len)], stroke);
                for i in 0..marker_len as usize {
       -            painter.line_segment(
       -                [
       -                    origin + Vec2::new(i as f32, 0.),
       -                    origin + Vec2::new(0., i as f32),
       -                ],
       -                stroke,
       -            );
       +            painter.line_segment([origin + Vec2::new(i as f32, 0.), origin + Vec2::new(0., i as f32)], stroke);
                }
                let stroke = Stroke::new(1., Color32::GRAY);
                painter.line_segment([origin, origin + Vec2::new(marker_len, 0.)], stroke);
                painter.line_segment([origin, origin + Vec2::new(0., marker_len)], stroke);
       -        painter.line_segment(
       -            [
       -                origin + Vec2::new(marker_len, 0.),
       -                origin + Vec2::new(0., marker_len),
       -            ],
       -            stroke,
       -        );
       +        painter.line_segment([origin + Vec2::new(marker_len, 0.), origin + Vec2::new(0., marker_len)], stroke);
        
                // paint bg marker
                let stroke = Stroke::new(1., Color32::WHITE);
                let origin = Pos2::new(
       -            stroke_rect.left()
       -                + (1 + caret_attr.get_background() % items_per_row as u32) as f32 * height,
       -            stroke_rect.top()
       -                + (1 + caret_attr.get_background() / items_per_row as u32) as f32 * height,
       +            stroke_rect.left() + (1 + caret_attr.get_background() % items_per_row as u32) as f32 * height,
       +            stroke_rect.top() + (1 + caret_attr.get_background() / items_per_row as u32) as f32 * height,
                );
                painter.line_segment([origin, origin - Vec2::new(marker_len, 0.)], stroke);
                painter.line_segment([origin, origin - Vec2::new(0., marker_len)], stroke);
                for i in 0..marker_len as usize {
       -            painter.line_segment(
       -                [
       -                    origin - Vec2::new(i as f32, 0.),
       -                    origin - Vec2::new(0., i as f32),
       -                ],
       -                stroke,
       -            );
       +            painter.line_segment([origin - Vec2::new(i as f32, 0.), origin - Vec2::new(0., i as f32)], stroke);
                }
                let stroke = Stroke::new(1., Color32::GRAY);
                painter.line_segment([origin, origin - Vec2::new(marker_len, 0.)], stroke);
                painter.line_segment([origin, origin - Vec2::new(0., marker_len)], stroke);
       -        painter.line_segment(
       -            [
       -                origin - Vec2::new(marker_len, 0.),
       -                origin - Vec2::new(0., marker_len),
       -            ],
       -            stroke,
       -        );
       +        painter.line_segment([origin - Vec2::new(marker_len, 0.), origin - Vec2::new(0., marker_len)], stroke);
        
                if let Some(hp) = response.hover_pos() {
                    let pos = (hp.to_vec2() - stroke_rect.left_top().to_vec2()) / Vec2::new(height, height);
       -            let color = min(
       -                palette.len() as u32 - 1,
       -                pos.x as u32 + pos.y as u32 * items_per_row as u32,
       -            );
       +            let color = min(palette.len() as u32 - 1, pos.x as u32 + pos.y as u32 * items_per_row as u32);
        
                    if response.hovered() {
                        response = response.on_hover_ui(|ui| {
   DIR diff --git a/src/ui/settings.rs b/src/ui/settings.rs
       @@ -45,12 +45,10 @@ impl Default for CharacterSet {
                    table: Vec::new(),
                };
                for i in crate::DEFAULT_CHAR_SET_TABLE {
       -            default_char_set
       -                .table
       -                .push(i.iter().fold(Vec::new(), |mut s, c| {
       -                    s.push(char::from_u32(*c as u32).unwrap());
       -                    s
       -                }));
       +            default_char_set.table.push(i.iter().fold(Vec::new(), |mut s, c| {
       +                s.push(char::from_u32(*c as u32).unwrap());
       +                s
       +            }));
                }
                default_char_set
            }
       @@ -63,9 +61,7 @@ impl Settings {
                    return ' ';
                }
                let char_set = &self.character_sets[table_idx];
       -        if self.character_set >= char_set.table.len()
       -            || ch >= char_set.table[self.character_set].len()
       -        {
       +        if self.character_set >= char_set.table.len() || ch >= char_set.table[self.character_set].len() {
                    return ' ';
                }
                char_set.table[self.character_set][ch]
       @@ -185,10 +181,7 @@ impl Settings {
                        if fs::create_dir_all(&dir).is_err() {
                            return Err(IcyDrawError::ErrorCreatingDirectory(format!("{dir:?}")).into());
                        }
       -                fs::write(
       -                    dir.join("elite-writing.lua"),
       -                    include_bytes!("../plugins/elite-writing.lua.txt"),
       -                )?;
       +                fs::write(dir.join("elite-writing.lua"), include_bytes!("../plugins/elite-writing.lua.txt"))?;
                    }
                    return Ok(dir);
                }
   DIR diff --git a/src/ui/tool_docking.rs b/src/ui/tool_docking.rs
       @@ -9,9 +9,7 @@ pub struct ToolTab {
        }
        impl ToolTab {
            pub(crate) fn new<T: 'static + ToolWindow>(tool_window: T) -> Self {
       -        Self {
       -            doc: Box::new(tool_window),
       -        }
       +        Self { doc: Box::new(tool_window) }
            }
        }
        
       @@ -28,12 +26,7 @@ impl egui_tiles::Behavior<ToolTab> for ToolBehavior {
                WidgetText::RichText(egui::RichText::new(title).small())
            }
        
       -    fn pane_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        _tile_id: egui_tiles::TileId,
       -        pane: &mut ToolTab,
       -    ) -> egui_tiles::UiResponse {
       +    fn pane_ui(&mut self, ui: &mut egui::Ui, _tile_id: egui_tiles::TileId, pane: &mut ToolTab) -> egui_tiles::UiResponse {
                let message = pane.doc.show_ui(ui, self.active_document.clone());
                if self.message.is_none() {
                    self.message = message;
       @@ -56,9 +49,5 @@ impl egui_tiles::Behavior<ToolTab> for ToolBehavior {
        pub trait ToolWindow {
            fn get_title(&self) -> String;
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        active_document: Option<Arc<Mutex<Box<dyn Document>>>>,
       -    ) -> Option<Message>;
       +    fn show_ui(&mut self, ui: &mut egui::Ui, active_document: Option<Arc<Mutex<Box<dyn Document>>>>) -> Option<Message>;
        }
   DIR diff --git a/src/ui/tool_switcher.rs b/src/ui/tool_switcher.rs
       @@ -4,11 +4,7 @@ use eframe::{
            epaint::{pos2, Rect, Rounding, Vec2},
        };
        
       -pub fn add_tool_switcher(
       -    ctx: &egui::Context,
       -    ui: &mut egui::Ui,
       -    arg: &MainWindow,
       -) -> Option<Message> {
       +pub fn add_tool_switcher(ctx: &egui::Context, ui: &mut egui::Ui, arg: &MainWindow) -> Option<Message> {
            let mut msg = None;
            let spacing = 4.0;
            let icon_size = 28.0;
       @@ -31,29 +27,17 @@ pub fn add_tool_switcher(
                    let rect = Rect::from_min_size(pos.floor(), Vec2::new(icon_size, icon_size));
                    let response = ui.interact(rect, id.with(i), Sense::click());
                    if i == arg.document_behavior.get_selected_tool() {
       -                ui.painter().rect_filled(
       -                    rect.expand(2.0),
       -                    Rounding::same(4.0),
       -                    ui.style().visuals.extreme_bg_color,
       -                );
       -                ui.painter().rect_stroke(
       -                    rect.expand(2.0),
       -                    Rounding::same(4.0),
       -                    ui.style().visuals.window_stroke,
       -                );
       +                ui.painter()
       +                    .rect_filled(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
       +                ui.painter()
       +                    .rect_stroke(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.window_stroke);
                    }
        
                    if response.hovered() {
       -                ui.painter().rect_filled(
       -                    rect.expand(2.0),
       -                    Rounding::same(4.0),
       -                    ui.style().visuals.widgets.active.bg_fill,
       -                );
       -                ui.painter().rect_stroke(
       -                    rect.expand(2.0),
       -                    Rounding::same(4.0),
       -                    ui.style().visuals.window_stroke,
       -                );
       +                ui.painter()
       +                    .rect_filled(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.widgets.active.bg_fill);
       +                ui.painter()
       +                    .rect_stroke(rect.expand(2.0), Rounding::same(4.0), ui.style().visuals.window_stroke);
                    }
        
                    let painter = ui.painter_at(rect);
   DIR diff --git a/src/ui/tools/channels.rs b/src/ui/tools/channels.rs
       @@ -13,21 +13,14 @@ impl ToolWindow for ChannelToolWindow {
                fl!(crate::LANGUAGE_LOADER, "channel_tool_title")
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        active_document: Option<Arc<Mutex<Box<dyn Document>>>>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut egui::Ui, active_document: Option<Arc<Mutex<Box<dyn Document>>>>) -> Option<Message> {
                if let Some(doc) = active_document {
                    if let Some(editor) = doc.lock().unwrap().get_ansi_editor() {
                        ui.add_space(8.0);
                        ui.horizontal(|ui| {
                            ui.add_space(4.0);
                            if ui
       -                        .checkbox(
       -                            &mut editor.buffer_view.lock().use_fg,
       -                            fl!(crate::LANGUAGE_LOADER, "channel_tool_fg"),
       -                        )
       +                        .checkbox(&mut editor.buffer_view.lock().use_fg, fl!(crate::LANGUAGE_LOADER, "channel_tool_fg"))
                                .changed()
                            {
                                editor.buffer_view.lock().redraw_view();
       @@ -36,10 +29,7 @@ impl ToolWindow for ChannelToolWindow {
                        ui.horizontal(|ui| {
                            ui.add_space(4.0);
                            if ui
       -                        .checkbox(
       -                            &mut editor.buffer_view.lock().use_bg,
       -                            fl!(crate::LANGUAGE_LOADER, "channel_tool_bg"),
       -                        )
       +                        .checkbox(&mut editor.buffer_view.lock().use_bg, fl!(crate::LANGUAGE_LOADER, "channel_tool_bg"))
                                .changed()
                            {
                                editor.buffer_view.lock().redraw_view();
       @@ -49,9 +39,7 @@ impl ToolWindow for ChannelToolWindow {
                } else {
                    ui.vertical_centered(|ui| {
                        ui.add_space(8.0);
       -                ui.label(
       -                    RichText::new(fl!(crate::LANGUAGE_LOADER, "no_document_selected")).small(),
       -                );
       +                ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "no_document_selected")).small());
                    });
                }
                None
   DIR diff --git a/src/ui/tools/char_table.rs b/src/ui/tools/char_table.rs
       @@ -34,86 +34,67 @@ impl CharTableToolWindow {
            pub fn show_plain_char_table(&mut self, ui: &mut egui::Ui) -> Option<char> {
                let mut something_hovered = false;
                let mut result = None;
       -        egui::ScrollArea::vertical()
       -            .id_source("char_table_scroll_area")
       -            .show(ui, |ui| {
       -                ui.add_space(4.0);
       -                ui.horizontal(|ui| {
       -                    let scale = 2.0;
       +        egui::ScrollArea::vertical().id_source("char_table_scroll_area").show(ui, |ui| {
       +            ui.add_space(4.0);
       +            ui.horizontal(|ui| {
       +                let scale = 2.0;
        
       -                    let width = self.char_table.width() as f32 * scale;
       +                let width = self.char_table.width() as f32 * scale;
        
       -                    let height = self.char_table.height() as f32 * scale;
       -                    ui.add_space((ui.available_width() - width) / 2.0);
       +                let height = self.char_table.height() as f32 * scale;
       +                ui.add_space((ui.available_width() - width) / 2.0);
        
       -                    let (id, rect) = ui.allocate_space([width, height].into());
       -                    let response = ui.interact(rect, id, Sense::click());
       -                    ui.painter().image(
       -                        self.char_table.texture_id(ui.ctx()),
       -                        Rect::from_min_size(
       -                            Pos2::new(rect.left(), rect.top()),
       -                            Vec2::new(width, height),
       -                        ),
       -                        Rect::from_min_max(Pos2::new(0.0, 0.0), Pos2::new(1.0, 1.0)),
       -                        Color32::WHITE,
       -                    );
       -                    let fw = scale * self.font.size.width as f32;
       -                    let fh = scale * self.font.size.height as f32;
       -                    if response.clicked() {
       -                        result = self.hover_char;
       -                    }
       -                    if response.hovered() {
       -                        if let Some(pos) = response.hover_pos() {
       -                            something_hovered = true;
       -                            let pos = pos - response.rect.min;
       -                            let ch =
       -                                (pos.x / fw) as usize + self.buffer_width * (pos.y / fh) as usize;
       -                            let ch = unsafe { char::from_u32_unchecked(ch as u32) };
       -                            let hover_char = Some(ch);
       -                            if self.hover_char != hover_char {
       -                                self.hover_char = hover_char;
       -                                self.hover_char_image = create_hover_image(&self.font, ch, 14);
       -                            }
       +                let (id, rect) = ui.allocate_space([width, height].into());
       +                let response = ui.interact(rect, id, Sense::click());
       +                ui.painter().image(
       +                    self.char_table.texture_id(ui.ctx()),
       +                    Rect::from_min_size(Pos2::new(rect.left(), rect.top()), Vec2::new(width, height)),
       +                    Rect::from_min_max(Pos2::new(0.0, 0.0), Pos2::new(1.0, 1.0)),
       +                    Color32::WHITE,
       +                );
       +                let fw = scale * self.font.size.width as f32;
       +                let fh = scale * self.font.size.height as f32;
       +                if response.clicked() {
       +                    result = self.hover_char;
       +                }
       +                if response.hovered() {
       +                    if let Some(pos) = response.hover_pos() {
       +                        something_hovered = true;
       +                        let pos = pos - response.rect.min;
       +                        let ch = (pos.x / fw) as usize + self.buffer_width * (pos.y / fh) as usize;
       +                        let ch = unsafe { char::from_u32_unchecked(ch as u32) };
       +                        let hover_char = Some(ch);
       +                        if self.hover_char != hover_char {
       +                            self.hover_char = hover_char;
       +                            self.hover_char_image = create_hover_image(&self.font, ch, 14);
       +                        }
        
       -                            let x = (ch as usize) % self.buffer_width;
       -                            let y = (ch as usize) / self.buffer_width;
       +                        let x = (ch as usize) % self.buffer_width;
       +                        let y = (ch as usize) / self.buffer_width;
        
       -                            let rect = Rect::from_min_size(
       -                                rect.min + Vec2::new(x as f32 * fw, y as f32 * fh),
       -                                Vec2::new(fw, fh),
       -                            );
       +                        let rect = Rect::from_min_size(rect.min + Vec2::new(x as f32 * fw, y as f32 * fh), Vec2::new(fw, fh));
        
       -                            ui.painter().image(
       -                                self.hover_char_image.texture_id(ui.ctx()),
       -                                rect.expand(2.0),
       -                                Rect::from_min_max(Pos2::new(0.0, 0.0), Pos2::new(1.0, 1.0)),
       -                                Color32::WHITE,
       -                            );
       -                        }
       +                        ui.painter().image(
       +                            self.hover_char_image.texture_id(ui.ctx()),
       +                            rect.expand(2.0),
       +                            Rect::from_min_max(Pos2::new(0.0, 0.0), Pos2::new(1.0, 1.0)),
       +                            Color32::WHITE,
       +                        );
                            }
       -                });
       +                }
                    });
       +        });
                ui.horizontal(|ui| {
                    ui.add_space(4.0);
                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-font_label")).small());
       -            ui.label(
       -                RichText::new(self.font.name.to_string())
       -                    .small()
       -                    .color(Color32::WHITE),
       -            );
       +            ui.label(RichText::new(self.font.name.to_string()).small().color(Color32::WHITE));
                });
        
                if let Some(ch) = self.hover_char {
                    ui.horizontal(|ui| {
                        ui.add_space(4.0);
       -                ui.label(
       -                    RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-char_label")).small(),
       -                );
       -                ui.label(
       -                    RichText::new(format!("{0}/0x{0:02X}", ch as u32))
       -                        .small()
       -                        .color(Color32::WHITE),
       -                );
       +                ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "font-view-char_label")).small());
       +                ui.label(RichText::new(format!("{0}/0x{0:02X}", ch as u32)).small().color(Color32::WHITE));
                    });
                } else {
                    ui.horizontal(|ui| {
       @@ -148,10 +129,7 @@ impl CharTableToolWindow {
                        ui.add_space(12.0);
        
                        ui.label(fl!(crate::LANGUAGE_LOADER, "font-view-font_page_label"));
       -                if ui
       -                    .selectable_label(false, RichText::new("◀").font(FontId::proportional(14.)))
       -                    .clicked()
       -                {
       +                if ui.selectable_label(false, RichText::new("◀").font(FontId::proportional(14.))).clicked() {
                            let mut prev = font_page;
                            let mut last = 0;
                            for (page, _) in editor.buffer_view.lock().get_buffer().font_iter() {
       @@ -172,10 +150,7 @@ impl CharTableToolWindow {
                        }
                        ui.label(RichText::new(font_page.to_string()));
        
       -                if ui
       -                    .selectable_label(false, RichText::new("▶").font(FontId::proportional(14.)))
       -                    .clicked()
       -                {
       +                if ui.selectable_label(false, RichText::new("▶").font(FontId::proportional(14.))).clicked() {
                            let mut next = font_page;
                            let mut first = usize::MAX;
                            for (page, _) in editor.buffer_view.lock().get_buffer().font_iter() {
       @@ -213,10 +188,7 @@ fn create_font_image(font: &BitFont, buffer_width: usize) -> RetainedImage {
            for ch in 0..256 {
                buffer.layers[0].set_char(
                    (ch % buffer_width, ch / buffer_width),
       -            AttributedChar::new(
       -                unsafe { char::from_u32_unchecked(ch as u32) },
       -                TextAttribute::default(),
       -            ),
       +            AttributedChar::new(unsafe { char::from_u32_unchecked(ch as u32) }, TextAttribute::default()),
                );
            }
            create_retained_image(&buffer).with_options(TextureOptions::NEAREST)
       @@ -228,10 +200,7 @@ fn create_hover_image(font: &BitFont, ch: char, color: u32) -> RetainedImage {
            let mut attr = TextAttribute::default();
            attr.set_foreground(color);
        
       -    buffer.layers[0].set_char(
       -        (0, 0),
       -        AttributedChar::new(unsafe { char::from_u32_unchecked(ch as u32) }, attr),
       -    );
       +    buffer.layers[0].set_char((0, 0), AttributedChar::new(unsafe { char::from_u32_unchecked(ch as u32) }, attr));
            create_retained_image(&buffer).with_options(TextureOptions::NEAREST)
        }
        
       @@ -240,11 +209,7 @@ impl ToolWindow for CharTableToolWindow {
                fl!(crate::LANGUAGE_LOADER, "char_table_tool_title")
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        active_document: Option<Arc<Mutex<Box<dyn Document>>>>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut egui::Ui, active_document: Option<Arc<Mutex<Box<dyn Document>>>>) -> Option<Message> {
                if let Some(doc) = active_document {
                    if let Some(editor) = doc.lock().unwrap().get_ansi_editor() {
                        return self.show_char_table(ui, editor);
   DIR diff --git a/src/ui/tools/layer_view.rs b/src/ui/tools/layer_view.rs
       @@ -18,11 +18,7 @@ impl ToolWindow for LayerToolWindow {
                fl!(crate::LANGUAGE_LOADER, "layer_tool_title")
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        active_document: Option<Arc<Mutex<Box<dyn Document>>>>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut egui::Ui, active_document: Option<Arc<Mutex<Box<dyn Document>>>>) -> Option<Message> {
                if let Some(doc) = active_document {
                    if let Some(editor) = doc.lock().unwrap().get_ansi_editor() {
                        return show_layer_view(ui, editor);
       @@ -56,27 +52,16 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
        
                    if paste_mode {
                        let r = medium_hover_button(ui, &crate::ADD_LAYER_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "add_layer_tooltip")).small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "add_layer_tooltip")).small());
                        });
        
                        if r.clicked() {
                            result = Some(Message::AddFloatingLayer);
                        }
       -                let role = editor
       -                    .buffer_view
       -                    .lock()
       -                    .get_edit_state()
       -                    .get_cur_layer()
       -                    .unwrap()
       -                    .role;
       +                let role = editor.buffer_view.lock().get_edit_state().get_cur_layer().unwrap().role;
                        if matches!(role, icy_engine::Role::PastePreview) {
                            let r = medium_hover_button(ui, &crate::ANCHOR_SVG).on_hover_ui(|ui| {
       -                        ui.label(
       -                            RichText::new(fl!(crate::LANGUAGE_LOADER, "anchor_layer_tooltip"))
       -                                .small(),
       -                        );
       +                        ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "anchor_layer_tooltip")).small());
                            });
        
                            if r.clicked() && cur_layer < max {
       @@ -85,9 +70,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                        }
        
                        let r = medium_hover_button(ui, &crate::DELETE_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "delete_layer_tooltip")).small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "delete_layer_tooltip")).small());
                        });
        
                        if r.clicked() && cur_layer < max {
       @@ -95,9 +78,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                        }
                    } else {
                        let r = medium_hover_button(ui, &crate::ADD_LAYER_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "add_layer_tooltip")).small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "add_layer_tooltip")).small());
                        });
        
                        if r.clicked() {
       @@ -105,9 +86,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                        }
        
                        let r = medium_hover_button(ui, &crate::MOVE_UP_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "move_layer_up_tooltip")).small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "move_layer_up_tooltip")).small());
                        });
        
                        if r.clicked() {
       @@ -115,10 +94,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                        }
        
                        let r = medium_hover_button(ui, &crate::MOVE_DOWN_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "move_layer_down_tooltip"))
       -                            .small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "move_layer_down_tooltip")).small());
                        });
        
                        if r.clicked() {
       @@ -126,9 +102,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                        }
        
                        let r = medium_hover_button(ui, &crate::DELETE_SVG).on_hover_ui(|ui| {
       -                    ui.label(
       -                        RichText::new(fl!(crate::LANGUAGE_LOADER, "delete_layer_tooltip")).small(),
       -                    );
       +                    ui.label(RichText::new(fl!(crate::LANGUAGE_LOADER, "delete_layer_tooltip")).small());
                        });
        
                        if r.clicked() && cur_layer < max {
       @@ -158,35 +132,19 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                                let back_painter = ui.painter_at(back_rect);
        
                                if response.hovered() {
       -                            back_painter.rect_filled(
       -                                back_rect,
       -                                Rounding::none(),
       -                                ui.style().visuals.widgets.active.bg_fill,
       -                            );
       +                            back_painter.rect_filled(back_rect, Rounding::none(), ui.style().visuals.widgets.active.bg_fill);
                                } else if i == cur_layer {
       -                            back_painter.rect_filled(
       -                                back_rect,
       -                                Rounding::none(),
       -                                ui.style().visuals.extreme_bg_color,
       -                            );
       +                            back_painter.rect_filled(back_rect, Rounding::none(), ui.style().visuals.extreme_bg_color);
                                }
        
       -                        let stroke_rect = Rect::from_min_size(
       -                            back_rect.min + Vec2::new(0.0, 1.0),
       -                            Vec2::new(22.0, 22.0),
       -                        );
       -                        let visible_icon_response =
       -                            ui.interact(stroke_rect, id.with("visible"), Sense::click());
       +                        let stroke_rect = Rect::from_min_size(back_rect.min + Vec2::new(0.0, 1.0), Vec2::new(22.0, 22.0));
       +                        let visible_icon_response = ui.interact(stroke_rect, id.with("visible"), Sense::click());
        
                                let painter = ui.painter_at(stroke_rect);
        
                                if let Some(color) = color {
                                    let (r, g, b) = color.into();
       -                            painter.rect_filled(
       -                                stroke_rect,
       -                                Rounding::none(),
       -                                Color32::from_rgb(r, g, b),
       -                            );
       +                            painter.rect_filled(stroke_rect, Rounding::none(), Color32::from_rgb(r, g, b));
                                }
        
                                let image = if is_visible {
       @@ -210,13 +168,7 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                                };
                                let font_id = TextStyle::Button.resolve(ui.style());
        
       -                        back_painter.text(
       -                            stroke_rect.right_center() + Vec2::new(4., 0.),
       -                            Align2::LEFT_CENTER,
       -                            title,
       -                            font_id,
       -                            color,
       -                        );
       +                        back_painter.text(stroke_rect.right_center() + Vec2::new(4., 0.), Align2::LEFT_CENTER, title, font_id, color);
        
                                if visible_icon_response.clicked() {
                                    result = Some(Message::ToggleLayerVisibility(i));
       @@ -225,76 +177,34 @@ fn show_layer_view(ui: &mut egui::Ui, editor: &AnsiEditor) -> Option<Message> {
                                if !paste_mode {
                                    response = response.context_menu(|ui| {
                                        ui.set_width(250.);
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_layer_properties"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_layer_properties")).clicked() {
                                            result = Some(Message::EditLayer(i));
                                            ui.close_menu();
                                        }
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_resize_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_resize_layer")).clicked() {
                                            result = Some(Message::ResizeLayer(i));
                                            ui.close_menu();
                                        }
                                        ui.separator();
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_new_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_new_layer")).clicked() {
                                            result = Some(Message::AddNewLayer(i));
                                            ui.close_menu();
                                        }
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_duplicate_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_duplicate_layer")).clicked() {
                                            result = Some(Message::DuplicateLayer(i));
                                            ui.close_menu();
                                        }
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_merge_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_merge_layer")).clicked() {
                                            result = Some(Message::MergeLayerDown(i));
                                            ui.close_menu();
                                        }
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_delete_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_delete_layer")).clicked() {
                                            result = Some(Message::RemoveLayer(i));
                                            ui.close_menu();
                                        }
                                        ui.separator();
        
       -                                if ui
       -                                    .button(fl!(
       -                                        crate::LANGUAGE_LOADER,
       -                                        "layer_tool_menu_clear_layer"
       -                                    ))
       -                                    .clicked()
       -                                {
       +                                if ui.button(fl!(crate::LANGUAGE_LOADER, "layer_tool_menu_clear_layer")).clicked() {
                                            result = Some(Message::ClearLayer(i));
                                            ui.close_menu();
                                        }
       @@ -323,11 +233,7 @@ pub fn medium_hover_button(ui: &mut egui::Ui, image: &RetainedImage) -> egui::Re
            let painter = ui.painter_at(rect);
        
            let tint = if response.hovered() {
       -        ui.painter().rect_filled(
       -            rect,
       -            Rounding::same(4.0),
       -            ui.style().visuals.extreme_bg_color,
       -        );
       +        ui.painter().rect_filled(rect, Rounding::same(4.0), ui.style().visuals.extreme_bg_color);
        
                ui.visuals().widgets.active.fg_stroke.color
            } else {
   DIR diff --git a/src/ui/tools/minimap_view.rs b/src/ui/tools/minimap_view.rs
       @@ -23,11 +23,7 @@ impl ToolWindow for MinimapToolWindow {
                fl!(crate::LANGUAGE_LOADER, "minimap_tool_title")
            }
        
       -    fn show_ui(
       -        &mut self,
       -        ui: &mut egui::Ui,
       -        active_document: Option<Arc<Mutex<Box<dyn Document>>>>,
       -    ) -> Option<Message> {
       +    fn show_ui(&mut self, ui: &mut egui::Ui, active_document: Option<Arc<Mutex<Box<dyn Document>>>>) -> Option<Message> {
                if let Some(doc) = active_document {
                    if let Some(editor) = doc.lock().unwrap().get_ansi_editor_mut() {
                        return self.show_minimap(ui, editor);
       @@ -44,30 +40,16 @@ impl ToolWindow for MinimapToolWindow {
        impl MinimapToolWindow {
            pub fn show_minimap(&mut self, ui: &mut egui::Ui, editor: &mut AnsiEditor) -> Option<Message> {
                let undo_stack = editor.buffer_view.lock().get_edit_state().undo_stack_len() as i32;
       -        let cur_palette_hash = editor
       -            .buffer_view
       -            .lock()
       -            .get_buffer_mut()
       -            .palette
       -            .get_checksum();
       -        if undo_stack != self.undo_size
       -            || self.last_id != editor.id
       -            || self.palette_hash != cur_palette_hash
       -        {
       +        let cur_palette_hash = editor.buffer_view.lock().get_buffer_mut().palette.get_checksum();
       +        if undo_stack != self.undo_size || self.last_id != editor.id || self.palette_hash != cur_palette_hash {
                    self.undo_size = undo_stack;
                    self.last_id = editor.id;
                    let bv = editor.buffer_view.lock();
                    let buffer = bv.get_buffer();
       -            self.buffer_view
       -                .lock()
       -                .get_buffer_mut()
       -                .set_size(buffer.get_size());
       +            self.buffer_view.lock().get_buffer_mut().set_size(buffer.get_size());
                    self.buffer_view.lock().get_buffer_mut().layers = buffer.layers.clone();
                    self.buffer_view.lock().get_buffer_mut().palette = buffer.palette.clone();
       -            self.buffer_view
       -                .lock()
       -                .get_buffer_mut()
       -                .set_font_table(buffer.get_font_table());
       +            self.buffer_view.lock().get_buffer_mut().set_font_table(buffer.get_font_table());
                    self.palette_hash = cur_palette_hash;
                    self.buffer_view.lock().redraw_font();
                    self.buffer_view.lock().redraw_view();
       @@ -75,14 +57,7 @@ impl MinimapToolWindow {
        
                self.buffer_view.lock().use_fg = editor.buffer_view.lock().use_fg;
                self.buffer_view.lock().use_bg = editor.buffer_view.lock().use_bg;
       -        let w = (ui.available_width()
       -            / self
       -                .buffer_view
       -                .lock()
       -                .get_buffer()
       -                .get_font_dimensions()
       -                .width as f32)
       -            .floor();
       +        let w = (ui.available_width() / self.buffer_view.lock().get_buffer().get_font_dimensions().width as f32).floor();
        
                let scalex = (w / self.buffer_view.lock().get_width() as f32).min(2.0);
                let scaley = if self.buffer_view.lock().get_buffer_mut().use_aspect_ratio() {
       @@ -108,21 +83,17 @@ impl MinimapToolWindow {
                    opt.scroll_offset_y = Some(next_scroll_pos.y);
                }
        
       -        let (response, ours) =
       -            icy_engine_egui::show_terminal_area(ui, self.buffer_view.clone(), opt);
       +        let (response, ours) = icy_engine_egui::show_terminal_area(ui, self.buffer_view.clone(), opt);
        
                let theirs = editor.buffer_view.lock().calc.clone();
        
                let their_total_size = Vec2::new(theirs.char_width, theirs.char_height) * theirs.char_size;
       -        let their_buffer_size =
       -            Vec2::new(theirs.buffer_char_width, theirs.buffer_char_height) * theirs.char_size;
       +        let their_buffer_size = Vec2::new(theirs.buffer_char_width, theirs.buffer_char_height) * theirs.char_size;
        
                let our_total_size = Vec2::new(ours.char_width, ours.char_height) * ours.char_size;
        
       -        let tmax_y: f32 =
       -            theirs.font_height * (theirs.char_height - theirs.buffer_char_height).max(0.0);
       -        let tmax_x: f32 =
       -            theirs.font_width * (theirs.real_width as f32 - theirs.buffer_char_width).max(0.0);
       +        let tmax_y: f32 = theirs.font_height * (theirs.char_height - theirs.buffer_char_height).max(0.0);
       +        let tmax_x: f32 = theirs.font_width * (theirs.real_width as f32 - theirs.buffer_char_width).max(0.0);
        
                let size = our_total_size * their_buffer_size / their_total_size;
                let tx = theirs.char_scroll_position.x / tmax_x.max(1.0);
       @@ -147,9 +118,7 @@ impl MinimapToolWindow {
                    ui.ctx().request_repaint();
                }
        
       -        if pos.x + size.x > ours.terminal_rect.size().x
       -            || pos.y + size.y > ours.terminal_rect.size().y
       -        {
       +        if pos.x + size.x > ours.terminal_rect.size().x || pos.y + size.y > ours.terminal_rect.size().y {
                    let p = pos + size - ours.terminal_rect.size();
                    self.next_scroll_pos = Some(ours.char_scroll_position + p / ours.scale);
                    ui.ctx().request_repaint();
       @@ -158,10 +127,8 @@ impl MinimapToolWindow {
                if response.dragged() {
                    if let Some(pos) = response.interact_pointer_pos() {
                        let pos = (pos - ours.buffer_rect.min) / ours.scale + ours.char_scroll_position;
       -                editor.next_scroll_x_position =
       -                    Some(pos.x - theirs.buffer_char_width * theirs.font_width / 2.0);
       -                editor.next_scroll_y_position =
       -                    Some(pos.y - theirs.buffer_char_height * theirs.font_height / 2.0);
       +                editor.next_scroll_x_position = Some(pos.x - theirs.buffer_char_width * theirs.font_width / 2.0);
       +                editor.next_scroll_y_position = Some(pos.y - theirs.buffer_char_height * theirs.font_height / 2.0);
                        ui.ctx().request_repaint();
                    }
                }
   DIR diff --git a/src/ui/top_bar.rs b/src/ui/top_bar.rs
       @@ -31,18 +31,12 @@ impl TopBar {
        }
        
        impl MainWindow {
       -    pub fn show_top_bar(
       -        &mut self,
       -        ctx: &egui::Context,
       -        frame: &mut eframe::Frame,
       -    ) -> Option<Message> {
       +    pub fn show_top_bar(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) -> Option<Message> {
                let mut result = None;
        
       -        TopBottomPanel::top("top_panel")
       -            .exact_height(24.0)
       -            .show(ctx, |ui| {
       -                result = self.main_menu(ui, frame);
       -            });
       +        TopBottomPanel::top("top_panel").exact_height(24.0).show(ctx, |ui| {
       +            result = self.main_menu(ui, frame);
       +        });
                result
            }
        
       @@ -74,25 +68,22 @@ impl MainWindow {
        
                        self.commands[0].new_file.ui(ui, &mut result);
                        self.commands[0].open_file.ui(ui, &mut result);
       -                ui.menu_button(
       -                    fl!(crate::LANGUAGE_LOADER, "menu-open_recent"),
       -                    |ui| unsafe {
       -                        ui.style_mut().wrap = Some(false);
       +                ui.menu_button(fl!(crate::LANGUAGE_LOADER, "menu-open_recent"), |ui| unsafe {
       +                    ui.style_mut().wrap = Some(false);
        
       -                        let get_recent_files = SETTINGS.get_recent_files();
       -                        if !get_recent_files.is_empty() {
       -                            for file in get_recent_files.iter().rev() {
       -                                let button = ui.button(file.file_name().unwrap().to_str().unwrap());
       -                                if button.clicked() {
       -                                    result = Some(Message::TryLoadFile(file.clone()));
       -                                    ui.close_menu();
       -                                }
       +                    let get_recent_files = SETTINGS.get_recent_files();
       +                    if !get_recent_files.is_empty() {
       +                        for file in get_recent_files.iter().rev() {
       +                            let button = ui.button(file.file_name().unwrap().to_str().unwrap());
       +                            if button.clicked() {
       +                                result = Some(Message::TryLoadFile(file.clone()));
       +                                ui.close_menu();
                                    }
       -                            ui.separator();
                                }
       -                        self.commands[0].clear_recent_open.ui(ui, &mut result);
       -                    },
       -                );
       +                        ui.separator();
       +                    }
       +                    self.commands[0].clear_recent_open.ui(ui, &mut result);
       +                });
                        ui.separator();
                        self.commands[0].save.ui(ui, &mut result);
                        self.commands[0].save_as.ui(ui, &mut result);
       @@ -113,11 +104,7 @@ impl MainWindow {
                                let button = button_with_shortcut(
                                    ui,
                                    enabled,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "menu-undo-op",
       -                                op = doc.lock().unwrap().undo_description().unwrap()
       -                            ),
       +                            fl!(crate::LANGUAGE_LOADER, "menu-undo-op", op = doc.lock().unwrap().undo_description().unwrap()),
                                    "Ctrl+Z",
                                );
                                if button.clicked() {
       @@ -132,11 +119,7 @@ impl MainWindow {
                                let button = button_with_shortcut(
                                    ui,
                                    true,
       -                            fl!(
       -                                crate::LANGUAGE_LOADER,
       -                                "menu-redo-op",
       -                                op = doc.lock().unwrap().redo_description().unwrap()
       -                            ),
       +                            fl!(crate::LANGUAGE_LOADER, "menu-redo-op", op = doc.lock().unwrap().redo_description().unwrap()),
                                    "Ctrl+Shift+Z",
                                );
                                if button.clicked() {
       @@ -161,23 +144,13 @@ impl MainWindow {
                            ui.style_mut().wrap = Some(false);
                            ui.set_min_width(200.0);
        
       -                    let button = button_with_shortcut(
       -                        ui,
       -                        pop_data(BUFFER_DATA).is_some(),
       -                        fl!(crate::LANGUAGE_LOADER, "menu-paste-as-new-image"),
       -                        "",
       -                    );
       +                    let button = button_with_shortcut(ui, pop_data(BUFFER_DATA).is_some(), fl!(crate::LANGUAGE_LOADER, "menu-paste-as-new-image"), "");
                            if button.clicked() {
                                result = Some(Message::PasteAsNewImage);
                                ui.close_menu();
                            }
        
       -                    let button = button_with_shortcut(
       -                        ui,
       -                        pop_data(BUFFER_DATA).is_some(),
       -                        fl!(crate::LANGUAGE_LOADER, "menu-paste-as-brush"),
       -                        "",
       -                    );
       +                    let button = button_with_shortcut(ui, pop_data(BUFFER_DATA).is_some(), fl!(crate::LANGUAGE_LOADER, "menu-paste-as-brush"), "");
                            if button.clicked() {
                                result = Some(Message::PasteAsBrush);
                                ui.close_menu();
       @@ -215,11 +188,7 @@ impl MainWindow {
        
                        ui.separator();
                        if ui
       -                    .add_enabled(
       -                        has_buffer,
       -                        egui::Button::new(fl!(crate::LANGUAGE_LOADER, "menu-edit-sauce"))
       -                            .wrap(false),
       -                    )
       +                    .add_enabled(has_buffer, egui::Button::new(fl!(crate::LANGUAGE_LOADER, "menu-edit-sauce")).wrap(false))
                            .clicked()
                        {
                            result = Some(Message::EditSauce);
       @@ -230,11 +199,7 @@ impl MainWindow {
                        ui.separator();
        
                        if ui
       -                    .add_enabled(
       -                        has_buffer,
       -                        egui::Button::new(fl!(crate::LANGUAGE_LOADER, "menu-set-canvas-size"))
       -                            .wrap(false),
       -                    )
       +                    .add_enabled(has_buffer, egui::Button::new(fl!(crate::LANGUAGE_LOADER, "menu-set-canvas-size")).wrap(false))
                            .clicked()
                        {
                            result = Some(Message::SetCanvasSize);
       @@ -281,85 +246,70 @@ impl MainWindow {
                                        }
        
                                        if ui
       +                                    .selectable_label(lock.get_buffer().ice_mode == IceMode::Blink, fl!(crate::LANGUAGE_LOADER, "menu-ice-mode-blink"))
       +                                    .clicked()
       +                                {
       +                                    result = Some(Message::SwitchIceMode(IceMode::Blink));
       +                                    ui.close_menu();
       +                                }
       +
       +                                if ui
       +                                    .selectable_label(lock.get_buffer().ice_mode == IceMode::Ice, fl!(crate::LANGUAGE_LOADER, "menu-ice-mode-ice"))
       +                                    .clicked()
       +                                {
       +                                    result = Some(Message::SwitchIceMode(IceMode::Ice));
       +                                    ui.close_menu();
       +                                }
       +                            });
       +
       +                            ui.menu_button(fl!(crate::LANGUAGE_LOADER, "menu-palette-mode"), |ui| {
       +                                ui.style_mut().wrap = Some(false);
       +                                ui.set_min_width(240.0);
       +
       +                                if ui
                                            .selectable_label(
       -                                        lock.get_buffer().ice_mode == IceMode::Blink,
       -                                        fl!(crate::LANGUAGE_LOADER, "menu-ice-mode-blink"),
       +                                        lock.get_buffer().palette_mode == PaletteMode::RGB,
       +                                        fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-unrestricted"),
                                            )
                                            .clicked()
                                        {
       -                                    result = Some(Message::SwitchIceMode(IceMode::Blink));
       +                                    result = Some(Message::SwitchPaletteMode(PaletteMode::RGB));
                                            ui.close_menu();
                                        }
        
                                        if ui
                                            .selectable_label(
       -                                        lock.get_buffer().ice_mode == IceMode::Ice,
       -                                        fl!(crate::LANGUAGE_LOADER, "menu-ice-mode-ice"),
       +                                        lock.get_buffer().palette_mode == PaletteMode::Fixed16,
       +                                        fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-dos"),
                                            )
                                            .clicked()
                                        {
       -                                    result = Some(Message::SwitchIceMode(IceMode::Ice));
       +                                    result = Some(Message::SwitchPaletteMode(PaletteMode::Fixed16));
       +                                    ui.close_menu();
       +                                }
       +
       +                                if ui
       +                                    .selectable_label(
       +                                        lock.get_buffer().palette_mode == PaletteMode::Free16,
       +                                        fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-free"),
       +                                    )
       +                                    .clicked()
       +                                {
       +                                    result = Some(Message::SwitchPaletteMode(PaletteMode::Free16));
                                            ui.close_menu();
                                        }
       -                            });
        
       -                            ui.menu_button(
       -                                fl!(crate::LANGUAGE_LOADER, "menu-palette-mode"),
       -                                |ui| {
       -                                    ui.style_mut().wrap = Some(false);
       -                                    ui.set_min_width(240.0);
       -
       -                                    if ui
       -                                        .selectable_label(
       -                                            lock.get_buffer().palette_mode == PaletteMode::RGB,
       -                                            fl!(
       -                                                crate::LANGUAGE_LOADER,
       -                                                "menu-palette-mode-unrestricted"
       -                                            ),
       -                                        )
       -                                        .clicked()
       -                                    {
       -                                        result = Some(Message::SwitchPaletteMode(PaletteMode::RGB));
       -                                        ui.close_menu();
       -                                    }
       -
       -                                    if ui
       -                                        .selectable_label(
       -                                            lock.get_buffer().palette_mode == PaletteMode::Fixed16,
       -                                            fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-dos"),
       -                                        )
       -                                        .clicked()
       -                                    {
       -                                        result =
       -                                            Some(Message::SwitchPaletteMode(PaletteMode::Fixed16));
       -                                        ui.close_menu();
       -                                    }
       -
       -                                    if ui
       -                                        .selectable_label(
       -                                            lock.get_buffer().palette_mode == PaletteMode::Free16,
       -                                            fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-free"),
       -                                        )
       -                                        .clicked()
       -                                    {
       -                                        result =
       -                                            Some(Message::SwitchPaletteMode(PaletteMode::Free16));
       -                                        ui.close_menu();
       -                                    }
       -
       -                                    if ui
       -                                        .selectable_label(
       -                                            lock.get_buffer().palette_mode == PaletteMode::Free8,
       -                                            fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-free8"),
       -                                        )
       -                                        .clicked()
       -                                    {
       -                                        result =
       -                                            Some(Message::SwitchPaletteMode(PaletteMode::Free8));
       -                                        ui.close_menu();
       -                                    }
       -                                },
       -                            );
       +                                if ui
       +                                    .selectable_label(
       +                                        lock.get_buffer().palette_mode == PaletteMode::Free8,
       +                                        fl!(crate::LANGUAGE_LOADER, "menu-palette-mode-free8"),
       +                                    )
       +                                    .clicked()
       +                                {
       +                                    result = Some(Message::SwitchPaletteMode(PaletteMode::Free8));
       +                                    ui.close_menu();
       +                                }
       +                            });
        
                                    ui.separator();
                                }
       @@ -377,9 +327,7 @@ impl MainWindow {
                        self.commands[0].next_bg_color.ui(ui, &mut result);
                        self.commands[0].prev_bg_color.ui(ui, &mut result);
        
       -                self.commands[0]
       -                    .pick_attribute_under_caret
       -                    .ui(ui, &mut result);
       +                self.commands[0].pick_attribute_under_caret.ui(ui, &mut result);
                        self.commands[0].toggle_color.ui(ui, &mut result);
                        self.commands[0].switch_to_default_color.ui(ui, &mut result);
                    });
       @@ -462,10 +410,7 @@ impl MainWindow {
                            fl!(
                                crate::LANGUAGE_LOADER,
                                "menu-zoom",
       -                        zoom = format!(
       -                            "{}%",
       -                            (100. * self.document_behavior.document_options.get_scale().x) as i32
       -                        )
       +                        zoom = format!("{}%", (100. * self.document_behavior.document_options.get_scale().x) as i32)
                            ),
                            |ui| {
                                ui.style_mut().wrap = Some(false);
       @@ -478,33 +423,23 @@ impl MainWindow {
                                ui.separator();
        
                                if ui.button("4:1 400%").clicked() {
       -                            self.document_behavior
       -                                .document_options
       -                                .set_scale(Vec2::new(4.0, 4.0));
       +                            self.document_behavior.document_options.set_scale(Vec2::new(4.0, 4.0));
                                    ui.close_menu();
                                }
                                if ui.button("2:1 200%").clicked() {
       -                            self.document_behavior
       -                                .document_options
       -                                .set_scale(Vec2::new(2.0, 2.0));
       +                            self.document_behavior.document_options.set_scale(Vec2::new(2.0, 2.0));
                                    ui.close_menu();
                                }
                                if ui.button("1:1 100%").clicked() {
       -                            self.document_behavior
       -                                .document_options
       -                                .set_scale(Vec2::new(1.0, 1.0));
       +                            self.document_behavior.document_options.set_scale(Vec2::new(1.0, 1.0));
                                    ui.close_menu();
                                }
                                if ui.button("1:2 50%").clicked() {
       -                            self.document_behavior
       -                                .document_options
       -                                .set_scale(Vec2::new(0.5, 0.5));
       +                            self.document_behavior.document_options.set_scale(Vec2::new(0.5, 0.5));
                                    ui.close_menu();
                                }
                                if ui.button("1:4 25%").clicked() {
       -                            self.document_behavior
       -                                .document_options
       -                                .set_scale(Vec2::new(0.25, 0.25));
       +                            self.document_behavior.document_options.set_scale(Vec2::new(0.25, 0.25));
                                    ui.close_menu();
                                }
        
       @@ -542,10 +477,7 @@ impl MainWindow {
                                ui.close_menu();
                            }
                            ui.separator();
       -                    if ui
       -                        .button(fl!(crate::LANGUAGE_LOADER, "menu-guides-off"))
       -                        .clicked()
       -                    {
       +                    if ui.button(fl!(crate::LANGUAGE_LOADER, "menu-guides-off")).clicked() {
                                result = Some(Message::SetGuide(0, 0));
                                ui.close_menu();
                            }
       @@ -580,10 +512,7 @@ impl MainWindow {
                            }
        
                            ui.separator();
       -                    if ui
       -                        .button(fl!(crate::LANGUAGE_LOADER, "menu-guides-off"))
       -                        .clicked()
       -                    {
       +                    if ui.button(fl!(crate::LANGUAGE_LOADER, "menu-guides-off")).clicked() {
                                result = Some(Message::SetRaster(0, 0));
                                ui.close_menu();
                            }
       @@ -606,13 +535,7 @@ impl MainWindow {
                                ui.style_mut().wrap = Some(false);
                                ui.set_min_width(250.0);
                                for (i, p) in PLUGINS.iter().enumerate() {
       -                            if ui
       -                                .add_enabled(
       -                                    has_buffer,
       -                                    egui::Button::new(p.title.clone()).wrap(false),
       -                                )
       -                                .clicked()
       -                            {
       +                            if ui.add_enabled(has_buffer, egui::Button::new(p.title.clone()).wrap(false)).clicked() {
                                        result = Some(Message::RunPlugin(i));
                                        ui.close_menu();
                                    }
       @@ -627,10 +550,7 @@ impl MainWindow {
                    ui.menu_button(fl!(crate::LANGUAGE_LOADER, "menu-help"), |ui| {
                        ui.style_mut().wrap = Some(false);
                        ui.set_min_width(170.0);
       -                let r = ui.hyperlink_to(
       -                    fl!(crate::LANGUAGE_LOADER, "menu-discuss"),
       -                    "https://github.com/mkrueger/icy_draw/discussions",
       -                );
       +                let r = ui.hyperlink_to(fl!(crate::LANGUAGE_LOADER, "menu-discuss"), "https://github.com/mkrueger/icy_draw/discussions");
                        if r.clicked() {
                            ui.close_menu();
                        }
       @@ -672,11 +592,7 @@ impl MainWindow {
            }
        }
        
       -pub fn medium_toggle_button(
       -    ui: &mut egui::Ui,
       -    icon: &RetainedImage,
       -    selected: bool,
       -) -> egui::Response {
       +pub fn medium_toggle_button(ui: &mut egui::Ui, icon: &RetainedImage, selected: bool) -> egui::Response {
            let size_points = egui::Vec2::splat(20.0);
        
            let tint = if selected {