diff --git a/README.md b/README.md index 0931c92..4322e06 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ undo/redo make math tiles read digits tooltips lock tile types for early levels to make it less overwhelming -make a gui alternative to pressing R to rotate between tile variants +display tool variant more clearly (it's not obvious there are more states) make marble movement more consistent (`>o o<` depends on internal marble order) decide on marble data size (u32 or byte?) blueprint rotation? diff --git a/src/editor.rs b/src/editor.rs index 08099c2..00e522d 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -18,7 +18,7 @@ use crate::{ }, simple_button, simple_option_button, slider, solution::{Score, Solution}, - text_input, texture_option_button, userdata_dir, Textures, + text_input, texture_option_button, get_scroll, userdata_dir, Scroll, Textures, }; const HEADER_HEIGHT: i32 = 40; @@ -186,50 +186,24 @@ impl Editor { } fn rotate_tool(&mut self, shift: bool) { - match &self.active_tool { - Tool::Math => { - self.tool_math = match self.tool_math { - MathOp::Add => MathOp::Sub, - MathOp::Sub => MathOp::Mul, - MathOp::Mul => MathOp::Div, - MathOp::Div => MathOp::Rem, - MathOp::Rem => MathOp::Add, - } + if shift { + match &self.active_tool { + Tool::Math => self.tool_math.prev(), + Tool::Gate => self.tool_gate.prev(), + Tool::Arrow => self.tool_arrow = self.tool_arrow.left(), + Tool::Mirror => self.tool_mirror.flip(), + Tool::Wire => self.tool_wire.prev(), + _ => (), } - Tool::Gate => { - self.tool_gate = match self.tool_gate { - GateType::LessThan => GateType::GreaterThan, - GateType::GreaterThan => GateType::Equal, - GateType::Equal => GateType::NotEqual, - GateType::NotEqual => GateType::LessThan, - } + } else { + match &self.active_tool { + Tool::Math => self.tool_math.next(), + Tool::Gate => self.tool_gate.next(), + Tool::Arrow => self.tool_arrow = self.tool_arrow.right(), + Tool::Mirror => self.tool_mirror.flip(), + Tool::Wire => self.tool_wire.next(), + _ => (), } - Tool::Arrow => { - self.tool_arrow = if shift { - self.tool_arrow.left() - } else { - self.tool_arrow.right() - } - } - Tool::Mirror => { - self.tool_mirror = match self.tool_mirror { - MirrorType::Forward => MirrorType::Back, - MirrorType::Back => MirrorType::Forward, - } - } - Tool::Wire => { - self.tool_wire = match self.tool_wire { - WireType::Vertical => WireType::Horizontal, - WireType::Horizontal => WireType::Cross, - WireType::Cross => WireType::Vertical, - } - } - Tool::None - | Tool::Erase - | Tool::SetTile(_) - | Tool::Digits(_) - | Tool::SelectArea(_, _) - | Tool::Blueprint => (), } } @@ -712,22 +686,32 @@ impl Editor { draw_scaled_texture(d, textures.get("cancel"), 148, footer_top as i32 + 53, 2.); } + let mouse_pos = d.get_mouse_position(); let mut tool_button = |(row, col): (i32, i32), texture: &str, tool_option: Tool| { let border = 4.; let gap = 2.; - let bound_offset = 32. + gap * 2. + border * 2.; + let tex_size = 32.; + let button_size = tex_size + border * 2.; + let grid_size = button_size + gap * 2.; + let pos = Vector2 { + x: 100. + col as f32 * grid_size - if col < 0 { 10. } else { 0. }, + y: footer_top + 5. + row as f32 * grid_size, + }; texture_option_button( d, - Vector2 { - x: 100. + col as f32 * bound_offset - if col < 0 { 10. } else { 0. }, - y: footer_top + 5. + row as f32 * bound_offset, - }, + pos, textures.get(texture), tool_option, &mut self.active_tool, - 32., + tex_size, border, ); + let bounds = Rectangle::new(pos.x, pos.y, button_size, button_size); + if bounds.check_collision_point_rec(mouse_pos) { + get_scroll(d) + } else { + None + } }; tool_button((0, -2), "eraser", Tool::Erase); tool_button((1, -2), "selection", Tool::SelectArea(None, false)); @@ -744,28 +728,48 @@ impl Editor { tool_button((0, 5), "digit_tool", Tool::Digits(None)); tool_button((1, 0), "marble", Tool::SetTile(Tile::from_char('o'))); - tool_button( + match tool_button( (1, 1), &Tile::Powerable(PTile::Wire(self.tool_wire), false).texture(), Tool::Wire, - ); + ) { + Some(Scroll::Down) => self.tool_wire.next(), + Some(Scroll::Up) => self.tool_wire.prev(), + None => (), + } - tool_button((1, 2), &Tile::Arrow(self.tool_arrow).texture(), Tool::Arrow); - tool_button( + match tool_button((1, 2), &Tile::Arrow(self.tool_arrow).texture(), Tool::Arrow) { + Some(Scroll::Down) => self.tool_arrow = self.tool_arrow.right(), + Some(Scroll::Up) => self.tool_arrow = self.tool_arrow.left(), + None => (), + } + if tool_button( (1, 3), &Tile::Mirror(self.tool_mirror).texture(), Tool::Mirror, - ); - tool_button( + ) + .is_some() + { + self.tool_mirror.flip() + } + match tool_button( (1, 4), &Tile::Powerable(PTile::Math(self.tool_math), false).texture(), Tool::Math, - ); - tool_button( + ) { + Some(Scroll::Down) => self.tool_math.next(), + Some(Scroll::Up) => self.tool_math.prev(), + None => (), + } + match tool_button( (1, 5), &Tile::Powerable(PTile::Gate(self.tool_gate), false).texture(), Tool::Gate, - ); + ) { + Some(Scroll::Down) => self.tool_gate.next(), + Some(Scroll::Up) => self.tool_gate.prev(), + None => (), + } } let output_x = 370; diff --git a/src/marble_engine.rs b/src/marble_engine.rs index 9c7fa3e..1ce2c58 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -361,17 +361,10 @@ impl Machine { WireType::Vertical => WireType::Horizontal, WireType::Horizontal => WireType::Vertical, WireType::Cross => WireType::Cross, - }; - } - Tile::Mirror(mirror) => { - *mirror = match *mirror { - MirrorType::Forward => MirrorType::Back, - MirrorType::Back => MirrorType::Forward, - }; - } - Tile::Arrow(dir) => { - *dir = dir.opposite(); + } } + Tile::Mirror(mirror) => mirror.flip(), + Tile::Arrow(dir) => *dir = dir.opposite(), _ => (), }; } diff --git a/src/marble_engine/tile.rs b/src/marble_engine/tile.rs index 1c9645f..703c221 100644 --- a/src/marble_engine/tile.rs +++ b/src/marble_engine/tile.rs @@ -250,6 +250,22 @@ impl WireType { } } + pub fn next(&mut self) { + *self = match self { + WireType::Vertical => WireType::Horizontal, + WireType::Horizontal => WireType::Cross, + WireType::Cross => WireType::Vertical, + } + } + + pub fn prev(&mut self) { + *self = match self { + WireType::Vertical => WireType::Cross, + WireType::Horizontal => WireType::Vertical, + WireType::Cross => WireType::Horizontal, + } + } + pub const fn texture_name(&self) -> &'static str { match self { WireType::Vertical => "wire_vertical", @@ -277,6 +293,13 @@ impl MirrorType { } } + pub fn flip(&mut self) { + *self = match self { + MirrorType::Forward => MirrorType::Back, + MirrorType::Back => MirrorType::Forward, + } + } + pub const fn texture_name(&self) -> &'static str { match self { MirrorType::Forward => "mirror_forward", @@ -295,6 +318,26 @@ impl MathOp { MathOp::Rem => "rem", } } + + pub fn next(&mut self) { + *self = match self { + MathOp::Add => MathOp::Sub, + MathOp::Sub => MathOp::Mul, + MathOp::Mul => MathOp::Div, + MathOp::Div => MathOp::Rem, + MathOp::Rem => MathOp::Add, + } + } + + pub fn prev(&mut self) { + *self = match self { + MathOp::Add => MathOp::Rem, + MathOp::Sub => MathOp::Add, + MathOp::Mul => MathOp::Sub, + MathOp::Div => MathOp::Mul, + MathOp::Rem => MathOp::Div, + } + } } impl GateType { @@ -306,4 +349,22 @@ impl GateType { GateType::NotEqual => "neq", } } + + pub fn next(&mut self) { + *self = match self { + GateType::LessThan => GateType::GreaterThan, + GateType::GreaterThan => GateType::Equal, + GateType::Equal => GateType::NotEqual, + GateType::NotEqual => GateType::LessThan, + } + } + + pub fn prev(&mut self) { + *self = match self { + GateType::LessThan => GateType::NotEqual, + GateType::GreaterThan => GateType::LessThan, + GateType::Equal => GateType::GreaterThan, + GateType::NotEqual => GateType::Equal, + } + } } diff --git a/src/util.rs b/src/util.rs index 0f07167..efdd070 100644 --- a/src/util.rs +++ b/src/util.rs @@ -289,3 +289,21 @@ pub fn draw_scaled_texture( let pos = Vector2::new(x as f32, y as f32); d.draw_texture_ex(texture, pos, 0., scale, Color::WHITE); } + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Scroll { + Up, + Down, +} + +pub fn get_scroll(rl: &RaylibHandle) -> Option { + const SCROLL_THRESHOLD: f32 = 0.5; + let value = rl.get_mouse_wheel_move(); + if value > SCROLL_THRESHOLD { + Some(Scroll::Up) + } else if value < -SCROLL_THRESHOLD { + Some(Scroll::Down) + } else { + None + } +}