refactor board resizing in negative directions, fixing broken execution in negative zones
This commit is contained in:
parent
1b74f9c996
commit
355a5af15e
2 changed files with 83 additions and 89 deletions
118
src/editor.rs
118
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);
|
||||
|
|
|
@ -55,8 +55,6 @@ pub struct Board {
|
|||
rows: Vec<Vec<Tile>>,
|
||||
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<Tile> {
|
||||
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()) {
|
||||
|
|
Loading…
Reference in a new issue