Track API changes. - icy_draw - icy_draw is the successor to mystic draw. fork / mirror
 (HTM) git clone https://git.drkhsh.at/icy_draw.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit e39e45b2a4747e42d4d401c8ec484b47e1e4adf8
 (DIR) parent cb04dce5ca6c5a61cc85a7664b2c3d1878874a1e
 (HTM) Author: Mike Krüger <mkrueger@posteo.de>
       Date:   Tue, 10 Oct 2023 16:31:44 +0200
       
       Track API changes.
       
       Diffstat:
         M src/model/tools/fill_imp.rs         |       5 ++++-
         M src/paint/ellipse.rs                |      34 ++++++++++++++++++++++++-------
         M src/paint/rectangle.rs              |      44 +++++++++++++++++++++----------
         M src/plugins/mod.rs                  |      16 ++++++++--------
         M src/ui/editor/ansi/mod.rs           |      34 +++++++++++++++++++------------
         M src/ui/messages.rs                  |       7 +++++--
         M src/ui/tools/layer_view.rs          |       5 ++++-
       
       7 files changed, 99 insertions(+), 46 deletions(-)
       ---
 (DIR) diff --git a/src/model/tools/fill_imp.rs b/src/model/tools/fill_imp.rs
       @@ -149,7 +149,10 @@ impl Tool for FillTool {
        
            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() {
       +            let Ok(layer) = editor.get_cur_layer_index() else {
       +                return None
       +            };
       +            if layer >= editor.buffer_view.lock().get_buffer().layers.len() {
                        return None;
                    }
                    let attr = editor.buffer_view.lock().get_caret().get_attribute();
 (DIR) diff --git a/src/paint/ellipse.rs b/src/paint/ellipse.rs
       @@ -1,3 +1,4 @@
       +use egui::ahash::HashSet;
        use icy_engine::Position;
        use icy_engine_egui::BufferView;
        
       @@ -57,29 +58,48 @@ fn get_ellipse_points(from: Position, to: Position) -> Vec<Position> {
                    d2 += dx - dy + (rx * rx);
                }
            }
       -
            result
        }
        
        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();
       +    let mut from = from.into();
       +    let mut to = to.into();
       +    let mut y_mul = 1;
       +    if !matches!(mode, BrushMode::HalfBlock) {
       +        from.y /= 2;
       +        to.y /= 2;
       +        y_mul = 2;
       +    }
       +    let mut visited = HashSet::default();
            for point in get_ellipse_points(from, to) {
       -        plot_point(buffer_view, point, mode.clone(), color_mode, PointRole::Line);
       +        let pos = (point.x, point.y * y_mul);
       +        if visited.insert(pos) {
       +            plot_point(buffer_view, pos, 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) {
       -    let from = from.into();
       -    let to = to.into();
       +    let mut from = from.into();
       +    let mut to = to.into();
       +    let mut y_mul = 1;
       +    if !matches!(mode, BrushMode::HalfBlock) {
       +        from.y /= 2;
       +        to.y /= 2;
       +        y_mul = 2;
       +    }
            let points = get_ellipse_points(from, to);
       +    let mut visited = HashSet::default();
        
            for i in 0..points.len() / 2 {
                let mut x1 = points[i * 2];
                let x2 = points[i * 2 + 1];
       +        if !visited.insert(x1.y) {
       +            continue;
       +        }
        
                while x1.x < x2.x {
       -            plot_point(buffer_view, x1, mode.clone(), color_mode, PointRole::Line);
       +            plot_point(buffer_view, (x1.x, x1.y * y_mul), mode.clone(), color_mode, PointRole::Line);
        
                    x1.x += 1;
                }
 (DIR) diff --git a/src/paint/rectangle.rs b/src/paint/rectangle.rs
       @@ -4,34 +4,50 @@ 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) {
       -    let from = from.into();
       -    let to = to.into();
       +    let mut from = from.into();
       +    let mut to = to.into();
       +    let mut y_mul = 1;
       +    if !matches!(mode, BrushMode::HalfBlock) {
       +        from.y /= 2;
       +        to.y /= 2;
       +        y_mul = 2;
       +    }
        
       +    
            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 * y_mul), mode.clone(), color_mode, PointRole::TopSide);
       +        plot_point(buffer_view, (x, to.y * y_mul), 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 * y_mul), mode.clone(), color_mode, PointRole::LeftSide);
       +        plot_point(buffer_view, (to.x, y  * y_mul), mode.clone(), color_mode, PointRole::RightSide);
            }
        
       -    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, from.y * y_mul), mode.clone(), color_mode, PointRole::NWCorner);
       +    plot_point(buffer_view, (to.x, from.y * y_mul), mode.clone(), color_mode, PointRole::NECorner);
       +
       +    plot_point(buffer_view, (from.x, to.y * y_mul), mode.clone(), color_mode, PointRole::SWCorner);
       +    plot_point(buffer_view, (to.x, to.y * y_mul), 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);
        }
        
        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();
       +    let mut from = from.into();
       +    let mut to = to.into();
       +    let mut y_mul = 1;
       +    if !matches!(mode, BrushMode::HalfBlock) {
       +        from.y /= 2;
       +        to.y /= 2;
       +        y_mul = 2;
       +    }
        
            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 * y_mul), mode.clone(), color_mode, PointRole::Fill);
                }
            }
       -    draw_rectangle(buffer_view, from, to, mode, color_mode);
       +    if matches!(mode, BrushMode::HalfBlock) {
       +        draw_rectangle(buffer_view, from, to, mode, color_mode);
       +    }
        }
 (DIR) diff --git a/src/plugins/mod.rs b/src/plugins/mod.rs
       @@ -165,7 +165,7 @@ impl UserData for LuaBufferView {
                    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().unwrap()));
                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);
       @@ -223,7 +223,7 @@ impl UserData for LuaBufferView {
                });
        
                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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -244,7 +244,7 @@ impl UserData for LuaBufferView {
                });
        
                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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -258,7 +258,7 @@ 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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -274,7 +274,7 @@ impl UserData for LuaBufferView {
                });
        
                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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -289,7 +289,7 @@ impl UserData for LuaBufferView {
                });
        
                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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -303,7 +303,7 @@ 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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
       @@ -318,7 +318,7 @@ impl UserData for LuaBufferView {
                });
        
                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().unwrap();
                    let layer_len = this.buffer_view.lock().get_buffer_mut().layers.len();
                    if cur_layer >= layer_len {
                        return Err(mlua::Error::SyntaxError {
 (DIR) diff --git a/src/ui/editor/ansi/mod.rs b/src/ui/editor/ansi/mod.rs
       @@ -241,7 +241,7 @@ impl AnsiEditor {
                }
            }
        
       -    pub fn get_cur_layer_index(&self) -> usize {
       +    pub fn get_cur_layer_index(&self) -> TerminalResult<usize> {
                self.buffer_view.lock().get_edit_state_mut().get_current_layer()
            }
        
       @@ -301,19 +301,23 @@ impl AnsiEditor {
            pub fn delete_line(&mut self, line: i32) {
                // TODO: Undo
                let mut lock = self.buffer_view.lock();
       -        let cur_layer = self.get_cur_layer_index();
       -
       -        let layer = &mut lock.get_buffer_mut().layers[cur_layer];
       -        layer.remove_line(line);
       +        if let Ok(cur_layer) = self.get_cur_layer_index() {
       +            let layer = &mut lock.get_buffer_mut().layers[cur_layer];
       +            layer.remove_line(line);
       +        } else {
       +            log::error!("can't get current layer!");
       +        }
            }
        
            pub fn insert_line(&mut self, line: i32) {
                // TODO: Undo
                let mut binding = self.buffer_view.lock();
       -        let cur_layer = self.get_cur_layer_index();
       -
       -        let layer = &mut binding.get_buffer_mut().layers[cur_layer];
       -        layer.insert_line(line, Line::new());
       +        if let Ok(cur_layer) = self.get_cur_layer_index() {
       +            let layer = &mut binding.get_buffer_mut().layers[cur_layer];
       +            layer.insert_line(line, Line::new());
       +        } else {
       +            log::error!("can't get current layer!");
       +        }
            }
        
            pub fn pickup_color(&mut self, pos: Position) {
       @@ -411,11 +415,15 @@ impl AnsiEditor {
            }
        
            pub fn get_char_from_cur_layer(&self, pos: Position) -> AttributedChar {
       -        if self.get_cur_layer_index() >= self.buffer_view.lock().get_buffer().layers.len() {
       -            return AttributedChar::invisible();
       +        if let Ok(cur_layer) = self.get_cur_layer_index() {
       +            if cur_layer >= self.buffer_view.lock().get_buffer().layers.len() {
       +                return AttributedChar::invisible();
       +            }
       +            self.buffer_view.lock().get_buffer().layers[cur_layer].get_char(pos)
       +        } else {
       +            log::error!("can't get current layer!");
       +            AttributedChar::invisible()
                }
       -        let cur_layer = self.get_cur_layer_index();
       -        self.buffer_view.lock().get_buffer().layers[cur_layer].get_char(pos)
            }
        
            pub fn set_char(&mut self, pos: impl Into<Position>, attributed_char: AttributedChar) {
 (DIR) diff --git a/src/ui/messages.rs b/src/ui/messages.rs
       @@ -352,8 +352,11 @@ impl<'a> MainWindow<'a> {
                    Message::RemoveFloatingLayer => {
                        self.run_editor_command(0, |_, editor: &mut crate::AnsiEditor, _| {
                            let mut lock = editor.buffer_view.lock();
       -                    let layer = lock.get_edit_state().get_current_layer();
       -                    to_message(lock.get_edit_state_mut().remove_layer(layer))
       +                    if let Ok(layer) = lock.get_edit_state().get_current_layer() {
       +                        to_message(lock.get_edit_state_mut().remove_layer(layer))
       +                    } else {
       +                        Some(Message::ShowError("No floating layer to remove".to_string()))
       +                    }
                        });
                    }
                    Message::ClearSelection => {
 (DIR) diff --git a/src/ui/tools/layer_view.rs b/src/ui/tools/layer_view.rs
       @@ -38,7 +38,10 @@ impl LayerToolWindow {
                let mut result = None;
        
                let max = editor.buffer_view.lock().get_buffer().layers.len();
       -        let cur_layer = editor.get_cur_layer_index();
       +        let Ok(cur_layer) = editor.get_cur_layer_index() else {
       +            log::error!("Invalid layer index");
       +            return result;
       +        };
        
                let paste_mode = editor.buffer_view.lock().get_buffer().layers.iter().position(|layer| layer.role.is_paste());