diff --git a/src/editor.rs b/src/editor.rs index aa70434..e7cdb3b 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -29,11 +29,11 @@ pub struct Editor { output_as_text: bool, input_as_text: bool, active_tool: Tool, - tool_menu_math: MathOp, - tool_menu_gate: GateType, - tool_menu_arrow: Direction, - tool_menu_mirror: MirrorType, - tool_menu_wire: WireType, + tool_math: MathOp, + tool_gate: GateType, + tool_arrow: Direction, + tool_mirror: MirrorType, + tool_wire: WireType, input_text_selected: bool, sim_speed: u8, time_since_step: f32, @@ -94,11 +94,11 @@ impl Editor { input_text_selected: false, sim_speed: 8, time_since_step: 0., - tool_menu_math: MathOp::Add, - tool_menu_gate: GateType::Equal, - tool_menu_arrow: Direction::Right, - tool_menu_mirror: MirrorType::Forward, - tool_menu_wire: WireType::Vertical, + tool_math: MathOp::Add, + tool_gate: GateType::Equal, + tool_arrow: Direction::Right, + tool_mirror: MirrorType::Forward, + tool_wire: WireType::Vertical, level, exit_state: ExitState::Dont, exit_menu: false, @@ -168,7 +168,7 @@ impl Editor { fn rotate_tool(&mut self, shift: bool) { match &self.active_tool { Tool::Math => { - self.tool_menu_math = match self.tool_menu_math { + self.tool_math = match self.tool_math { MathOp::Add => MathOp::Sub, MathOp::Sub => MathOp::Mul, MathOp::Mul => MathOp::Div, @@ -177,7 +177,7 @@ impl Editor { } } Tool::Gate => { - self.tool_menu_gate = match self.tool_menu_gate { + self.tool_gate = match self.tool_gate { GateType::LessThan => GateType::GreaterThan, GateType::GreaterThan => GateType::Equal, GateType::Equal => GateType::NotEqual, @@ -185,20 +185,20 @@ impl Editor { } } Tool::Arrow => { - self.tool_menu_arrow = if shift { - self.tool_menu_arrow.left() + self.tool_arrow = if shift { + self.tool_arrow.left() } else { - self.tool_menu_arrow.right() + self.tool_arrow.right() } } Tool::Mirror => { - self.tool_menu_mirror = match self.tool_menu_mirror { + self.tool_mirror = match self.tool_mirror { MirrorType::Forward => MirrorType::Back, MirrorType::Back => MirrorType::Forward, } } Tool::Wire => { - self.tool_menu_wire = match self.tool_menu_wire { + self.tool_wire = match self.tool_wire { WireType::Vertical => WireType::Horizontal, WireType::Horizontal => WireType::Cross, WireType::Cross => WireType::Vertical, @@ -212,11 +212,33 @@ impl Editor { } } - fn set_tile(&mut self, pos: Pos, tile: Tile) { - self.source_board.grow_to_include(pos); + fn set_tile(&mut self, mut pos: Pos, tile: Tile) { + let tile_size = (16 << self.zoom) as f32; + let (x, y) = self.source_board.grow_to_include(pos); + if x != 0 || y != 0 { + self.view_offset.x -= x as f32 * tile_size; + self.view_offset.y -= y as f32 * tile_size; + pos.x += x; + pos.y += y; + match &mut self.active_tool { + Tool::Digits(Some(pos)) => { + pos.x += x; + pos.y += y; + } + Tool::SelectArea(Some((start, end)), _) => { + start.x += x; + start.y += y; + end.x += x; + end.y += y; + } + _ => (), + } + } self.source_board.set(pos, tile); if tile.is_blank() { - self.source_board.trim_size(); + let (x, y) = self.source_board.trim_size(); + self.view_offset.x += x as f32 * tile_size; + self.view_offset.y += y as f32 * tile_size; } } @@ -530,28 +552,24 @@ impl Editor { tool_button((1, 0), "marble", Tool::SetTile(Tile::from_char('o'))); tool_button( (1, 1), - &Tile::Powerable(PTile::Wire(self.tool_menu_wire), false).texture(), + &Tile::Powerable(PTile::Wire(self.tool_wire), false).texture(), Tool::Wire, ); - tool_button( - (1, 2), - &Tile::Arrow(self.tool_menu_arrow).texture(), - Tool::Arrow, - ); + tool_button((1, 2), &Tile::Arrow(self.tool_arrow).texture(), Tool::Arrow); tool_button( (1, 3), - &Tile::Mirror(self.tool_menu_mirror).texture(), + &Tile::Mirror(self.tool_mirror).texture(), Tool::Mirror, ); tool_button( (1, 4), - &Tile::Powerable(PTile::Math(self.tool_menu_math), false).texture(), + &Tile::Powerable(PTile::Math(self.tool_math), false).texture(), Tool::Math, ); tool_button( (1, 5), - &Tile::Powerable(PTile::Gate(self.tool_menu_gate), false).texture(), + &Tile::Powerable(PTile::Gate(self.tool_gate), false).texture(), Tool::Gate, ); @@ -659,11 +677,11 @@ impl Editor { Tool::None => unreachable!(), Tool::Erase => "selection".into(), Tool::SetTile(t) => t.texture(), - Tool::Math => format!("{}_off", self.tool_menu_math.texture_name()), - Tool::Gate => format!("{}_off", self.tool_menu_gate.texture_name()), - Tool::Wire => format!("{}_off", self.tool_menu_wire.texture_name()), - Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(), - Tool::Mirror => self.tool_menu_mirror.texture_name().into(), + Tool::Math => format!("{}_off", self.tool_math.texture_name()), + Tool::Gate => format!("{}_off", self.tool_gate.texture_name()), + Tool::Wire => format!("{}_off", self.tool_wire.texture_name()), + Tool::Arrow => self.tool_arrow.arrow_texture_name().into(), + Tool::Mirror => self.tool_mirror.texture_name().into(), Tool::Digits(_) => "selection".into(), Tool::SelectArea(_, false) => "area_full".into(), Tool::SelectArea(_, true) => "transparent".into(), @@ -678,31 +696,25 @@ impl Editor { ); } if d.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT) { + let pos = tile_pos.into(); match self.active_tool { Tool::None => (), Tool::Erase => (), - Tool::SetTile(tile) => self.set_tile(tile_pos.into(), tile), - Tool::Math => self.set_tile( - tile_pos.into(), - Tile::Powerable(PTile::Math(self.tool_menu_math), false), - ), - Tool::Gate => self.set_tile( - tile_pos.into(), - Tile::Powerable(PTile::Gate(self.tool_menu_gate), false), - ), - Tool::Wire => self.set_tile( - tile_pos.into(), - Tile::Powerable(PTile::Wire(self.tool_menu_wire), false), - ), - Tool::Arrow => { - self.set_tile(tile_pos.into(), Tile::Arrow(self.tool_menu_arrow)) + Tool::SetTile(tile) => self.set_tile(pos, tile), + Tool::Math => { + self.set_tile(pos, Tile::Powerable(PTile::Math(self.tool_math), false)) } - Tool::Mirror => { - self.set_tile(tile_pos.into(), Tile::Mirror(self.tool_menu_mirror)) + Tool::Gate => { + self.set_tile(pos, Tile::Powerable(PTile::Gate(self.tool_gate), false)) } + Tool::Wire => { + self.set_tile(pos, Tile::Powerable(PTile::Wire(self.tool_wire), false)) + } + Tool::Arrow => self.set_tile(pos, Tile::Arrow(self.tool_arrow)), + Tool::Mirror => self.set_tile(pos, Tile::Mirror(self.tool_mirror)), Tool::Digits(_pos) => { - self.active_tool = Tool::Digits(Some(tile_pos.into())); - if let Some(tile) = self.source_board.get_mut(tile_pos.into()) { + self.active_tool = Tool::Digits(Some(pos)); + if let Some(tile) = self.source_board.get_mut(pos) { if let Tile::Digit(_) = tile { } else { *tile = Tile::Digit(0); diff --git a/src/marble_engine/board.rs b/src/marble_engine/board.rs index 60c93df..f353179 100644 --- a/src/marble_engine/board.rs +++ b/src/marble_engine/board.rs @@ -55,8 +55,6 @@ pub struct Board { rows: Vec>, width: usize, height: usize, - offset_x: isize, - offset_y: isize, } impl Board { @@ -96,8 +94,6 @@ impl Board { rows, width, height, - offset_x: 0, - offset_y: 0, } } @@ -106,8 +102,6 @@ impl Board { width: rows[0].len(), height: rows.len(), rows, - offset_x: 0, - offset_y: 0, } } @@ -124,15 +118,7 @@ impl Board { sum } - fn transform(&self, p: Pos) -> Pos { - Pos { - x: p.x + self.offset_x, - y: p.y + self.offset_y, - } - } - pub fn pos_in_bounds(&self, p: Pos) -> bool { - let p = self.transform(p); self.in_bounds(p) } @@ -141,7 +127,6 @@ impl Board { } pub fn get(&self, p: Pos) -> Option { - let p = self.transform(p); if self.in_bounds(p) { Some(self.rows[p.y as usize][p.x as usize]) } else { @@ -150,7 +135,6 @@ impl Board { } pub fn get_or_blank(&self, p: Pos) -> Tile { - let p = self.transform(p); if self.in_bounds(p) { self.rows[p.y as usize][p.x as usize] } else { @@ -159,7 +143,6 @@ impl Board { } pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> { - let p = self.transform(p); if self.in_bounds(p) { Some(&mut self.rows[p.y as usize][p.x as usize]) } else { @@ -168,7 +151,6 @@ impl Board { } pub fn get_blank_mut(&mut self, p: Pos) -> Option<&mut Tile> { - let p = self.transform(p); if self.in_bounds(p) { let tile = &mut self.rows[p.y as usize][p.x as usize]; if tile == &Tile::Blank { @@ -179,25 +161,25 @@ impl Board { } pub fn set(&mut self, p: Pos, tile: Tile) { - let p = self.transform(p); if self.in_bounds(p) { self.rows[p.y as usize][p.x as usize] = tile; } } - pub fn grow_to_include(&mut self, p: Pos) { - let p = self.transform(p); + pub fn grow_to_include(&mut self, p: Pos) -> (isize, isize) { + let mut offset_x = 0; + let mut offset_y = 0; if p.x < 0 { - let len = p.x.unsigned_abs(); + let len = p.x.unsigned_abs() + 2; for row in &mut self.rows { let mut new_row = vec![Tile::Blank; len]; new_row.append(row); *row = new_row; } - self.offset_x += len as isize; + offset_x = len; self.width += len; } else if p.x as usize >= self.width { - let new_width = p.x as usize + 1; + let new_width = p.x as usize + 3; for row in &mut self.rows { row.resize(new_width, Tile::Blank); } @@ -205,20 +187,22 @@ impl Board { } if p.y < 0 { - let len = p.y.unsigned_abs(); + let len = p.y.unsigned_abs() + 2; let mut new_rows = vec![vec![Tile::Blank; self.width]; len]; new_rows.append(&mut self.rows); self.rows = new_rows; - self.offset_y += len as isize; + offset_y = len; self.height += len; } else if p.y as usize >= self.height { - let new_height = p.y as usize + 1; + let new_height = p.y as usize + 3; self.rows.resize(new_height, vec![Tile::Blank; self.width]); self.height = new_height; } + (offset_x as isize, offset_y as isize) } - pub fn trim_size(&mut self) { + pub fn trim_size(&mut self) -> (usize, usize) { + let (offset_x, offset_y); // top { let mut n = 0; @@ -229,7 +213,7 @@ impl Board { for _ in 0..trim_top { self.rows.remove(0); } - self.offset_y -= trim_top as isize; + offset_y = trim_top; self.height -= trim_top; } // bottom @@ -256,7 +240,7 @@ impl Board { row.remove(0); } } - self.offset_x -= trim_left as isize; + offset_x = trim_left; self.width -= trim_left; } // right @@ -273,6 +257,7 @@ impl Board { } self.width -= trim_right; } + (offset_x, offset_y) } pub fn width(&self) -> usize { @@ -288,10 +273,7 @@ impl Board { for y in 0..self.height { for x in 0..self.width { if let Tile::Marble { value: _, dir: _ } = self.rows[y][x] { - out.push(Pos { - x: x as isize - self.offset_x, - y: y as isize - self.offset_y, - }); + out.push((x, y).into()); } } } @@ -308,8 +290,8 @@ impl Board { for x in start_x..(start_x + tile_width) { for y in start_y..(start_y + tile_height) { - let tx = (x as isize + self.offset_x) as usize; - let ty = (y as isize + self.offset_y) as usize; + let tx = x as usize; + let ty = y as usize; let px = x * tile_size + offset.x as i32; let py = y * tile_size + offset.y as i32; if self.in_bounds((tx, ty).into()) {