From 6a11320b27f60215d64a45ffdb842f709a17d638 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sun, 8 Dec 2024 13:01:20 +0100 Subject: [PATCH] add copy/paste and erase selecton buttons --- README.md | 2 +- assets/copy.png | Bin 0 -> 159 bytes src/editor.rs | 103 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 assets/copy.png diff --git a/README.md b/README.md index 5d53374..15df295 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble ## todo -- copy/cut/paste selections - undo/redo - more levels - make marble movement symmetric and order-independent - make power propagation not recursive - story/lore +- cut selections, copy to system clipboard - timestamps in solutions and blueprints - multiple input/output sets - tooltips diff --git a/assets/copy.png b/assets/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..ad4cbbef76da5a8da19cca4ed91edbd7090013a7 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`X`U{QAr`$ygQEEkC~z$9{=UEH zdumEg)9FcT>$$!(9uk_6QkI{_#_+FZgjKOaUO4n93`NpHbs8II$9Ql7_d zxx75Uzj8({%hEl*7arC(UEHpd(*5U}<2NPordQtDd-@8Pc-I;z`J`ve1KP;o>FVdQ I&MBb@0Ax}=bpQYW literal 0 HcmV?d00001 diff --git a/src/editor.rs b/src/editor.rs index b353cd2..81abaab 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -63,8 +63,9 @@ pub struct Editor { selected_blueprint: usize, blueprint_scroll: usize, step_time: u128, - max_step_time:u128, - start_time: Instant + max_step_time: u128, + start_time: Instant, + pasting_board: Option, } #[derive(Debug, PartialEq)] @@ -142,7 +143,8 @@ impl Editor { blueprint_scroll: 0, step_time: 0, max_step_time: 0, - start_time: Instant::now(), + start_time: Instant::now(), + pasting_board: None, } } @@ -262,7 +264,7 @@ impl Editor { } } - fn save_blueprint(&mut self, selection: (Pos, Pos)) { + fn get_selected_as_board(&self, selection: (Pos, Pos)) -> Board { let min = selection.0.min(selection.1); let max = selection.0.max(selection.1) + (1, 1).into(); let width = (max.x - min.x) as usize; @@ -275,6 +277,11 @@ impl Editor { } } } + board + } + + fn save_blueprint(&mut self, selection: (Pos, Pos)) { + let mut board = self.get_selected_as_board(selection); board.trim_size(0); let id = get_free_id(&self.blueprints, Blueprint::id); let mut blueprint = Blueprint::new(&board, id); @@ -405,6 +412,17 @@ impl Editor { if rl.is_key_pressed(KeyboardKey::KEY_R) { self.rotate_tool(rl.is_key_down(KeyboardKey::KEY_LEFT_SHIFT)); } + + if self.sim_state == SimState::Editing { + if rl.is_key_down(KeyboardKey::KEY_LEFT_CONTROL) + && rl.is_key_pressed(KeyboardKey::KEY_V) + { + if let Ok(text) = rl.get_clipboard_text() { + let b = Board::parse(&text); + self.pasting_board = Some(b); + } + } + } } fn draw_board(&self, d: &mut RaylibDrawHandle, textures: &Textures) { @@ -686,25 +704,37 @@ impl Editor { 32, true, ); - if simple_button(d, 100, footer_top as i32 + 49, 40, 40) { + let y = footer_top as i32 + 49; + + if simple_button(d, 100, y, 40, 40) { self.save_blueprint(selection); } - draw_scaled_texture(d, textures.get("save"), 104, footer_top as i32 + 53, 2.); - if simple_button(d, 144, footer_top as i32 + 49, 40, 40) { + draw_scaled_texture(d, textures.get("save"), 104, y + 4, 2.); + + if simple_button(d, 144, y, 40, 40) { self.active_tool = Tool::SelectArea(Selection::default()); } - draw_scaled_texture(d, textures.get("cancel"), 148, footer_top as i32 + 53, 2.); + draw_scaled_texture(d, textures.get("cancel"), 148, y + 4, 2.); - // if simple_button(d, 144, footer_top as i32 + 49, 40, 40) { - // self.active_tool = Tool::SelectArea(Selection::default()); - // } - // draw_scaled_texture( - // d, - // textures.get("direction_up"), - // 148, - // footer_top as i32 + 53, - // 2., - // ); + if simple_button(d, 188, y, 40, 40) + || (d.is_key_pressed(KeyboardKey::KEY_C) + && d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL)) + { + let board = self.get_selected_as_board(selection); + self.pasting_board = Some(board); + } + draw_scaled_texture(d, textures.get("copy"), 192, y + 4, 2.); + + if simple_button(d, 232, y, 40, 40) { + let min = selection.0.min(selection.1); + let max = selection.0.max(selection.1); + for x in min.x..=max.x { + for y in min.y..=max.y { + self.source_board.set(Pos { x, y }, Tile::Blank); + } + } + } + draw_scaled_texture(d, textures.get("eraser"), 236, y + 4, 2.); } let mouse_pos = d.get_mouse_position(); @@ -859,6 +889,43 @@ impl Editor { let tile_scale = (1 << self.zoom) as f32; let tile_size = 16 << self.zoom; if self.sim_state == SimState::Editing { + if let Some(board) = &self.pasting_board { + if d.is_key_pressed(KeyboardKey::KEY_ESCAPE) { + self.pasting_board = None; + return; + } + if mouse_pos.y < footer_top && mouse_pos.y > HEADER_HEIGHT as f32 { + let view_offset = Vector2::new( + self.view_offset.x.rem(tile_size as f32), + self.view_offset.y.rem(tile_size as f32), + ); + let mut offset = mouse_pos - view_offset; + offset.x -= offset.x.rem(tile_size as f32); + offset.y -= offset.y.rem(tile_size as f32); + offset += view_offset; + board.draw(d, textures, offset, self.zoom); + if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) { + let tile_pos = (mouse_pos - self.view_offset) / tile_size as f32; + let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor()); + let mut pos = tile_pos.into(); + + let board = self.pasting_board.take().unwrap(); + self.grow_board_and_update_view(&mut pos); + self.grow_board_and_update_view( + &mut (pos + (board.width() - 1, board.height() - 1).into()), + ); + for x in 0..board.width() { + for y in 0..board.height() { + let p = (x, y).into(); + if let Some(tile) = board.get(p) { + self.source_board.set(p + pos, tile); + } + } + } + } + } + return; + } if let Tool::Digits(Some(pos)) = &mut self.active_tool { let tile_screen_pos = pos.to_vec() * tile_size as f32 + self.view_offset; d.draw_texture_ex(