Compare commits

...

4 commits

8 changed files with 185 additions and 291 deletions

View file

@ -3,7 +3,8 @@ Game store page: https://crispypin.itch.io/marble-machinations
## [Unreleased]
### 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
- in-grid text comments (not yet editable in-game)
- changelog file

243
Cargo.lock generated
View file

@ -2,12 +2,6 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
[[package]]
name = "aho-corasick"
version = "1.1.3"
@ -32,12 +26,6 @@ dependencies = [
"x11rb",
]
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "autocfg"
version = "1.4.0"
@ -46,16 +34,14 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bindgen"
version = "0.69.4"
version = "0.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
dependencies = [
"bitflags",
"cexpr",
"clang-sys",
"itertools",
"lazy_static",
"lazycell",
"log",
"prettyplease",
"proc-macro2",
@ -63,8 +49,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.79",
"which",
"syn",
]
[[package]]
@ -100,12 +85,6 @@ dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -141,28 +120,6 @@ dependencies = [
"cc",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if 0.1.10",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "either"
version = "1.13.0"
@ -185,12 +142,6 @@ version = "3.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "gethostname"
version = "0.4.3"
@ -207,31 +158,6 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "hashbrown"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96282e96bfcd3da0d3aa9938bedf1e50df3269b6db08b4876d2da0bb1a0841cf"
dependencies = [
"ahash",
"autocfg",
]
[[package]]
name = "hibitset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3ede5cfa60c958e60330d65163adbc4211e15a2653ad80eb0cce878de120121"
[[package]]
name = "home"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
dependencies = [
"windows-sys",
]
[[package]]
name = "itertools"
version = "0.12.1"
@ -247,18 +173,6 @@ version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.159"
@ -271,7 +185,7 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [
"cfg-if 1.0.0",
"cfg-if",
"windows-targets 0.52.6",
]
@ -307,12 +221,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "2.7.4"
@ -325,12 +233,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "mopa"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915"
[[package]]
name = "nom"
version = "7.1.3"
@ -440,15 +342,6 @@ dependencies = [
"objc2-metal",
]
[[package]]
name = "once_cell"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
dependencies = [
"portable-atomic",
]
[[package]]
name = "parking_lot"
version = "0.12.3"
@ -465,7 +358,7 @@ version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if 1.0.0",
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
@ -473,10 +366,10 @@ dependencies = [
]
[[package]]
name = "portable-atomic"
version = "1.9.0"
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "prettyplease"
@ -485,14 +378,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
dependencies = [
"proc-macro2",
"syn 2.0.79",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.86"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [
"unicode-ident",
]
@ -508,29 +401,26 @@ dependencies = [
[[package]]
name = "raylib"
version = "5.0.2"
version = "5.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2a7a6734329d7b872a418fe4cb08ca282eb66a6f4a3430bd4ee4e6a8cac6632"
checksum = "e5c54335590d1b6e6fbdbccee09dafdfd76a1111fc3c709eca949e71e81f7a8a"
dependencies = [
"cfg-if 1.0.0",
"lazy_static",
"libc",
"parking_lot",
"cfg-if",
"paste",
"raylib-sys",
"specs",
"specs-derive",
"seq-macro",
"thiserror",
]
[[package]]
name = "raylib-sys"
version = "5.0.2"
version = "5.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db5c6001cfaeec17210713227d11f3b1ba4b723bb12cff47d1b93c4060e10ad0"
checksum = "3ce5adc950b042db67f1f78f24f7e76563652ce24db032afe9ca9e534d8b7a13"
dependencies = [
"bindgen",
"cc",
"cmake",
"fs_extra",
]
[[package]]
@ -602,6 +492,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "seq-macro"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
[[package]]
name = "serde"
version = "1.0.210"
@ -619,7 +515,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.79",
"syn",
]
[[package]]
@ -640,62 +536,17 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "shred"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f08237e667ac94ad20f8878b5943d91a93ccb231428446c57c21c57779016d"
dependencies = [
"arrayvec",
"hashbrown",
"mopa",
"smallvec",
"tynm",
]
[[package]]
name = "shrev"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5ea33232fdcf1bf691ca33450e5a94dde13e1a8cbb8caabc5e4f9d761e10b1a"
[[package]]
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "specs"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff28a29366aff703d5da8a7e2c8875dc8453ac1118f842cbc0fa70c7db51240"
dependencies = [
"crossbeam-queue",
"hashbrown",
"hibitset",
"log",
"shred",
"shrev",
"tuple_utils",
]
[[package]]
name = "specs-derive"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e23e09360f3d2190fec4222cd9e19d3158d5da948c0d1ea362df617dd103511"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "syn"
version = "1.0.109"
version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [
"proc-macro2",
"quote",
@ -703,29 +554,23 @@ dependencies = [
]
[[package]]
name = "syn"
version = "2.0.79"
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
"thiserror-impl",
]
[[package]]
name = "tuple_utils"
version = "0.3.0"
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44834418e2c5b16f47bedf35c28e148db099187dd5feee6367fb2525863af4f1"
[[package]]
name = "tynm"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd30d05e69d1478e13fe3e7a853409cfec82cebc2cf9b8d613b3c6b0081781ed"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"nom",
"proc-macro2",
"quote",
"syn",
]
[[package]]
@ -734,18 +579,6 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "windows-sys"
version = "0.52.0"

