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
|
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
BIN
assets/copy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 159 B |
103
src/editor.rs
103
src/editor.rs
|
@ -63,8 +63,9 @@ pub struct Editor {
|
||||||
selected_blueprint: usize,
|
selected_blueprint: usize,
|
||||||
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)]
|
||||||
|
@ -142,7 +143,8 @@ impl Editor {
|
||||||
blueprint_scroll: 0,
|
blueprint_scroll: 0,
|
||||||
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(
|
||||||
|
|
Loading…
Reference in a new issue