add copy/paste and erase selecton buttons
This commit is contained in:
parent
dc9411cf9d
commit
6a11320b27
3 changed files with 86 additions and 19 deletions
|
@ -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
|
||||
|
|
BIN
assets/copy.png
Normal file
BIN
assets/copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 159 B |
|
@ -64,7 +64,8 @@ pub struct Editor {
|
|||
blueprint_scroll: usize,
|
||||
step_time: u128,
|
||||
max_step_time: u128,
|
||||
start_time: Instant
|
||||
start_time: Instant,
|
||||
pasting_board: Option<Board>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -143,6 +144,7 @@ impl Editor {
|
|||
step_time: 0,
|
||||
max_step_time: 0,
|
||||
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(
|
||||
|
|
Loading…
Reference in a new issue