View file

@ -6,7 +6,7 @@ default-run = "marble-machinations"
[dependencies]
arboard = { version = "3.4.1", default-features = false }
raylib = "5.0.2"
raylib = "5.5"
serde = { version = "1.0.210", features = ["derive"] }
serde_json = "1.0.128"

View file

@ -15,7 +15,6 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
- accessibility
- ui scaling
- background colour setting
- configurable hotkeys
- hotkeys for everything (no mouse needed to play)
- font selection (probably a lot of work)
- more levels
@ -34,7 +33,7 @@ logic mostly like https://git.crispypin.cc/CrispyPin/marble
#### undecided
- option to use 8-bit marbles?
- blueprint rotation?
- changable marble start direction?
- settable marble start direction?
## playtesting observations
- 'loops' introduces too many things (powering, redirection, generating zeroes)

View file

@ -1,11 +1,13 @@
use raylib::prelude::*;
use serde::{Deserialize, Serialize};
use crate::{input::Input, theme::FG_CHAPTER_TITLE, ui::text_button, Globals};
use crate::{input::Input, theme::FG_CHAPTER_TITLE, ui::text_button, util::Scroll, Globals};
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct Config {
pub input: Input,
#[serde(skip)]
scroll_offset: u32,
}
pub enum MenuReturn {
@ -18,19 +20,26 @@ pub enum MenuReturn {
impl Config {
#[must_use]
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals) -> MenuReturn {
d.draw_text("Settings", 16, 16, 30, FG_CHAPTER_TITLE);
match globals.mouse.scroll() {
Some(Scroll::Down) => self.scroll_offset += 64,
Some(Scroll::Up) => self.scroll_offset = self.scroll_offset.saturating_sub(64),
None => (),
}
let y = -(self.scroll_offset as i32);
if text_button(d, &globals.mouse, 10, 60, 80, "apply") {
d.draw_text("Settings", 16, y + 16, 30, FG_CHAPTER_TITLE);
if text_button(d, &globals.mouse, 10, y + 60, 80, "apply") {
return MenuReturn::StaySave;
}
if text_button(d, &globals.mouse, 100, 60, 80, "done") {
if text_button(d, &globals.mouse, 100, y + 60, 80, "done") {
return MenuReturn::ReturnSave;
}
if text_button(d, &globals.mouse, 190, 60, 80, "cancel") {
if text_button(d, &globals.mouse, 190, y + 60, 80, "cancel") {
return MenuReturn::ReturnCancel;
}
self.input.draw_edit(d, globals);
self.input.draw_edit(d, globals, y);
MenuReturn::Stay
}
}

View file

@ -345,28 +345,6 @@ impl Editor {
}
}
fn rotate_tool(&mut self, shift: bool) {
if shift {
match &self.active_tool {
Tool::Math => self.tool_math.prev(),
Tool::Comparator => self.tool_comparator.prev(),
Tool::Arrow => self.tool_arrow = self.tool_arrow.left(),
Tool::Mirror => self.tool_mirror.flip(),
Tool::Wire => self.tool_wire.prev(),
_ => (),
}
} else {
match &self.active_tool {
Tool::Math => self.tool_math.next(),
Tool::Comparator => self.tool_comparator.next(),
Tool::Arrow => self.tool_arrow = self.tool_arrow.right(),
Tool::Mirror => self.tool_mirror.flip(),
Tool::Wire => self.tool_wire.next(),
_ => (),
}
}
}
pub fn center_view(&mut self, d: &RaylibHandle) {
let tile_size = TILE_TEXTURE_SIZE * self.zoom;
let tile_x = self.source_board.grid.width() as f32 / 2. * tile_size;
@ -543,10 +521,29 @@ impl Editor {
self.center_view(rl);
}
if rl.is_key_pressed(KeyboardKey::KEY_R) {
self.rotate_tool(rl.is_key_down(KeyboardKey::KEY_LEFT_SHIFT));
if globals.is_pressed(ActionId::CycleGroup) {
if globals.is_held(ActionId::CycleGroupRevMod) {
match &self.active_tool {
Tool::Math => self.tool_math.prev(),
Tool::Comparator => self.tool_comparator.prev(),
Tool::Arrow => self.tool_arrow = self.tool_arrow.left(),
Tool::Mirror => self.tool_mirror.flip(),
Tool::Wire => self.tool_wire.prev(),
_ => (),
}
} else {
match &self.active_tool {
Tool::Math => self.tool_math.next(),
Tool::Comparator => self.tool_comparator.next(),
Tool::Arrow => self.tool_arrow = self.tool_arrow.right(),
Tool::Mirror => self.tool_mirror.flip(),
Tool::Wire => self.tool_wire.next(),
_ => (),
}
}
}
if !self.machine.debug_subticks.is_empty() {
if rl.is_key_pressed(KeyboardKey::KEY_N) {
self.machine.subtick_index += 1;
self.machine.subtick_index %= self.machine.debug_subticks.len();
@ -554,6 +551,7 @@ impl Editor {
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 let Some(clipboard) = &mut globals.clipboard {
@ -1064,8 +1062,11 @@ impl Editor {
draw_scaled_texture(d, globals.get_tex("eraser"), 236, y + 4, 2.);
}
let mut tool_button =
|(row, col): (i32, i32), texture: &str, tooltip: &'static str, tool_option: Tool| {
let mut tool_button = |(row, col): (i32, i32),
texture: &str,
tooltip: &'static str,
tool_option: Tool,
action: Option<ActionId>| {
let border = 4.;
let gap = 2.;
let button_size = 32. + border * 2.;
@ -1085,18 +1086,20 @@ impl Editor {
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);
tool_button((0, -2), "eraser", "Eraser", Tool::Erase, None);
tool_button(
(1, -2),
"selection",
"Select",
Tool::SelectArea(Selection::default()),
None,
);
tool_button((0, -1), "blueprint", "Blueprints", Tool::Blueprint);
tool_button((1, -1), "transparent", "None", Tool::None);
tool_button((0, -1), "blueprint", "Blueprints", Tool::Blueprint, None);
tool_button((1, -1), "transparent", "None", Tool::None, None);
if !hide_tile_tools {
tool_button(
@ -1104,44 +1107,57 @@ impl Editor {
"block",
"Block",
Tool::SetTile(Tile::from_char('#')),
Some(ActionId::TileBlock),
);
tool_button(
(0, 1),
"silo_off",
"Silo",
Tool::SetTile(Tile::from_char('B')),
Some(ActionId::TileSilo),
);
tool_button(
(0, 2),
"button_off",
"Button",
Tool::SetTile(Tile::from_char('*')),
Some(ActionId::TileButton),
);
tool_button(
(0, 3),
"io_tile_off",
"Input/Output silo",
Tool::SetTile(Tile::from_char('I')),
Some(ActionId::TileIOSilo),
);
tool_button(
(0, 4),
"flipper_off",
"Flipper",
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(
(1, 0),
"marble",
"Marble",
Tool::SetTile(Tile::from_char('o')),
Some(ActionId::TileMarble),
);
match tool_button(
(1, 1),
self.tool_wire.texture_name_off(),
self.tool_wire.human_name(),
Tool::Wire,
Some(ActionId::TileGroupWire),
) {
Some(Scroll::Down) => self.tool_wire.next(),
Some(Scroll::Up) => self.tool_wire.prev(),
@ -1153,6 +1169,7 @@ impl Editor {
self.tool_arrow.arrow_tile_texture_name(),
self.tool_arrow.arrow_tile_human_name(),
Tool::Arrow,
Some(ActionId::TileGroupArrow),
) {
Some(Scroll::Down) => self.tool_arrow = self.tool_arrow.right(),
Some(Scroll::Up) => self.tool_arrow = self.tool_arrow.left(),
@ -1163,6 +1180,7 @@ impl Editor {
self.tool_mirror.texture_name(),
self.tool_mirror.human_name(),
Tool::Mirror,
Some(ActionId::TileGroupMirror),
)
.is_some()
{
@ -1173,6 +1191,7 @@ impl Editor {
self.tool_math.texture_name_off(),
self.tool_math.human_name(),
Tool::Math,
Some(ActionId::TileGroupMath),
) {
Some(Scroll::Down) => self.tool_math.next(),
Some(Scroll::Up) => self.tool_math.prev(),
@ -1183,6 +1202,7 @@ impl Editor {
self.tool_comparator.texture_name_off(),
self.tool_comparator.human_name(),
Tool::Comparator,
Some(ActionId::TileGroupCompare),
) {
Some(Scroll::Down) => self.tool_comparator.next(),
Some(Scroll::Up) => self.tool_comparator.prev(),

View file

@ -26,6 +26,21 @@ pub enum ActionId {
StartSim,
StopSim,
StepSim,
CycleGroup,
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
_EnumSize,
}
@ -49,11 +64,25 @@ impl Default for Input {
bind_key(ActionId::StartSim, vec![], Enter);
bind_key(ActionId::StopSim, vec![], Enter);
bind_key(ActionId::StepSim, vec![], Space);
bind_key(ActionId::CycleGroup, vec![], Tab);
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 {
bindings,
states: Default::default(),
editing_input: None,
editing_binding: None,
}
}
}
@ -75,7 +104,7 @@ pub struct Input {
bindings: [Vec<Binding>; ActionId::SIZE],
states: [BindingState; ActionId::SIZE],
#[serde(skip)]
editing_input: Option<(ActionId, usize, BindingEdit)>,
editing_binding: Option<(ActionId, usize, BindingEdit)>,
}
#[derive(Clone, Debug)]
@ -86,42 +115,42 @@ enum BindingEdit {
}
impl Input {
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals) {
let mut y = 96;
if self.editing_input.is_some() {
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, y: i32) {
let mut y = y + 96;
if self.editing_binding.is_some() {
globals.mouse.clear();
}
let buttons_x = 220;
let binding_text_x = buttons_x + 135;
for action_index in 0..ActionId::SIZE {
let action = ActionId::from_usize(action_index).unwrap();
d.draw_text(&format!("{action:?}"), 16, y, 20, Color::ORANGE);
if self.bindings[action_index].is_empty() {
y += 32;
}
for (binding_index, binding) in self.bindings[action_index].iter().enumerate() {
if text_button(d, &globals.mouse, 160, y, 80, "remove") {
if text_button(d, &globals.mouse, buttons_x, y, 80, "remove") {
self.bindings[action_index].remove(binding_index);
return;
}
if text_button(d, &globals.mouse, 245, y, 45, "edit") {
self.editing_input = Some((action, binding_index, BindingEdit::Init));
if text_button(d, &globals.mouse, buttons_x + 85, y, 45, "edit") {
self.editing_binding = Some((action, binding_index, BindingEdit::Init));
}
let trigger = format!("{:?}", binding.trigger);
d.draw_text(&trigger, 300, y, 20, Color::LIMEGREEN);
let x = 310 + d.measure_text(&trigger, 20);
d.draw_text(&trigger, binding_text_x, y + 5, 20, Color::LIMEGREEN);
let x = binding_text_x + 10 + d.measure_text(&trigger, 20);
let modifiers = format!("{:?}", binding.modifiers);
d.draw_text(&modifiers, x, y, 20, Color::LIGHTBLUE);
d.draw_text(&modifiers, x, y + 5, 20, Color::LIGHTBLUE);
y += 32;
}
if text_button(d, &globals.mouse, 160, y, 130, "add binding") {
self.editing_input =
if text_button(d, &globals.mouse, buttons_x, y, 130, "add binding") {
self.editing_binding =
Some((action, self.bindings[action_index].len(), BindingEdit::Init));
}
y += 45;
}
if let Some((action, binding_index, edit_state)) = &mut self.editing_input {
if let Some((action, binding_index, edit_state)) = &mut self.editing_binding {
globals.mouse.update(d);
let border = screen_centered_rect(d, 368, 128);
d.draw_rectangle_rec(border, BG_LIGHT);
@ -198,11 +227,11 @@ impl Input {
} else {
binding_list.push(binding.clone());
}
self.editing_input = None;
self.editing_binding = None;
}
}
if text_button(d, &globals.mouse, x + 100, y + 40, 80, "cancel") {
self.editing_input = None;
self.editing_binding = None;
}
}
}

View file

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