add copy/paste and erase selecton buttons

This commit is contained in:
Crispy 2024-12-08 13:01:20 +01:00
parent dc9411cf9d
commit 6a11320b27
3 changed files with 86 additions and 19 deletions

View file

@ -4,12 +4,12 @@
logic mostly like https://git.crispypin.cc/CrispyPin/marble logic mostly like https://git.crispypin.cc/CrispyPin/marble
## todo ## todo
- copy/cut/paste selections
- undo/redo - undo/redo
- more levels - more levels
- make marble movement symmetric and order-independent - make marble movement symmetric and order-independent
- make power propagation not recursive - make power propagation not recursive
- story/lore - story/lore
- cut selections, copy to system clipboard
- timestamps in solutions and blueprints - timestamps in solutions and blueprints
- multiple input/output sets - multiple input/output sets
- tooltips - tooltips

BIN
assets/copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

View file

@ -64,7 +64,8 @@ pub struct Editor {
blueprint_scroll: usize, blueprint_scroll: usize,
step_time: u128, step_time: u128,
max_step_time: u128, max_step_time: u128,
start_time: Instant start_time: Instant,
pasting_board: Option<Board>,
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -143,6 +144,7 @@ impl Editor {
step_time: 0, step_time: 0,
max_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 min = selection.0.min(selection.1);
let max = selection.0.max(selection.1) + (1, 1).into(); let max = selection.0.max(selection.1) + (1, 1).into();
let width = (max.x - min.x) as usize; 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); board.trim_size(0);
let id = get_free_id(&self.blueprints, Blueprint::id); let id = get_free_id(&self.blueprints, Blueprint::id);
let mut blueprint = Blueprint::new(&board, id); let mut blueprint = Blueprint::new(&board, id);
@ -405,6 +412,17 @@ impl Editor {
if rl.is_key_pressed(KeyboardKey::KEY_R) { if rl.is_key_pressed(KeyboardKey::KEY_R) {
self.rotate_tool(rl.is_key_down(KeyboardKey::KEY_LEFT_SHIFT)); 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) { fn draw_board(&self, d: &mut RaylibDrawHandle, textures: &Textures) {
@ -686,25 +704,37 @@ impl Editor {
32, 32,
true, 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); self.save_blueprint(selection);
} }
draw_scaled_texture(d, textures.get("save"), 104, footer_top as i32 + 53, 2.); draw_scaled_texture(d, textures.get("save"), 104, y + 4, 2.);
if simple_button(d, 144, footer_top as i32 + 49, 40, 40) {
if simple_button(d, 144, y, 40, 40) {
self.active_tool = Tool::SelectArea(Selection::default()); 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) { if simple_button(d, 188, y, 40, 40)
// self.active_tool = Tool::SelectArea(Selection::default()); || (d.is_key_pressed(KeyboardKey::KEY_C)
// } && d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL))
// draw_scaled_texture( {
// d, let board = self.get_selected_as_board(selection);
// textures.get("direction_up"), self.pasting_board = Some(board);
// 148, }
// footer_top as i32 + 53, draw_scaled_texture(d, textures.get("copy"), 192, y + 4, 2.);
// 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(); let mouse_pos = d.get_mouse_position();
@ -859,6 +889,43 @@ impl Editor {
let tile_scale = (1 << self.zoom) as f32; let tile_scale = (1 << self.zoom) as f32;
let tile_size = 16 << self.zoom; let tile_size = 16 << self.zoom;
if self.sim_state == SimState::Editing { 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 { if let Tool::Digits(Some(pos)) = &mut self.active_tool {
let tile_screen_pos = pos.to_vec() * tile_size as f32 + self.view_offset; let tile_screen_pos = pos.to_vec() * tile_size as f32 + self.view_offset;
d.draw_texture_ex( d.draw_texture_ex(