scroll on tools to rotate between variants

This commit is contained in:
Crispy 2024-10-13 00:55:28 +02:00
parent ed956ffbe4
commit 44017f4ed5
5 changed files with 145 additions and 69 deletions

View file

@ -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?

View file

@ -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,51 +186,25 @@ impl Editor {
}
fn rotate_tool(&mut self, shift: bool) {
if shift {
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,
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,
}
}
Tool::Arrow => {
self.tool_arrow = if shift {
self.tool_arrow.left()
} else {
self.tool_arrow.right()
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::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 => (),
}
}
pub fn center_view(&mut self, d: &RaylibHandle) {
@ -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;

View file

@ -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(),
_ => (),
};
}

View file

@ -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,
}
}
}

View file

@ -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<Scroll> {
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
}
}