add bindings (default qwerty + asdfgh) for the tile tools

This commit is contained in:
Crispy 2025-04-03 13:45:49 +02:00
parent 04e7e4090d
commit 6a8bc840b4
5 changed files with 89 additions and 38 deletions

View file

@ -3,7 +3,8 @@ Game store page: https://crispypin.itch.io/marble-machinations
## [Unreleased] ## [Unreleased]
### added ### added
- configurable key bindings for the basic editor actions - configurable key bindings for many editor actions
- QWERTY+ASDFGH keybindings for the tile tools
- OS clipboard copy/paste, with fallback to old behavior when copying - OS clipboard copy/paste, with fallback to old behavior when copying
- in-grid text comments (not yet editable in-game) - in-grid text comments (not yet editable in-game)
- changelog file - changelog file

View file

@ -33,7 +33,7 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
#### undecided #### undecided
- option to use 8-bit marbles? - option to use 8-bit marbles?
- blueprint rotation? - blueprint rotation?
- changable marble start direction? - settable marble start direction?
## playtesting observations ## playtesting observations
- 'loops' introduces too many things (powering, redirection, generating zeroes) - 'loops' introduces too many things (powering, redirection, generating zeroes)

View file

@ -523,7 +523,6 @@ impl Editor {
if globals.is_pressed(ActionId::CycleGroup) { if globals.is_pressed(ActionId::CycleGroup) {
if globals.is_held(ActionId::CycleGroupRevMod) { if globals.is_held(ActionId::CycleGroupRevMod) {
println!("rotate reverse");
match &self.active_tool { match &self.active_tool {
Tool::Math => self.tool_math.prev(), Tool::Math => self.tool_math.prev(),
Tool::Comparator => self.tool_comparator.prev(), Tool::Comparator => self.tool_comparator.prev(),
@ -533,7 +532,6 @@ impl Editor {
_ => (), _ => (),
} }
} else { } else {
println!("rotate");
match &self.active_tool { match &self.active_tool {
Tool::Math => self.tool_math.next(), Tool::Math => self.tool_math.next(),
Tool::Comparator => self.tool_comparator.next(), Tool::Comparator => self.tool_comparator.next(),
@ -545,12 +543,14 @@ impl Editor {
} }
} }
if rl.is_key_pressed(KeyboardKey::KEY_N) { if !self.machine.debug_subticks.is_empty() {
self.machine.subtick_index += 1; if rl.is_key_pressed(KeyboardKey::KEY_N) {
self.machine.subtick_index %= self.machine.debug_subticks.len(); self.machine.subtick_index += 1;
} self.machine.subtick_index %= self.machine.debug_subticks.len();
if rl.is_key_pressed(KeyboardKey::KEY_M) { }
self.machine.subtick_index = self.machine.subtick_index.saturating_sub(1); if rl.is_key_pressed(KeyboardKey::KEY_M) {
self.machine.subtick_index = self.machine.subtick_index.saturating_sub(1);
}
} }
if self.sim_state == SimState::Editing { if self.sim_state == SimState::Editing {
@ -1062,39 +1062,44 @@ impl Editor {
draw_scaled_texture(d, globals.get_tex("eraser"), 236, y + 4, 2.); draw_scaled_texture(d, globals.get_tex("eraser"), 236, y + 4, 2.);
} }
let mut tool_button = let mut tool_button = |(row, col): (i32, i32),
|(row, col): (i32, i32), texture: &str, tooltip: &'static str, tool_option: Tool| { texture: &str,
let border = 4.; tooltip: &'static str,
let gap = 2.; tool_option: Tool,
let button_size = 32. + border * 2.; action: Option<ActionId>| {
let grid_size = button_size + gap * 2.; let border = 4.;
let pos = Vector2 { let gap = 2.;
x: 100. + col as f32 * grid_size - if col < 0 { 10. } else { 0. }, let button_size = 32. + border * 2.;
y: footer_top + 5. + row as f32 * grid_size, let grid_size = button_size + gap * 2.;
}; let pos = Vector2 {
self.tooltip.add_rec( x: 100. + col as f32 * grid_size - if col < 0 { 10. } else { 0. },
Rectangle::new(pos.x, pos.y, button_size, button_size), y: footer_top + 5. + row as f32 * grid_size,
tooltip,
);
scrollable_texture_option_button(
(d, &self.mouse),
pos,
globals.get_tex(texture),
tool_option,
&mut self.active_tool,
border,
)
}; };
tool_button((0, -2), "eraser", "Eraser", Tool::Erase); self.tooltip.add_rec(
Rectangle::new(pos.x, pos.y, button_size, button_size),
tooltip,
);
scrollable_texture_option_button(
(d, &self.mouse),
pos,
globals.get_tex(texture),
tool_option,
&mut self.active_tool,
border,
action.map(|a| globals.is_pressed(a)).unwrap_or(false),
)
};
tool_button((0, -2), "eraser", "Eraser", Tool::Erase, None);
tool_button( tool_button(
(1, -2), (1, -2),
"selection", "selection",
"Select", "Select",
Tool::SelectArea(Selection::default()), Tool::SelectArea(Selection::default()),
None,
); );
tool_button((0, -1), "blueprint", "Blueprints", Tool::Blueprint); tool_button((0, -1), "blueprint", "Blueprints", Tool::Blueprint, None);
tool_button((1, -1), "transparent", "None", Tool::None); tool_button((1, -1), "transparent", "None", Tool::None, None);
if !hide_tile_tools { if !hide_tile_tools {
tool_button( tool_button(
@ -1102,44 +1107,57 @@ impl Editor {
"block", "block",
"Block", "Block",
Tool::SetTile(Tile::from_char('#')), Tool::SetTile(Tile::from_char('#')),
Some(ActionId::TileBlock),
); );
tool_button( tool_button(
(0, 1), (0, 1),
"silo_off", "silo_off",
"Silo", "Silo",
Tool::SetTile(Tile::from_char('B')), Tool::SetTile(Tile::from_char('B')),
Some(ActionId::TileSilo),
); );
tool_button( tool_button(
(0, 2), (0, 2),
"button_off", "button_off",
"Button", "Button",
Tool::SetTile(Tile::from_char('*')), Tool::SetTile(Tile::from_char('*')),
Some(ActionId::TileButton),
); );
tool_button( tool_button(
(0, 3), (0, 3),
"io_tile_off", "io_tile_off",
"Input/Output silo", "Input/Output silo",
Tool::SetTile(Tile::from_char('I')), Tool::SetTile(Tile::from_char('I')),
Some(ActionId::TileIOSilo),
); );
tool_button( tool_button(
(0, 4), (0, 4),
"flipper_off", "flipper_off",
"Flipper", "Flipper",
Tool::SetTile(Tile::from_char('F')), Tool::SetTile(Tile::from_char('F')),
Some(ActionId::TileFlipper),
);
tool_button(
(0, 5),
"digit_tool",
"Digit",
Tool::Digits(None),
Some(ActionId::TileDigit),
); );
tool_button((0, 5), "digit_tool", "Digit", Tool::Digits(None));
tool_button( tool_button(
(1, 0), (1, 0),
"marble", "marble",
"Marble", "Marble",
Tool::SetTile(Tile::from_char('o')), Tool::SetTile(Tile::from_char('o')),
Some(ActionId::TileMarble),
); );
match tool_button( match tool_button(
(1, 1), (1, 1),
self.tool_wire.texture_name_off(), self.tool_wire.texture_name_off(),
self.tool_wire.human_name(), self.tool_wire.human_name(),
Tool::Wire, Tool::Wire,
Some(ActionId::TileGroupWire),
) { ) {
Some(Scroll::Down) => self.tool_wire.next(), Some(Scroll::Down) => self.tool_wire.next(),
Some(Scroll::Up) => self.tool_wire.prev(), Some(Scroll::Up) => self.tool_wire.prev(),
@ -1151,6 +1169,7 @@ impl Editor {
self.tool_arrow.arrow_tile_texture_name(), self.tool_arrow.arrow_tile_texture_name(),
self.tool_arrow.arrow_tile_human_name(), self.tool_arrow.arrow_tile_human_name(),
Tool::Arrow, Tool::Arrow,
Some(ActionId::TileGroupArrow),
) { ) {
Some(Scroll::Down) => self.tool_arrow = self.tool_arrow.right(), Some(Scroll::Down) => self.tool_arrow = self.tool_arrow.right(),
Some(Scroll::Up) => self.tool_arrow = self.tool_arrow.left(), Some(Scroll::Up) => self.tool_arrow = self.tool_arrow.left(),
@ -1161,6 +1180,7 @@ impl Editor {
self.tool_mirror.texture_name(), self.tool_mirror.texture_name(),
self.tool_mirror.human_name(), self.tool_mirror.human_name(),
Tool::Mirror, Tool::Mirror,
Some(ActionId::TileGroupMirror),
) )
.is_some() .is_some()
{ {
@ -1171,6 +1191,7 @@ impl Editor {
self.tool_math.texture_name_off(), self.tool_math.texture_name_off(),
self.tool_math.human_name(), self.tool_math.human_name(),
Tool::Math, Tool::Math,
Some(ActionId::TileGroupMath),
) { ) {
Some(Scroll::Down) => self.tool_math.next(), Some(Scroll::Down) => self.tool_math.next(),
Some(Scroll::Up) => self.tool_math.prev(), Some(Scroll::Up) => self.tool_math.prev(),
@ -1181,6 +1202,7 @@ impl Editor {
self.tool_comparator.texture_name_off(), self.tool_comparator.texture_name_off(),
self.tool_comparator.human_name(), self.tool_comparator.human_name(),
Tool::Comparator, Tool::Comparator,
Some(ActionId::TileGroupCompare),
) { ) {
Some(Scroll::Down) => self.tool_comparator.next(), Some(Scroll::Down) => self.tool_comparator.next(),
Some(Scroll::Up) => self.tool_comparator.prev(), Some(Scroll::Up) => self.tool_comparator.prev(),

View file

@ -28,6 +28,19 @@ pub enum ActionId {
StepSim, StepSim,
CycleGroup, CycleGroup,
CycleGroupRevMod, CycleGroupRevMod,
TileBlock,
TileSilo,
TileButton,
TileIOSilo,
TileFlipper,
TileDigit,
TileMarble,
TileGroupWire,
TileGroupArrow,
TileGroupMirror,
TileGroupMath,
TileGroupCompare,
// just like in C, because this way doesn't need more dependencies // just like in C, because this way doesn't need more dependencies
_EnumSize, _EnumSize,
} }
@ -51,8 +64,20 @@ impl Default for Input {
bind_key(ActionId::StartSim, vec![], Enter); bind_key(ActionId::StartSim, vec![], Enter);
bind_key(ActionId::StopSim, vec![], Enter); bind_key(ActionId::StopSim, vec![], Enter);
bind_key(ActionId::StepSim, vec![], Space); bind_key(ActionId::StepSim, vec![], Space);
bind_key(ActionId::CycleGroup, vec![], R); bind_key(ActionId::CycleGroup, vec![], Tab);
bind_key(ActionId::CycleGroupRevMod, vec![], LShift); bind_key(ActionId::CycleGroupRevMod, vec![], LShift);
bind_key(ActionId::TileBlock, vec![], Q);
bind_key(ActionId::TileSilo, vec![], W);
bind_key(ActionId::TileButton, vec![], E);
bind_key(ActionId::TileIOSilo, vec![], R);
bind_key(ActionId::TileFlipper, vec![], T);
bind_key(ActionId::TileDigit, vec![], Y);
bind_key(ActionId::TileMarble, vec![], A);
bind_key(ActionId::TileGroupWire, vec![], S);
bind_key(ActionId::TileGroupArrow, vec![], D);
bind_key(ActionId::TileGroupMirror, vec![], F);
bind_key(ActionId::TileGroupMath, vec![], G);
bind_key(ActionId::TileGroupCompare, vec![], H);
Self { Self {
bindings, bindings,

View file

@ -304,6 +304,7 @@ pub fn scrollable_texture_option_button<T>(
option: T, option: T,
current: &mut T, current: &mut T,
border: f32, border: f32,
clicked_override: bool,
) -> Option<Scroll> ) -> Option<Scroll>
where where
T: PartialEq, T: PartialEq,
@ -329,7 +330,9 @@ where
32. / texture.width as f32, 32. / texture.width as f32,
Color::WHITE, Color::WHITE,
); );
if mouse.is_over(bounds) { if clicked_override {
*current = option;
} else if mouse.is_over(bounds) {
if mouse.left_click() { if mouse.left_click() {
*current = option; *current = option;
} }