Compare commits
No commits in common. "0b2a3991edf4d69edb17e322876dce3382bae15f" and "1cc8e999b7a42be87c9af9324f971a391ee6c82f" have entirely different histories.
0b2a3991ed
...
1cc8e999b7
15 changed files with 1104 additions and 1037 deletions
387
Cargo.lock
generated
387
Cargo.lock
generated
|
@ -3,16 +3,13 @@
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler2"
|
name = "aho-corasick"
|
||||||
version = "2.0.0"
|
version = "1.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
[[package]]
|
"memchr",
|
||||||
name = "allocator-api2"
|
]
|
||||||
version = "0.2.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arboard"
|
name = "arboard"
|
||||||
|
@ -36,10 +33,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bindgen"
|
||||||
version = "1.3.2"
|
version = "0.70.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cexpr",
|
||||||
|
"clang-sys",
|
||||||
|
"itertools",
|
||||||
|
"log",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"regex",
|
||||||
|
"rustc-hash",
|
||||||
|
"shlex",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
|
@ -57,16 +68,22 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "cc"
|
||||||
version = "1.22.0"
|
version = "1.1.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
|
||||||
|
dependencies = [
|
||||||
|
"shlex",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "cexpr"
|
||||||
version = "1.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -74,6 +91,17 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clang-sys"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||||
|
dependencies = [
|
||||||
|
"glob",
|
||||||
|
"libc",
|
||||||
|
"libloading",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
version = "5.4.0"
|
version = "5.4.0"
|
||||||
|
@ -84,25 +112,19 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color_quant"
|
name = "cmake"
|
||||||
version = "1.1.0"
|
version = "0.1.51"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crc32fast"
|
|
||||||
version = "1.4.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "either"
|
||||||
version = "1.0.2"
|
version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
|
@ -120,41 +142,6 @@ version = "3.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
|
checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fdeflate"
|
|
||||||
version = "0.3.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
|
|
||||||
dependencies = [
|
|
||||||
"simd-adler32",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "flate2"
|
|
||||||
version = "1.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
|
||||||
dependencies = [
|
|
||||||
"crc32fast",
|
|
||||||
"miniz_oxide",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "foldhash"
|
|
||||||
version = "0.1.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fontdue"
|
|
||||||
version = "0.9.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e57e16b3fe8ff4364c0661fdaac543fb38b29ea9bc9c2f45612d90adf931d2b"
|
|
||||||
dependencies = [
|
|
||||||
"hashbrown",
|
|
||||||
"ttf-parser",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gethostname"
|
name = "gethostname"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -166,33 +153,18 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glam"
|
name = "glob"
|
||||||
version = "0.27.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
|
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "itertools"
|
||||||
version = "0.15.2"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allocator-api2",
|
"either",
|
||||||
"equivalent",
|
|
||||||
"foldhash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "image"
|
|
||||||
version = "0.24.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
|
|
||||||
dependencies = [
|
|
||||||
"bytemuck",
|
|
||||||
"byteorder",
|
|
||||||
"color_quant",
|
|
||||||
"num-traits",
|
|
||||||
"png",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -207,6 +179,16 @@ version = "0.2.159"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libloading"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.14"
|
version = "0.4.14"
|
||||||
|
@ -229,41 +211,12 @@ version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "macroquad"
|
|
||||||
version = "0.4.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d2befbae373456143ef55aa93a73594d080adfb111dc32ec96a1123a3e4ff4ae"
|
|
||||||
dependencies = [
|
|
||||||
"fontdue",
|
|
||||||
"glam",
|
|
||||||
"image",
|
|
||||||
"macroquad_macro",
|
|
||||||
"miniquad",
|
|
||||||
"quad-rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "macroquad_macro"
|
|
||||||
version = "0.1.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "64b1d96218903768c1ce078b657c0d5965465c95a60d2682fd97443c9d2483dd"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "malloc_buf"
|
|
||||||
version = "0.0.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marble-machinations"
|
name = "marble-machinations"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arboard",
|
"arboard",
|
||||||
"macroquad",
|
"raylib",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -275,49 +228,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniquad"
|
name = "minimal-lexical"
|
||||||
version = "0.4.8"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fb3e758e46dbc45716a8a49ca9edc54b15bcca826277e80b1f690708f67f9e3"
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"ndk-sys",
|
|
||||||
"objc-rs",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "nom"
|
||||||
version = "0.8.8"
|
version = "7.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler2",
|
"memchr",
|
||||||
"simd-adler32",
|
"minimal-lexical",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ndk-sys"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e1bcdd74c20ad5d95aacd60ef9ba40fdf77f767051040541df557b7a9b2a2121"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "objc-rs"
|
|
||||||
version = "0.2.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "64a1e7069a2525126bf12a9f1f7916835fafade384fb27cabf698e745e2a1eb8"
|
|
||||||
dependencies = [
|
|
||||||
"malloc_buf",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -342,7 +265,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"block2",
|
"block2",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
@ -358,7 +281,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -388,7 +311,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"block2",
|
"block2",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
@ -400,7 +323,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -412,7 +335,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -443,16 +366,19 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "png"
|
name = "paste"
|
||||||
version = "0.17.16"
|
version = "1.0.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"proc-macro2",
|
||||||
"crc32fast",
|
"syn",
|
||||||
"fdeflate",
|
|
||||||
"flate2",
|
|
||||||
"miniz_oxide",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -464,12 +390,6 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "quad-rand"
|
|
||||||
version = "0.2.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a651516ddc9168ebd67b24afd085a718be02f8858fe406591b013d101ce2f40"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.37"
|
version = "1.0.37"
|
||||||
|
@ -479,22 +399,81 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raylib"
|
||||||
|
version = "5.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e5c54335590d1b6e6fbdbccee09dafdfd76a1111fc3c709eca949e71e81f7a8a"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"paste",
|
||||||
|
"raylib-sys",
|
||||||
|
"seq-macro",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raylib-sys"
|
||||||
|
version = "5.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ce5adc950b042db67f1f78f24f7e76563652ce24db032afe9ca9e534d8b7a13"
|
||||||
|
dependencies = [
|
||||||
|
"bindgen",
|
||||||
|
"cc",
|
||||||
|
"cmake",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.7"
|
version = "0.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.37"
|
version = "0.38.37"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
|
@ -513,6 +492,12 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "seq-macro"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.210"
|
version = "1.0.210"
|
||||||
|
@ -546,10 +531,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simd-adler32"
|
name = "shlex"
|
||||||
version = "0.3.7"
|
version = "1.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
|
@ -569,10 +554,24 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ttf-parser"
|
name = "thiserror"
|
||||||
version = "0.21.1"
|
version = "1.0.69"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
|
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
|
@ -580,28 +579,6 @@ version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
|
|
|
@ -6,8 +6,7 @@ default-run = "marble-machinations"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arboard = { version = "3.4.1", default-features = false }
|
arboard = { version = "3.4.1", default-features = false }
|
||||||
macroquad = "0.4"
|
raylib = "5.5"
|
||||||
# raylib = "5.5"
|
|
||||||
serde = { version = "1.0.210", features = ["derive"] }
|
serde = { version = "1.0.210", features = ["derive"] }
|
||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
|
|
||||||
|
|
24
src/board.rs
24
src/board.rs
|
@ -1,4 +1,8 @@
|
||||||
use macroquad::{color::colors, prelude::*};
|
use raylib::{
|
||||||
|
color::Color,
|
||||||
|
drawing::{RaylibDraw, RaylibDrawHandle},
|
||||||
|
math::Vector2,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -67,18 +71,18 @@ impl Board {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_comments(&self, offset: Vec2, scale: f32) {
|
pub fn draw_comments(&self, d: &mut RaylibDrawHandle, offset: Vector2, scale: f32) {
|
||||||
let tile_size = TILE_TEXTURE_SIZE * scale;
|
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
||||||
let font_size = 10. * scale.max(1.);
|
let font_size = 10 * (scale as i32).max(1);
|
||||||
let line_space = 12. * scale.max(1.);
|
let line_space = 12 * (scale as i32).max(1);
|
||||||
|
|
||||||
for comment in &self.comments {
|
for comment in &self.comments {
|
||||||
let x = comment.x as f32 * tile_size + offset.x;
|
let x = comment.x * tile_size + offset.x as i32;
|
||||||
let y = comment.y as f32 * tile_size + offset.y;
|
let y = comment.y * tile_size + offset.y as i32;
|
||||||
let y = y + (tile_size - font_size) / 2.; // center vertically in the grid row
|
let y = y + (tile_size - font_size) / 2; // center vertically in the grid row
|
||||||
for (i, line) in comment.text.lines().enumerate() {
|
for (i, line) in comment.text.lines().enumerate() {
|
||||||
let y = y + line_space * i as f32;
|
let y = y + line_space * i as i32;
|
||||||
draw_text(line, x, y, font_size, colors::ORANGE);
|
d.draw_text(line, x, y, font_size, Color::ORANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use macroquad::{color::colors, prelude::*};
|
use raylib::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -17,7 +17,7 @@ pub struct Config {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub show_power_direction: bool,
|
pub show_power_direction: bool,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
scroll_offset: f32,
|
scroll_offset: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum MenuReturn {
|
pub enum MenuReturn {
|
||||||
|
@ -29,38 +29,38 @@ pub enum MenuReturn {
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn draw_edit(&mut self, globals: &mut Globals) -> MenuReturn {
|
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals) -> MenuReturn {
|
||||||
match globals.mouse.scroll() {
|
match globals.mouse.scroll() {
|
||||||
Some(Scroll::Down) => self.scroll_offset += 64.,
|
Some(Scroll::Down) => self.scroll_offset += 64,
|
||||||
Some(Scroll::Up) => self.scroll_offset = (self.scroll_offset - 64.).max(0.),
|
Some(Scroll::Up) => self.scroll_offset = self.scroll_offset.saturating_sub(64),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
let mut y = -self.scroll_offset + 15.;
|
let mut y = -(self.scroll_offset as i32) + 15;
|
||||||
draw_text("Settings", 16., y, 30., FG_CHAPTER_TITLE);
|
d.draw_text("Settings", 16, y, 30, FG_CHAPTER_TITLE);
|
||||||
y += 40.;
|
y += 40;
|
||||||
|
|
||||||
if text_button(&globals.mouse, 10., y, 80., "apply") {
|
if text_button(d, &globals.mouse, 10, y, 80, "apply") {
|
||||||
return MenuReturn::StaySave;
|
return MenuReturn::StaySave;
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, 100., y, 80., "done") {
|
if text_button(d, &globals.mouse, 100, y, 80, "done") {
|
||||||
return MenuReturn::ReturnSave;
|
return MenuReturn::ReturnSave;
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, 190., y, 80., "cancel") {
|
if text_button(d, &globals.mouse, 190, y, 80, "cancel") {
|
||||||
return MenuReturn::ReturnCancel;
|
return MenuReturn::ReturnCancel;
|
||||||
}
|
}
|
||||||
y += 40.;
|
y += 40;
|
||||||
|
|
||||||
let mut toggle = |value, text| {
|
let mut toggle = |value, text| {
|
||||||
toggle_button(&globals.mouse, 10., y, 30., 30., value);
|
toggle_button((d, &globals.mouse), 10, y, 30, 30, value);
|
||||||
draw_text(text, 50., y + 5., 20., colors::WHITE);
|
d.draw_text(text, 50, y + 5, 20, Color::WHITE);
|
||||||
y += 40.;
|
y += 40;
|
||||||
};
|
};
|
||||||
|
|
||||||
toggle(&mut self.show_power_direction, "show power directions");
|
toggle(&mut self.show_power_direction, "show power directions");
|
||||||
toggle(&mut self.show_debug_timing, "show debug timing");
|
toggle(&mut self.show_debug_timing, "show debug timing");
|
||||||
|
|
||||||
// self.input.update(d);
|
// self.input.update(d);
|
||||||
self.input.draw_edit(globals, y);
|
self.input.draw_edit(d, globals, y);
|
||||||
MenuReturn::Stay
|
MenuReturn::Stay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
577
src/editor.rs
577
src/editor.rs
File diff suppressed because it is too large
Load diff
368
src/input.rs
368
src/input.rs
|
@ -1,12 +1,17 @@
|
||||||
use std::{collections::BTreeMap, mem::transmute, vec};
|
use std::{collections::BTreeMap, mem::transmute, vec};
|
||||||
|
|
||||||
use macroquad::{color::colors, prelude::*};
|
use raylib::{
|
||||||
|
color::Color,
|
||||||
|
drawing::{RaylibDraw, RaylibDrawHandle},
|
||||||
|
ffi::{KeyboardKey, MouseButton},
|
||||||
|
RaylibHandle,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
theme::{BG_DARK, BG_LIGHT},
|
theme::{BG_DARK, BG_LIGHT},
|
||||||
ui::text_button,
|
ui::text_button,
|
||||||
util::{draw_rectangle_rec, screen_centered_rect},
|
util::{rect, screen_centered_rect},
|
||||||
Globals,
|
Globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,89 +132,89 @@ enum BindingEdit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn draw_edit(&mut self, globals: &mut Globals, mut y: f32) {
|
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, mut y: i32) {
|
||||||
if self.editing_binding.is_some() {
|
if self.editing_binding.is_some() {
|
||||||
globals.mouse.clear();
|
globals.mouse.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons_x = 220.;
|
let buttons_x = 220;
|
||||||
let binding_text_x = buttons_x + 135.;
|
let binding_text_x = buttons_x + 135;
|
||||||
|
|
||||||
for action_index in 0..ActionId::SIZE {
|
for action_index in 0..ActionId::SIZE {
|
||||||
let action = ActionId::from_usize(action_index).unwrap();
|
let action = ActionId::from_usize(action_index).unwrap();
|
||||||
|
|
||||||
// if self.action_states[action_index] == BindingState::Pressed {
|
// if self.action_states[action_index] == BindingState::Pressed {
|
||||||
// draw_rectangle(200, y, 20, 20, colors::LIMEGREEN);
|
// d.draw_rectangle(200, y, 20, 20, Color::LIMEGREEN);
|
||||||
// }
|
// }
|
||||||
draw_text(&format!("{action:?}"), 16., y, 20., colors::ORANGE);
|
d.draw_text(&format!("{action:?}"), 16, y, 20, Color::ORANGE);
|
||||||
for (binding_index, binding) in self.action_bindings[action_index].iter().enumerate() {
|
for (binding_index, binding) in self.action_bindings[action_index].iter().enumerate() {
|
||||||
if text_button(&globals.mouse, buttons_x, y, 80., "remove") {
|
if text_button(d, &globals.mouse, buttons_x, y, 80, "remove") {
|
||||||
self.action_bindings[action_index].remove(binding_index);
|
self.action_bindings[action_index].remove(binding_index);
|
||||||
self.update_modifier_blocks();
|
self.update_modifier_blocks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, buttons_x + 85., y, 45., "edit") {
|
if text_button(d, &globals.mouse, buttons_x + 85, y, 45, "edit") {
|
||||||
self.editing_binding = Some((action, binding_index, BindingEdit::Init));
|
self.editing_binding = Some((action, binding_index, BindingEdit::Init));
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
let trigger = format!("{:?}", binding.trigger);
|
let trigger = format!("{:?}", binding.trigger);
|
||||||
let mut x = binding_text_x;
|
let mut x = binding_text_x;
|
||||||
draw_text(&trigger, x, y + 5., 20., colors::GREEN);
|
d.draw_text(&trigger, x, y + 5, 20, Color::LIMEGREEN);
|
||||||
x += 10. + measure_text(&trigger, None, 20, 1.).width;
|
x += 10 + d.measure_text(&trigger, 20);
|
||||||
//
|
//
|
||||||
let modifiers = format!("{:?}", binding.modifiers);
|
let modifiers = format!("{:?}", binding.modifiers);
|
||||||
draw_text(&modifiers, x, y + 5., 20., colors::BLUE);
|
d.draw_text(&modifiers, x, y + 5, 20, Color::LIGHTBLUE);
|
||||||
x += 10. + measure_text(&modifiers, None, 20, 1.).width;
|
x += 10 + d.measure_text(&modifiers, 20);
|
||||||
//
|
//
|
||||||
let conflicts = conflicts(&self.action_bindings, binding, action);
|
let conflicts = conflicts(&self.action_bindings, binding, action);
|
||||||
if !conflicts.is_empty() {
|
if !conflicts.is_empty() {
|
||||||
let conflict_text = format!("also used by: {conflicts:?}");
|
let conflict_text = format!("also used by: {conflicts:?}");
|
||||||
draw_text(&conflict_text, x, y + 5., 20., colors::ORANGE);
|
d.draw_text(&conflict_text, x, y + 5, 20, Color::ORANGERED);
|
||||||
x += 10. + measure_text(&conflict_text, None, 20, 1.).width
|
x += 10 + d.measure_text(&conflict_text, 20);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if !binding.blocking_modifiers.is_empty() {
|
if !binding.blocking_modifiers.is_empty() {
|
||||||
let blocking_text = format!("not while: {:?}", binding.blocking_modifiers);
|
let blocking_text = format!("not while: {:?}", binding.blocking_modifiers);
|
||||||
draw_text(&blocking_text, x, y + 5., 20., colors::GRAY);
|
d.draw_text(&blocking_text, x, y + 5, 20, Color::GRAY);
|
||||||
}
|
}
|
||||||
y += 32.;
|
y += 32;
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, buttons_x, y, 130., "add binding") {
|
if text_button(d, &globals.mouse, buttons_x, y, 130, "add binding") {
|
||||||
self.editing_binding = Some((
|
self.editing_binding = Some((
|
||||||
action,
|
action,
|
||||||
self.action_bindings[action_index].len(),
|
self.action_bindings[action_index].len(),
|
||||||
BindingEdit::Init,
|
BindingEdit::Init,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
y += 45.;
|
y += 45;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((action, binding_index, edit_state)) = &mut self.editing_binding {
|
if let Some((action, binding_index, edit_state)) = &mut self.editing_binding {
|
||||||
globals.mouse.update();
|
globals.mouse.update(d);
|
||||||
let border = screen_centered_rect(408., 128.);
|
let border = screen_centered_rect(d, 408, 128);
|
||||||
draw_rectangle_rec(border, BG_LIGHT);
|
d.draw_rectangle_rec(border, BG_LIGHT);
|
||||||
let bounds = screen_centered_rect(400., 120.);
|
let bounds = screen_centered_rect(d, 400, 120);
|
||||||
draw_rectangle_rec(bounds, BG_DARK);
|
d.draw_rectangle_rec(bounds, BG_DARK);
|
||||||
let x = bounds.x;
|
let x = bounds.x as i32;
|
||||||
let y = bounds.y;
|
let y = bounds.y as i32;
|
||||||
draw_text(
|
d.draw_text(
|
||||||
&format!("editing binding for {action:?}"),
|
&format!("editing binding for {action:?}"),
|
||||||
x + 10.,
|
x + 10,
|
||||||
y + 5.,
|
y + 5,
|
||||||
20.,
|
20,
|
||||||
colors::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
let y = y + 30.;
|
let y = y + 30;
|
||||||
let ok_btn_x = x + 10.;
|
let ok_btn_x = x + 10;
|
||||||
let ok_btn_y = y + 40.;
|
let ok_btn_y = y + 40;
|
||||||
let ok_btn_width = 80.;
|
let ok_btn_width = 80;
|
||||||
let ok_btn_rect = Rect::new(ok_btn_x, ok_btn_y, ok_btn_width, 30.);
|
let ok_btn_rect = rect(ok_btn_x, ok_btn_y, ok_btn_width, 30);
|
||||||
|
|
||||||
for key_index in 0..Button::SIZE {
|
for key_index in 0..Button::SIZE {
|
||||||
let key = Button::from_usize(key_index).unwrap();
|
let key = Button::from_usize(key_index).unwrap();
|
||||||
match edit_state {
|
match edit_state {
|
||||||
BindingEdit::Init => {
|
BindingEdit::Init => {
|
||||||
if key.just_pressed() {
|
if key.just_pressed(d) {
|
||||||
*edit_state = BindingEdit::Adding(Binding {
|
*edit_state = BindingEdit::Adding(Binding {
|
||||||
blocking_modifiers: Vec::new(),
|
blocking_modifiers: Vec::new(),
|
||||||
modifiers: Vec::new(),
|
modifiers: Vec::new(),
|
||||||
|
@ -218,12 +223,12 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingEdit::Adding(binding) => {
|
BindingEdit::Adding(binding) => {
|
||||||
if key.just_pressed() {
|
if key.just_pressed(d) {
|
||||||
if key != binding.trigger && !binding.modifiers.contains(&key) {
|
if key != binding.trigger && !binding.modifiers.contains(&key) {
|
||||||
binding.modifiers.push(binding.trigger);
|
binding.modifiers.push(binding.trigger);
|
||||||
binding.trigger = key;
|
binding.trigger = key;
|
||||||
}
|
}
|
||||||
} else if key.released() {
|
} else if key.released(d) {
|
||||||
if let Some(i) = binding.modifiers.iter().position(|&k| k == key) {
|
if let Some(i) = binding.modifiers.iter().position(|&k| k == key) {
|
||||||
binding.modifiers.remove(i);
|
binding.modifiers.remove(i);
|
||||||
binding.modifiers.push(binding.trigger);
|
binding.modifiers.push(binding.trigger);
|
||||||
|
@ -235,7 +240,7 @@ impl Input {
|
||||||
BindingEdit::Releasing(_binding) => {
|
BindingEdit::Releasing(_binding) => {
|
||||||
let clicking_ok =
|
let clicking_ok =
|
||||||
globals.mouse.is_over(ok_btn_rect) && key == Button::MouseLeft;
|
globals.mouse.is_over(ok_btn_rect) && key == Button::MouseLeft;
|
||||||
if key.just_pressed() && !clicking_ok {
|
if key.just_pressed(d) && !clicking_ok {
|
||||||
*edit_state = BindingEdit::Adding(Binding {
|
*edit_state = BindingEdit::Adding(Binding {
|
||||||
blocking_modifiers: Vec::new(),
|
blocking_modifiers: Vec::new(),
|
||||||
modifiers: Vec::new(),
|
modifiers: Vec::new(),
|
||||||
|
@ -248,25 +253,25 @@ impl Input {
|
||||||
|
|
||||||
if let BindingEdit::Adding(b) | BindingEdit::Releasing(b) = &edit_state {
|
if let BindingEdit::Adding(b) | BindingEdit::Releasing(b) = &edit_state {
|
||||||
let colour = if matches!(edit_state, BindingEdit::Releasing(_)) {
|
let colour = if matches!(edit_state, BindingEdit::Releasing(_)) {
|
||||||
colors::GREEN
|
Color::GREEN
|
||||||
} else {
|
} else {
|
||||||
colors::ORANGE
|
Color::ORANGE
|
||||||
};
|
};
|
||||||
let text = format!("{:?} + {:?}", b.modifiers, b.trigger);
|
let text = format!("{:?} + {:?}", b.modifiers, b.trigger);
|
||||||
draw_text(&text, x + 5., y + 5., 20., colour);
|
d.draw_text(&text, x + 5, y + 5, 20, colour);
|
||||||
|
|
||||||
let conflicts = conflicts(&self.action_bindings, b, *action);
|
let conflicts = conflicts(&self.action_bindings, b, *action);
|
||||||
if !conflicts.is_empty() {
|
if !conflicts.is_empty() {
|
||||||
draw_text(
|
d.draw_text(
|
||||||
&format!("conflicts: {conflicts:?}"),
|
&format!("conflicts: {conflicts:?}"),
|
||||||
x + 200.,
|
x + 200,
|
||||||
y + 40.,
|
y + 40,
|
||||||
20.,
|
20,
|
||||||
colors::ORANGE,
|
Color::ORANGERED,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, ok_btn_x, ok_btn_y, ok_btn_width, "ok") {
|
if text_button(d, &globals.mouse, ok_btn_x, ok_btn_y, ok_btn_width, "ok") {
|
||||||
if let BindingEdit::Releasing(binding) = edit_state {
|
if let BindingEdit::Releasing(binding) = edit_state {
|
||||||
let binding_list = &mut self.action_bindings[*action as usize];
|
let binding_list = &mut self.action_bindings[*action as usize];
|
||||||
if *binding_index < binding_list.len() {
|
if *binding_index < binding_list.len() {
|
||||||
|
@ -278,17 +283,17 @@ impl Input {
|
||||||
self.update_modifier_blocks();
|
self.update_modifier_blocks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text_button(&globals.mouse, x + 100., y + 40., 80., "cancel") {
|
if text_button(d, &globals.mouse, x + 100, y + 40, 80, "cancel") {
|
||||||
self.editing_binding = None;
|
self.editing_binding = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self, rl: &RaylibHandle) {
|
||||||
for i in 0..Button::SIZE {
|
for i in 0..Button::SIZE {
|
||||||
let button = Button::from_usize(i).unwrap();
|
let button = Button::from_usize(i).unwrap();
|
||||||
let state = &mut self.key_states[i];
|
let state = &mut self.key_states[i];
|
||||||
*state = if button.is_down() {
|
*state = if button.is_down(rl) {
|
||||||
match state {
|
match state {
|
||||||
BindingState::Off | BindingState::Released => BindingState::Pressed,
|
BindingState::Off | BindingState::Released => BindingState::Pressed,
|
||||||
BindingState::Pressed | BindingState::Held => BindingState::Held,
|
BindingState::Pressed | BindingState::Held => BindingState::Held,
|
||||||
|
@ -459,10 +464,10 @@ enum Button {
|
||||||
MouseLeft,
|
MouseLeft,
|
||||||
MouseRight,
|
MouseRight,
|
||||||
MouseMiddle,
|
MouseMiddle,
|
||||||
// Mouse3,
|
Mouse3,
|
||||||
// Mouse4,
|
Mouse4,
|
||||||
// Mouse5,
|
Mouse5,
|
||||||
// Mouse6,
|
Mouse6,
|
||||||
Apostrophe,
|
Apostrophe,
|
||||||
Comma,
|
Comma,
|
||||||
Minus,
|
Minus,
|
||||||
|
@ -569,12 +574,14 @@ enum Button {
|
||||||
KpEnter,
|
KpEnter,
|
||||||
KpEqual,
|
KpEqual,
|
||||||
Back,
|
Back,
|
||||||
|
VolumeUp,
|
||||||
|
VolumeDown,
|
||||||
//
|
//
|
||||||
_EnumSize,
|
_EnumSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RlInput {
|
enum RlInput {
|
||||||
Key(KeyCode),
|
Key(KeyboardKey),
|
||||||
Mouse(MouseButton),
|
Mouse(MouseButton),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,143 +596,146 @@ impl Button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_down(self) -> bool {
|
fn is_down(self, rl: &RaylibHandle) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => is_key_down(key),
|
RlInput::Key(key) => rl.is_key_down(key),
|
||||||
RlInput::Mouse(btn) => is_mouse_button_down(btn),
|
RlInput::Mouse(btn) => rl.is_mouse_button_down(btn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn just_pressed(self) -> bool {
|
fn just_pressed(self, rl: &RaylibHandle) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => is_key_pressed(key),
|
RlInput::Key(key) => rl.is_key_pressed(key),
|
||||||
RlInput::Mouse(btn) => is_mouse_button_pressed(btn),
|
RlInput::Mouse(btn) => rl.is_mouse_button_pressed(btn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn released(self) -> bool {
|
fn released(self, rl: &RaylibHandle) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => is_key_released(key),
|
RlInput::Key(key) => rl.is_key_released(key),
|
||||||
RlInput::Mouse(btn) => is_mouse_button_released(btn),
|
RlInput::Mouse(btn) => rl.is_mouse_button_released(btn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_raylib(self) -> RlInput {
|
fn to_raylib(self) -> RlInput {
|
||||||
|
use KeyboardKey::*;
|
||||||
use RlInput::*;
|
use RlInput::*;
|
||||||
match self {
|
match self {
|
||||||
Button::MouseLeft => Mouse(MouseButton::Left),
|
Button::MouseLeft => Mouse(MouseButton::MOUSE_BUTTON_LEFT),
|
||||||
Button::MouseRight => Mouse(MouseButton::Right),
|
Button::MouseRight => Mouse(MouseButton::MOUSE_BUTTON_RIGHT),
|
||||||
Button::MouseMiddle => Mouse(MouseButton::Middle),
|
Button::MouseMiddle => Mouse(MouseButton::MOUSE_BUTTON_MIDDLE),
|
||||||
// Button::Mouse3 => Mouse(MouseButton::MOUSE_BUTTON_SIDE),
|
Button::Mouse3 => Mouse(MouseButton::MOUSE_BUTTON_SIDE),
|
||||||
// Button::Mouse4 => Mouse(MouseButton::MOUSE_BUTTON_EXTRA),
|
Button::Mouse4 => Mouse(MouseButton::MOUSE_BUTTON_EXTRA),
|
||||||
// Button::Mouse5 => Mouse(MouseButton::MOUSE_BUTTON_FORWARD),
|
Button::Mouse5 => Mouse(MouseButton::MOUSE_BUTTON_FORWARD),
|
||||||
// Button::Mouse6 => Mouse(MouseButton::MOUSE_BUTTON_BACK),
|
Button::Mouse6 => Mouse(MouseButton::MOUSE_BUTTON_BACK),
|
||||||
Button::Apostrophe => Key(KeyCode::Apostrophe),
|
Button::Apostrophe => Key(KEY_APOSTROPHE),
|
||||||
Button::Comma => Key(KeyCode::Comma),
|
Button::Comma => Key(KEY_COMMA),
|
||||||
Button::Minus => Key(KeyCode::Minus),
|
Button::Minus => Key(KEY_MINUS),
|
||||||
Button::Period => Key(KeyCode::Period),
|
Button::Period => Key(KEY_PERIOD),
|
||||||
Button::Slash => Key(KeyCode::Slash),
|
Button::Slash => Key(KEY_SLASH),
|
||||||
Button::Zero => Key(KeyCode::Key0),
|
Button::Zero => Key(KEY_ZERO),
|
||||||
Button::One => Key(KeyCode::Key1),
|
Button::One => Key(KEY_ONE),
|
||||||
Button::Two => Key(KeyCode::Key2),
|
Button::Two => Key(KEY_TWO),
|
||||||
Button::Three => Key(KeyCode::Key3),
|
Button::Three => Key(KEY_THREE),
|
||||||
Button::Four => Key(KeyCode::Key4),
|
Button::Four => Key(KEY_FOUR),
|
||||||
Button::Five => Key(KeyCode::Key5),
|
Button::Five => Key(KEY_FIVE),
|
||||||
Button::Six => Key(KeyCode::Key6),
|
Button::Six => Key(KEY_SIX),
|
||||||
Button::Seven => Key(KeyCode::Key7),
|
Button::Seven => Key(KEY_SEVEN),
|
||||||
Button::Eight => Key(KeyCode::Key8),
|
Button::Eight => Key(KEY_EIGHT),
|
||||||
Button::Nine => Key(KeyCode::Key9),
|
Button::Nine => Key(KEY_NINE),
|
||||||
Button::Semicolon => Key(KeyCode::Semicolon),
|
Button::Semicolon => Key(KEY_SEMICOLON),
|
||||||
Button::Equal => Key(KeyCode::Equal),
|
Button::Equal => Key(KEY_EQUAL),
|
||||||
Button::A => Key(KeyCode::A),
|
Button::A => Key(KEY_A),
|
||||||
Button::B => Key(KeyCode::B),
|
Button::B => Key(KEY_B),
|
||||||
Button::C => Key(KeyCode::C),
|
Button::C => Key(KEY_C),
|
||||||
Button::D => Key(KeyCode::D),
|
Button::D => Key(KEY_D),
|
||||||
Button::E => Key(KeyCode::E),
|
Button::E => Key(KEY_E),
|
||||||
Button::F => Key(KeyCode::F),
|
Button::F => Key(KEY_F),
|
||||||
Button::G => Key(KeyCode::G),
|
Button::G => Key(KEY_G),
|
||||||
Button::H => Key(KeyCode::H),
|
Button::H => Key(KEY_H),
|
||||||
Button::I => Key(KeyCode::I),
|
Button::I => Key(KEY_I),
|
||||||
Button::J => Key(KeyCode::J),
|
Button::J => Key(KEY_J),
|
||||||
Button::K => Key(KeyCode::K),
|
Button::K => Key(KEY_K),
|
||||||
Button::L => Key(KeyCode::L),
|
Button::L => Key(KEY_L),
|
||||||
Button::M => Key(KeyCode::M),
|
Button::M => Key(KEY_M),
|
||||||
Button::N => Key(KeyCode::N),
|
Button::N => Key(KEY_N),
|
||||||
Button::O => Key(KeyCode::O),
|
Button::O => Key(KEY_O),
|
||||||
Button::P => Key(KeyCode::P),
|
Button::P => Key(KEY_P),
|
||||||
Button::Q => Key(KeyCode::Q),
|
Button::Q => Key(KEY_Q),
|
||||||
Button::R => Key(KeyCode::R),
|
Button::R => Key(KEY_R),
|
||||||
Button::S => Key(KeyCode::S),
|
Button::S => Key(KEY_S),
|
||||||
Button::T => Key(KeyCode::T),
|
Button::T => Key(KEY_T),
|
||||||
Button::U => Key(KeyCode::U),
|
Button::U => Key(KEY_U),
|
||||||
Button::V => Key(KeyCode::V),
|
Button::V => Key(KEY_V),
|
||||||
Button::W => Key(KeyCode::W),
|
Button::W => Key(KEY_W),
|
||||||
Button::X => Key(KeyCode::X),
|
Button::X => Key(KEY_X),
|
||||||
Button::Y => Key(KeyCode::Y),
|
Button::Y => Key(KEY_Y),
|
||||||
Button::Z => Key(KeyCode::Z),
|
Button::Z => Key(KEY_Z),
|
||||||
Button::LeftBracket => Key(KeyCode::LeftBracket),
|
Button::LeftBracket => Key(KEY_LEFT_BRACKET),
|
||||||
Button::Backslash => Key(KeyCode::Backslash),
|
Button::Backslash => Key(KEY_BACKSLASH),
|
||||||
Button::RightBracket => Key(KeyCode::RightBracket),
|
Button::RightBracket => Key(KEY_RIGHT_BRACKET),
|
||||||
Button::Grave => Key(KeyCode::GraveAccent),
|
Button::Grave => Key(KEY_GRAVE),
|
||||||
Button::Space => Key(KeyCode::Space),
|
Button::Space => Key(KEY_SPACE),
|
||||||
Button::Escape => Key(KeyCode::Escape),
|
Button::Escape => Key(KEY_ESCAPE),
|
||||||
Button::Enter => Key(KeyCode::Enter),
|
Button::Enter => Key(KEY_ENTER),
|
||||||
Button::Tab => Key(KeyCode::Tab),
|
Button::Tab => Key(KEY_TAB),
|
||||||
Button::Backspace => Key(KeyCode::Backspace),
|
Button::Backspace => Key(KEY_BACKSPACE),
|
||||||
Button::Insert => Key(KeyCode::Insert),
|
Button::Insert => Key(KEY_INSERT),
|
||||||
Button::Delete => Key(KeyCode::Delete),
|
Button::Delete => Key(KEY_DELETE),
|
||||||
Button::Right => Key(KeyCode::Right),
|
Button::Right => Key(KEY_RIGHT),
|
||||||
Button::Left => Key(KeyCode::Left),
|
Button::Left => Key(KEY_LEFT),
|
||||||
Button::Down => Key(KeyCode::Down),
|
Button::Down => Key(KEY_DOWN),
|
||||||
Button::Up => Key(KeyCode::Up),
|
Button::Up => Key(KEY_UP),
|
||||||
Button::PageUp => Key(KeyCode::PageUp),
|
Button::PageUp => Key(KEY_PAGE_UP),
|
||||||
Button::PageDown => Key(KeyCode::PageDown),
|
Button::PageDown => Key(KEY_PAGE_DOWN),
|
||||||
Button::Home => Key(KeyCode::Home),
|
Button::Home => Key(KEY_HOME),
|
||||||
Button::End => Key(KeyCode::End),
|
Button::End => Key(KEY_END),
|
||||||
Button::CapsLock => Key(KeyCode::CapsLock),
|
Button::CapsLock => Key(KEY_CAPS_LOCK),
|
||||||
Button::ScrollLock => Key(KeyCode::ScrollLock),
|
Button::ScrollLock => Key(KEY_SCROLL_LOCK),
|
||||||
Button::NumLock => Key(KeyCode::NumLock),
|
Button::NumLock => Key(KEY_NUM_LOCK),
|
||||||
Button::PrintScreen => Key(KeyCode::PrintScreen),
|
Button::PrintScreen => Key(KEY_PRINT_SCREEN),
|
||||||
Button::Pause => Key(KeyCode::Pause),
|
Button::Pause => Key(KEY_PAUSE),
|
||||||
Button::F1 => Key(KeyCode::F1),
|
Button::F1 => Key(KEY_F1),
|
||||||
Button::F2 => Key(KeyCode::F2),
|
Button::F2 => Key(KEY_F2),
|
||||||
Button::F3 => Key(KeyCode::F3),
|
Button::F3 => Key(KEY_F3),
|
||||||
Button::F4 => Key(KeyCode::F4),
|
Button::F4 => Key(KEY_F4),
|
||||||
Button::F5 => Key(KeyCode::F5),
|
Button::F5 => Key(KEY_F5),
|
||||||
Button::F6 => Key(KeyCode::F6),
|
Button::F6 => Key(KEY_F6),
|
||||||
Button::F7 => Key(KeyCode::F7),
|
Button::F7 => Key(KEY_F7),
|
||||||
Button::F8 => Key(KeyCode::F8),
|
Button::F8 => Key(KEY_F8),
|
||||||
Button::F9 => Key(KeyCode::F9),
|
Button::F9 => Key(KEY_F9),
|
||||||
Button::F10 => Key(KeyCode::F10),
|
Button::F10 => Key(KEY_F10),
|
||||||
Button::F11 => Key(KeyCode::F11),
|
Button::F11 => Key(KEY_F11),
|
||||||
Button::F12 => Key(KeyCode::F12),
|
Button::F12 => Key(KEY_F12),
|
||||||
Button::LShift => Key(KeyCode::LeftShift),
|
Button::LShift => Key(KEY_LEFT_SHIFT),
|
||||||
Button::LCtrl => Key(KeyCode::LeftControl),
|
Button::LCtrl => Key(KEY_LEFT_CONTROL),
|
||||||
Button::LAlt => Key(KeyCode::LeftAlt),
|
Button::LAlt => Key(KEY_LEFT_ALT),
|
||||||
Button::LeftSuper => Key(KeyCode::LeftSuper),
|
Button::LeftSuper => Key(KEY_LEFT_SUPER),
|
||||||
Button::RShift => Key(KeyCode::RightShift),
|
Button::RShift => Key(KEY_RIGHT_SHIFT),
|
||||||
Button::RCtrl => Key(KeyCode::RightControl),
|
Button::RCtrl => Key(KEY_RIGHT_CONTROL),
|
||||||
Button::RAlt => Key(KeyCode::RightAlt),
|
Button::RAlt => Key(KEY_RIGHT_ALT),
|
||||||
Button::RightSuper => Key(KeyCode::RightSuper),
|
Button::RightSuper => Key(KEY_RIGHT_SUPER),
|
||||||
Button::Menu => Key(KeyCode::Menu),
|
Button::Menu => Key(KEY_KB_MENU),
|
||||||
Button::Kp0 => Key(KeyCode::Kp0),
|
Button::Kp0 => Key(KEY_KP_0),
|
||||||
Button::Kp1 => Key(KeyCode::Kp1),
|
Button::Kp1 => Key(KEY_KP_1),
|
||||||
Button::Kp2 => Key(KeyCode::Kp2),
|
Button::Kp2 => Key(KEY_KP_2),
|
||||||
Button::Kp3 => Key(KeyCode::Kp3),
|
Button::Kp3 => Key(KEY_KP_3),
|
||||||
Button::Kp4 => Key(KeyCode::Kp4),
|
Button::Kp4 => Key(KEY_KP_4),
|
||||||
Button::Kp5 => Key(KeyCode::Kp5),
|
Button::Kp5 => Key(KEY_KP_5),
|
||||||
Button::Kp6 => Key(KeyCode::Kp6),
|
Button::Kp6 => Key(KEY_KP_6),
|
||||||
Button::Kp7 => Key(KeyCode::Kp7),
|
Button::Kp7 => Key(KEY_KP_7),
|
||||||
Button::Kp8 => Key(KeyCode::Kp8),
|
Button::Kp8 => Key(KEY_KP_8),
|
||||||
Button::Kp9 => Key(KeyCode::Kp9),
|
Button::Kp9 => Key(KEY_KP_9),
|
||||||
Button::KpDecimal => Key(KeyCode::KpDecimal),
|
Button::KpDecimal => Key(KEY_KP_DECIMAL),
|
||||||
Button::KpDivide => Key(KeyCode::KpDivide),
|
Button::KpDivide => Key(KEY_KP_DIVIDE),
|
||||||
Button::KpMultiply => Key(KeyCode::KpMultiply),
|
Button::KpMultiply => Key(KEY_KP_MULTIPLY),
|
||||||
Button::KpSubtract => Key(KeyCode::KpSubtract),
|
Button::KpSubtract => Key(KEY_KP_SUBTRACT),
|
||||||
Button::KpAdd => Key(KeyCode::KpAdd),
|
Button::KpAdd => Key(KEY_KP_ADD),
|
||||||
Button::KpEnter => Key(KeyCode::KpEnter),
|
Button::KpEnter => Key(KEY_KP_ENTER),
|
||||||
Button::KpEqual => Key(KeyCode::KpEqual),
|
Button::KpEqual => Key(KEY_KP_EQUAL),
|
||||||
Button::Back => Key(KeyCode::Back),
|
Button::Back => Key(KEY_BACK),
|
||||||
|
Button::VolumeUp => Key(KEY_VOLUME_UP),
|
||||||
|
Button::VolumeDown => Key(KEY_VOLUME_DOWN),
|
||||||
Button::_EnumSize => unreachable!(),
|
Button::_EnumSize => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -15,7 +15,7 @@ use std::fs;
|
||||||
use arboard::Clipboard;
|
use arboard::Clipboard;
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use input::ActionId;
|
use input::ActionId;
|
||||||
use macroquad::prelude::*;
|
use raylib::{texture::Texture2D, RaylibHandle};
|
||||||
use util::{userdata_dir, MouseInput, Textures};
|
use util::{userdata_dir, MouseInput, Textures};
|
||||||
// use util::MouseInput;
|
// use util::MouseInput;
|
||||||
|
|
||||||
|
@ -29,11 +29,11 @@ pub struct Globals {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Globals {
|
impl Globals {
|
||||||
pub async fn new() -> Self {
|
pub fn new(rl: &mut RaylibHandle, thread: &raylib::prelude::RaylibThread) -> Self {
|
||||||
let mut textures = Textures::default();
|
let mut textures = Textures::default();
|
||||||
textures.load_dir("assets").await;
|
textures.load_dir("assets", rl, thread);
|
||||||
textures.load_dir("assets/tiles").await;
|
textures.load_dir("assets/tiles", rl, thread);
|
||||||
textures.load_dir("assets/digits").await;
|
textures.load_dir("assets/digits", rl, thread);
|
||||||
|
|
||||||
let config_path = userdata_dir().join(CONFIG_FILE_NAME);
|
let config_path = userdata_dir().join(CONFIG_FILE_NAME);
|
||||||
let mut config: Config = fs::read_to_string(config_path)
|
let mut config: Config = fs::read_to_string(config_path)
|
||||||
|
@ -52,9 +52,9 @@ impl Globals {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self, rl: &RaylibHandle) {
|
||||||
self.config.input.update();
|
self.config.input.update(rl);
|
||||||
self.mouse.update();
|
self.mouse.update(rl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_pressed(&self, action: ActionId) -> bool {
|
pub fn is_pressed(&self, action: ActionId) -> bool {
|
||||||
|
|
196
src/main.rs
196
src/main.rs
|
@ -4,7 +4,7 @@ use std::{
|
||||||
io::Write,
|
io::Write,
|
||||||
};
|
};
|
||||||
|
|
||||||
use macroquad::{color::colors, miniquad::window::set_mouse_cursor, prelude::*};
|
use raylib::prelude::*;
|
||||||
|
|
||||||
use marble_machinations::*;
|
use marble_machinations::*;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ const TITLE_TEXT: &str = concat!("Marble Machinations v", env!("CARGO_PKG_VERSIO
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
chapters: Vec<Chapter>,
|
chapters: Vec<Chapter>,
|
||||||
level_scroll: f32,
|
level_scroll: i32,
|
||||||
solutions: HashMap<String, Vec<Solution>>,
|
solutions: HashMap<String, Vec<Solution>>,
|
||||||
open_editor: Option<Editor>,
|
open_editor: Option<Editor>,
|
||||||
selected_level: (usize, usize),
|
selected_level: (usize, usize),
|
||||||
|
@ -32,43 +32,45 @@ struct Game {
|
||||||
edit_settings: Option<Config>,
|
edit_settings: Option<Config>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macroquad::main("what does thsi doa")]
|
fn main() {
|
||||||
async fn main() {
|
let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
||||||
// let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
rl.set_target_fps(60);
|
||||||
// set_target_fps(60);
|
rl.set_window_min_size(640, 480);
|
||||||
// set_window_min_size(640, 480);
|
rl.set_mouse_cursor(MouseCursor::MOUSE_CURSOR_CROSSHAIR);
|
||||||
set_mouse_cursor(miniquad::CursorIcon::Crosshair);
|
rl.set_exit_key(None);
|
||||||
|
rl.set_trace_log(TraceLogLevel::LOG_WARNING);
|
||||||
|
|
||||||
let mut game = Game::new().await;
|
let mut game = Game::new(&mut rl, &thread);
|
||||||
game.run().await
|
game.run(&mut rl, &thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
async fn new() -> Self {
|
fn new(rl: &mut RaylibHandle, thread: &RaylibThread) -> Self {
|
||||||
let solutions = get_solutions();
|
let solutions = get_solutions();
|
||||||
let chapters = get_chapters(&solutions);
|
let chapters = get_chapters(&solutions);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
chapters,
|
chapters,
|
||||||
level_scroll: 0.,
|
level_scroll: 0,
|
||||||
solutions,
|
solutions,
|
||||||
open_editor: None,
|
open_editor: None,
|
||||||
selected_level: (0, 0),
|
selected_level: (0, 0),
|
||||||
selected_solution: 0,
|
selected_solution: 0,
|
||||||
delete_solution: None,
|
delete_solution: None,
|
||||||
editing_solution_name: false,
|
editing_solution_name: false,
|
||||||
level_desc_text: ShapedText::new(20.),
|
level_desc_text: ShapedText::new(20),
|
||||||
globals: Globals::new().await,
|
globals: Globals::new(rl, thread),
|
||||||
edit_settings: None,
|
edit_settings: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(&mut self) {
|
fn run(&mut self, rl: &mut RaylibHandle, thread: &RaylibThread) {
|
||||||
loop {
|
while !rl.window_should_close() {
|
||||||
self.globals.update();
|
let mut d = rl.begin_drawing(thread);
|
||||||
|
self.globals.update(&d);
|
||||||
if let Some(editor) = &mut self.open_editor {
|
if let Some(editor) = &mut self.open_editor {
|
||||||
editor.update(&mut self.globals);
|
editor.update(&d, &mut self.globals);
|
||||||
editor.draw(&mut self.globals);
|
editor.draw(&mut d, &mut self.globals);
|
||||||
match editor.get_exit_state() {
|
match editor.get_exit_state() {
|
||||||
ExitState::Dont => (),
|
ExitState::Dont => (),
|
||||||
ExitState::ExitAndSave => {
|
ExitState::ExitAndSave => {
|
||||||
|
@ -88,8 +90,8 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(config) = &mut self.edit_settings {
|
} else if let Some(config) = &mut self.edit_settings {
|
||||||
clear_background(BG_DARK);
|
d.clear_background(BG_DARK);
|
||||||
match config.draw_edit(&mut self.globals) {
|
match config.draw_edit(&mut d, &mut self.globals) {
|
||||||
config::MenuReturn::Stay => (),
|
config::MenuReturn::Stay => (),
|
||||||
config::MenuReturn::StaySave => {
|
config::MenuReturn::StaySave => {
|
||||||
self.globals.config = config.clone();
|
self.globals.config = config.clone();
|
||||||
|
@ -103,65 +105,65 @@ impl Game {
|
||||||
config::MenuReturn::ReturnCancel => self.edit_settings = None,
|
config::MenuReturn::ReturnCancel => self.edit_settings = None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.draw();
|
self.draw(&mut d);
|
||||||
}
|
}
|
||||||
next_frame().await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self) {
|
fn draw(&mut self, d: &mut RaylibDrawHandle) {
|
||||||
clear_background(BG_DARK);
|
d.clear_background(BG_DARK);
|
||||||
|
|
||||||
let mut tooltip = Tooltip::default();
|
let mut tooltip = Tooltip::default();
|
||||||
tooltip.init_frame();
|
tooltip.init_frame(d);
|
||||||
|
|
||||||
draw_text(
|
d.draw_text(
|
||||||
TITLE_TEXT,
|
TITLE_TEXT,
|
||||||
screen_width() - 275.,
|
d.get_screen_width() - 275,
|
||||||
screen_height() - 20.,
|
d.get_screen_height() - 20,
|
||||||
20.,
|
20,
|
||||||
colors::GRAY,
|
Color::GRAY,
|
||||||
);
|
);
|
||||||
|
|
||||||
let level_list_width = (screen_width() / 3.).min(400.);
|
let level_list_width = (d.get_screen_width() / 3).min(400);
|
||||||
|
let screen_height = d.get_screen_height();
|
||||||
draw_rectangle(0., 0., level_list_width, screen_height(), BG_MEDIUM);
|
d.draw_rectangle(0, 0, level_list_width, screen_height, BG_MEDIUM);
|
||||||
|
|
||||||
if text_button(
|
if text_button(
|
||||||
|
d,
|
||||||
&self.globals.mouse,
|
&self.globals.mouse,
|
||||||
screen_width() - 100.,
|
d.get_screen_width() - 100,
|
||||||
screen_height() - 70.,
|
d.get_screen_height() - 70,
|
||||||
90.,
|
90,
|
||||||
"settings",
|
"settings",
|
||||||
) {
|
) {
|
||||||
self.edit_settings = Some(self.globals.config.clone());
|
self.edit_settings = Some(self.globals.config.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
const ENTRY_SPACING: f32 = 65.;
|
const ENTRY_SPACING: i32 = 65;
|
||||||
let fit_on_screen = (screen_height() / ENTRY_SPACING) as usize;
|
let fit_on_screen = (d.get_screen_height() / ENTRY_SPACING) as usize;
|
||||||
let max_scroll = self
|
let max_scroll = self
|
||||||
.chapters
|
.chapters
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| 1 + if c.visible { c.levels.len() } else { 0 })
|
.map(|c| 1 + if c.visible { c.levels.len() } else { 0 })
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
.saturating_sub(fit_on_screen) as f32
|
.saturating_sub(fit_on_screen) as i32
|
||||||
* ENTRY_SPACING;
|
* ENTRY_SPACING;
|
||||||
if self.globals.mouse.pos().x < level_list_width {
|
if self.globals.mouse.pos().x < level_list_width as f32 {
|
||||||
if self.globals.mouse.scroll() == Some(Scroll::Down) && self.level_scroll < max_scroll {
|
if self.globals.mouse.scroll() == Some(Scroll::Down) && self.level_scroll < max_scroll {
|
||||||
self.level_scroll += ENTRY_SPACING;
|
self.level_scroll += ENTRY_SPACING;
|
||||||
}
|
}
|
||||||
if self.globals.mouse.scroll() == Some(Scroll::Up) && self.level_scroll > 0. {
|
if self.globals.mouse.scroll() == Some(Scroll::Up) && self.level_scroll > 0 {
|
||||||
self.level_scroll -= ENTRY_SPACING;
|
self.level_scroll -= ENTRY_SPACING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut y = 10. - self.level_scroll;
|
let mut y = 10 - self.level_scroll;
|
||||||
for (chapter_i, chapter) in self.chapters.iter_mut().enumerate() {
|
for (chapter_i, chapter) in self.chapters.iter_mut().enumerate() {
|
||||||
let bounds = Rect::new(5., y - 5., level_list_width - 10., ENTRY_SPACING - 5.);
|
let bounds = rect(5, y - 5, level_list_width - 10, ENTRY_SPACING - 5);
|
||||||
draw_rectangle_rec(bounds, BG_DARK);
|
d.draw_rectangle_rec(bounds, BG_DARK);
|
||||||
draw_text(&chapter.title, 10., y, 30., FG_CHAPTER_TITLE);
|
d.draw_text(&chapter.title, 10, y, 30, FG_CHAPTER_TITLE);
|
||||||
let subtitle = format!("{} levels", chapter.levels.len());
|
let subtitle = format!("{} levels", chapter.levels.len());
|
||||||
draw_text(&subtitle, 10., y + 30., 20., colors::WHITE);
|
d.draw_text(&subtitle, 10, y + 30, 20, Color::WHITE);
|
||||||
y += ENTRY_SPACING;
|
y += ENTRY_SPACING;
|
||||||
let clicked_this =
|
let clicked_this =
|
||||||
self.globals.mouse.left_click() && self.globals.mouse.is_over(bounds);
|
self.globals.mouse.left_click() && self.globals.mouse.is_over(bounds);
|
||||||
|
@ -175,7 +177,7 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (level_index, level) in chapter.levels.iter().enumerate() {
|
for (level_index, level) in chapter.levels.iter().enumerate() {
|
||||||
let bounds = Rect::new(5., y - 5., level_list_width - 10., ENTRY_SPACING - 5.);
|
let bounds = rect(5, y - 5, level_list_width - 10, ENTRY_SPACING - 5);
|
||||||
let clicked_this =
|
let clicked_this =
|
||||||
self.globals.mouse.left_click() && self.globals.mouse.is_over(bounds);
|
self.globals.mouse.left_click() && self.globals.mouse.is_over(bounds);
|
||||||
|
|
||||||
|
@ -189,18 +191,18 @@ impl Game {
|
||||||
self.selected_solution = solutions.len().saturating_sub(1);
|
self.selected_solution = solutions.len().saturating_sub(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_rectangle_rec(
|
d.draw_rectangle_rec(
|
||||||
bounds,
|
bounds,
|
||||||
widget_bg(self.selected_level == (chapter_i, level_index)),
|
widget_bg(self.selected_level == (chapter_i, level_index)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut title_color = colors::WHITE;
|
let mut title_color = Color::WHITE;
|
||||||
if let Some(solutions) = self.solutions.get(level.id()) {
|
if let Some(solutions) = self.solutions.get(level.id()) {
|
||||||
if solutions.iter().any(|s| s.score.is_some()) {
|
if solutions.iter().any(|s| s.score.is_some()) {
|
||||||
title_color = colors::GREEN;
|
title_color = Color::LIGHTGREEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
draw_text(level.name(), 10., y, 30., title_color);
|
d.draw_text(level.name(), 10, y, 30, title_color);
|
||||||
let solution_count = self
|
let solution_count = self
|
||||||
.solutions
|
.solutions
|
||||||
.get(level.id())
|
.get(level.id())
|
||||||
|
@ -208,11 +210,11 @@ impl Game {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let subtext = format!("solutions: {solution_count}");
|
let subtext = format!("solutions: {solution_count}");
|
||||||
let subtext_color = if solution_count > 0 {
|
let subtext_color = if solution_count > 0 {
|
||||||
colors::GOLD
|
Color::GOLD
|
||||||
} else {
|
} else {
|
||||||
colors::LIGHTGRAY
|
Color::LIGHTGRAY
|
||||||
};
|
};
|
||||||
draw_text(&subtext, 10., y + 30., 20., subtext_color);
|
d.draw_text(&subtext, 10, y + 30, 20, subtext_color);
|
||||||
y += ENTRY_SPACING;
|
y += ENTRY_SPACING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,31 +224,25 @@ impl Game {
|
||||||
.get(self.selected_level.0)
|
.get(self.selected_level.0)
|
||||||
.and_then(|c| c.levels.get(self.selected_level.1))
|
.and_then(|c| c.levels.get(self.selected_level.1))
|
||||||
{
|
{
|
||||||
draw_text(
|
d.draw_text(level.name(), level_list_width + 10, 10, 40, Color::CYAN);
|
||||||
level.name(),
|
d.draw_text(level.id(), level_list_width + 10, 50, 10, Color::GRAY);
|
||||||
level_list_width + 10.,
|
|
||||||
10.,
|
|
||||||
40.,
|
|
||||||
colors::SKYBLUE,
|
|
||||||
);
|
|
||||||
draw_text(level.id(), level_list_width + 10., 50., 10., colors::GRAY);
|
|
||||||
|
|
||||||
let mut y = 70.;
|
let mut y = 70;
|
||||||
self.level_desc_text.set_text(level.description());
|
self.level_desc_text.set_text(level.description());
|
||||||
self.level_desc_text
|
self.level_desc_text
|
||||||
.update_width(screen_width() - level_list_width - 30.);
|
.update_width(d, d.get_render_width() - level_list_width - 30);
|
||||||
self.level_desc_text.draw(level_list_width + 10., y);
|
self.level_desc_text.draw(d, level_list_width + 10, y);
|
||||||
y += self.level_desc_text.height() + 10.;
|
y += self.level_desc_text.height() + 10;
|
||||||
|
|
||||||
if let Some(solutions) = self.solutions.get_mut(level.id()) {
|
if let Some(solutions) = self.solutions.get_mut(level.id()) {
|
||||||
let solution_entry_height = 40.;
|
let solution_entry_height = 40;
|
||||||
let entry_width = 200.;
|
let entry_width = 200;
|
||||||
let mut solution_y = y;
|
let mut solution_y = y;
|
||||||
for (solution_index, solution) in solutions.iter().enumerate() {
|
for (solution_index, solution) in solutions.iter().enumerate() {
|
||||||
if simple_option_button(
|
if simple_option_button(
|
||||||
&self.globals.mouse,
|
(d, &self.globals.mouse),
|
||||||
Rect::new(
|
rect(
|
||||||
level_list_width + 10.,
|
level_list_width + 10,
|
||||||
solution_y,
|
solution_y,
|
||||||
entry_width,
|
entry_width,
|
||||||
solution_entry_height,
|
solution_entry_height,
|
||||||
|
@ -257,39 +253,40 @@ impl Game {
|
||||||
self.editing_solution_name = false;
|
self.editing_solution_name = false;
|
||||||
}
|
}
|
||||||
let name_color = if solution.score.is_some() {
|
let name_color = if solution.score.is_some() {
|
||||||
colors::LIME
|
Color::LIME
|
||||||
} else {
|
} else {
|
||||||
colors::ORANGE
|
Color::ORANGE
|
||||||
};
|
};
|
||||||
draw_text(
|
d.draw_text(
|
||||||
&solution.name,
|
&solution.name,
|
||||||
level_list_width + 15.,
|
level_list_width + 15,
|
||||||
solution_y + 5.,
|
solution_y + 5,
|
||||||
20.,
|
20,
|
||||||
name_color,
|
name_color,
|
||||||
);
|
);
|
||||||
draw_text(
|
d.draw_text(
|
||||||
&solution.score_text(),
|
&solution.score_text(),
|
||||||
level_list_width + 15.,
|
level_list_width + 15,
|
||||||
solution_y + 25.,
|
solution_y + 25,
|
||||||
10.,
|
10,
|
||||||
colors::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
if tex32_button(
|
if tex32_button(
|
||||||
&self.globals.mouse,
|
(d, &self.globals.mouse),
|
||||||
(level_list_width + entry_width + 15., solution_y + 4.),
|
(level_list_width + entry_width + 15, solution_y + 4),
|
||||||
self.globals.get_tex("cancel"),
|
self.globals.get_tex("cancel"),
|
||||||
(&mut tooltip, "delete"),
|
(&mut tooltip, "delete"),
|
||||||
) {
|
) {
|
||||||
self.delete_solution = Some(solution_index);
|
self.delete_solution = Some(solution_index);
|
||||||
}
|
}
|
||||||
solution_y += solution_entry_height + 10.;
|
solution_y += solution_entry_height + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_id = get_free_id(solutions, Solution::id);
|
let next_id = get_free_id(solutions, Solution::id);
|
||||||
if text_button(
|
if text_button(
|
||||||
|
d,
|
||||||
&self.globals.mouse,
|
&self.globals.mouse,
|
||||||
level_list_width + 10.,
|
level_list_width + 10,
|
||||||
solution_y,
|
solution_y,
|
||||||
entry_width,
|
entry_width,
|
||||||
"new solution",
|
"new solution",
|
||||||
|
@ -300,23 +297,24 @@ impl Game {
|
||||||
|
|
||||||
if let Some(i) = self.delete_solution {
|
if let Some(i) = self.delete_solution {
|
||||||
let text = format!("really delete solution '{}'?", &solutions[i].name);
|
let text = format!("really delete solution '{}'?", &solutions[i].name);
|
||||||
let y = (solution_y + 40.).max(240.);
|
let y = (solution_y + 40).max(240);
|
||||||
let x = level_list_width + 10.;
|
let x = level_list_width + 10;
|
||||||
draw_text(&text, x, y, 20., colors::ORANGE);
|
d.draw_text(&text, x, y, 20, Color::ORANGE);
|
||||||
if text_button(&self.globals.mouse, x, y + 30., 100., "yes") {
|
if text_button(d, &self.globals.mouse, x, y + 30, 100, "yes") {
|
||||||
solutions[i].remove_file();
|
solutions[i].remove_file();
|
||||||
solutions.remove(i);
|
solutions.remove(i);
|
||||||
self.delete_solution = None;
|
self.delete_solution = None;
|
||||||
}
|
}
|
||||||
if text_button(&self.globals.mouse, x + 110., y + 30., 100., "no") {
|
if text_button(d, &self.globals.mouse, x + 110, y + 30, 100, "no") {
|
||||||
self.delete_solution = None;
|
self.delete_solution = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(solution) = solutions.get_mut(self.selected_solution) {
|
if let Some(solution) = solutions.get_mut(self.selected_solution) {
|
||||||
let column_x = level_list_width + entry_width + 56.;
|
let column_x = level_list_width + entry_width + 56;
|
||||||
let bounds = Rect::new(column_x, y, 220., 30.);
|
let bounds = Rectangle::new(column_x as f32, y as f32, 220., 30.);
|
||||||
if text_input(
|
if text_input(
|
||||||
|
d,
|
||||||
&mut self.globals,
|
&mut self.globals,
|
||||||
bounds,
|
bounds,
|
||||||
&mut solution.name,
|
&mut solution.name,
|
||||||
|
@ -327,18 +325,18 @@ impl Game {
|
||||||
solution.save();
|
solution.save();
|
||||||
}
|
}
|
||||||
let id_text = format!("{}", solution.id());
|
let id_text = format!("{}", solution.id());
|
||||||
draw_text(&id_text, column_x, y + 35., 10., colors::GRAY);
|
d.draw_text(&id_text, column_x, y + 35, 10, Color::GRAY);
|
||||||
|
|
||||||
if text_button(&self.globals.mouse, column_x, y + 50., 220., "clone") {
|
if text_button(d, &self.globals.mouse, column_x, y + 50, 220, "clone") {
|
||||||
let cloned = solution.new_copy(next_id);
|
let cloned = solution.new_copy(next_id);
|
||||||
self.selected_solution = solutions.len();
|
self.selected_solution = solutions.len();
|
||||||
solutions.push(cloned);
|
solutions.push(cloned);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if text_button(&self.globals.mouse, column_x, y + 85., 220., "edit") {
|
if text_button(d, &self.globals.mouse, column_x, y + 85, 220, "edit") {
|
||||||
let mut editor = Editor::new(solution.clone(), level.clone());
|
let mut editor = Editor::new(solution.clone(), level.clone());
|
||||||
editor.center_view();
|
editor.center_view(d);
|
||||||
self.open_editor = Some(editor);
|
self.open_editor = Some(editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -346,7 +344,7 @@ impl Game {
|
||||||
self.solutions.insert(level.id().to_owned(), Vec::new());
|
self.solutions.insert(level.id().to_owned(), Vec::new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tooltip.draw();
|
tooltip.draw(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_config(&self) {
|
fn save_config(&self) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use macroquad::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod pos;
|
pub mod pos;
|
||||||
|
@ -99,23 +99,26 @@ impl Machine {
|
||||||
self.input = bytes;
|
self.input = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_marble_values(&self, textures: &Textures, offset: Vec2, scale: f32) {
|
pub fn draw_marble_values(
|
||||||
let tile_size = TILE_TEXTURE_SIZE * scale;
|
&self,
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
|
textures: &Textures,
|
||||||
|
offset: Vector2,
|
||||||
|
scale: f32,
|
||||||
|
) {
|
||||||
|
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
||||||
for marble in &self.marbles {
|
for marble in &self.marbles {
|
||||||
let x = marble.x;
|
let x = marble.x;
|
||||||
let y = marble.y;
|
let y = marble.y;
|
||||||
if let Some(tile) = self.grid.get(*marble) {
|
if let Some(tile) = self.grid.get(*marble) {
|
||||||
let px = x as f32 * tile_size + offset.x;
|
let px = x as i32 * tile_size + offset.x as i32;
|
||||||
let py = y as f32 * tile_size + offset.y;
|
let py = y as i32 * tile_size + offset.y as i32;
|
||||||
if let Tile::Marble { value, dir } = tile {
|
if let Tile::Marble { value, dir } = tile {
|
||||||
let tex = textures.get(dir.arrow_texture_name());
|
let texture = textures.get(dir.arrow_texture_name());
|
||||||
let faded_white = Color::from_rgba(255, 255, 255, 100);
|
let pos = Vector2::new(px as f32, py as f32);
|
||||||
let params = DrawTextureParams {
|
let faded_white = Color::new(255, 255, 255, 100);
|
||||||
dest_size: Some(Vec2::new(tex.width() * scale, tex.height() * scale)),
|
d.draw_texture_ex(texture, pos, 0., scale, faded_white);
|
||||||
..Default::default()
|
draw_usize_small(d, textures, value as usize, px, py, scale);
|
||||||
};
|
|
||||||
draw_texture_ex(tex, px, py, faded_white, params);
|
|
||||||
draw_usize_small(textures, value as usize, px, py, scale);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,10 +544,10 @@ impl Machine {
|
||||||
let val_b = self.grid.get_or_blank(pos_b).read_value();
|
let val_b = self.grid.get_or_blank(pos_b).read_value();
|
||||||
|
|
||||||
let result = match comp {
|
let result = match comp {
|
||||||
Comp::LessThan => val_a < val_b,
|
Comparison::LessThan => val_a < val_b,
|
||||||
Comp::GreaterThan => val_a > val_b,
|
Comparison::GreaterThan => val_a > val_b,
|
||||||
Comp::Equal => val_a == val_b,
|
Comparison::Equal => val_a == val_b,
|
||||||
Comp::NotEqual => val_a != val_b,
|
Comparison::NotEqual => val_a != val_b,
|
||||||
};
|
};
|
||||||
if result {
|
if result {
|
||||||
match self.grid.get_mut(front_pos) {
|
match self.grid.get_mut(front_pos) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use macroquad::prelude::*;
|
use raylib::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{tile::*, Pos, PosInt};
|
use super::{tile::*, Pos, PosInt};
|
||||||
|
@ -285,43 +285,44 @@ impl Grid {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, textures: &Textures, offset: Vec2, scale: f32, power_directions: bool) {
|
pub fn draw(
|
||||||
|
&self,
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
|
textures: &Textures,
|
||||||
|
offset: Vector2,
|
||||||
|
scale: f32,
|
||||||
|
power_directions: bool,
|
||||||
|
) {
|
||||||
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
||||||
|
|
||||||
let start_x = (-offset.x as i32) / tile_size - 1;
|
let start_x = (-offset.x as i32) / tile_size - 1;
|
||||||
let tiles_width = screen_width() as i32 / tile_size + 3;
|
let tiles_width = d.get_screen_width() / tile_size + 3;
|
||||||
let start_y = (-offset.y as i32) / tile_size - 1;
|
let start_y = (-offset.y as i32) / tile_size - 1;
|
||||||
let tiles_height = screen_height() as i32 / tile_size + 3;
|
let tiles_height = d.get_screen_height() / tile_size + 3;
|
||||||
|
|
||||||
for x in start_x..(start_x + tiles_width) {
|
for x in start_x..(start_x + tiles_width) {
|
||||||
for y in start_y..(start_y + tiles_height) {
|
for y in start_y..(start_y + tiles_height) {
|
||||||
let px = (x * tile_size) as f32 + offset.x;
|
let px = x * tile_size + offset.x as i32;
|
||||||
let py = (y * tile_size) as f32 + offset.y;
|
let py = y * tile_size + offset.y as i32;
|
||||||
if let Some(tile) = self.get((x, y).into()) {
|
if let Some(tile) = self.get((x, y).into()) {
|
||||||
let texname = tile.texture();
|
let texname = tile.texture();
|
||||||
if texname.is_empty() {
|
if texname.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let texture = textures.get(texname);
|
let texture = textures.get(texname);
|
||||||
draw_scaled_texture(texture, px, py, scale);
|
draw_scaled_texture(d, texture, px, py, scale);
|
||||||
if power_directions {
|
if power_directions {
|
||||||
if let Tile::Powerable(_, state) = &tile {
|
if let Tile::Powerable(_, state) = &tile {
|
||||||
for dir in Direction::ALL {
|
for dir in Direction::ALL {
|
||||||
if state.get_dir(dir) {
|
if state.get_dir(dir) {
|
||||||
let texture = textures.get(dir.debug_arrow_texture_name());
|
let texture = textures.get(dir.debug_arrow_texture_name());
|
||||||
draw_scaled_texture(texture, px, py, scale);
|
draw_scaled_texture(d, texture, px, py, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
draw_rectangle(
|
d.draw_rectangle(px, py, tile_size, tile_size, Color::new(0, 0, 0, 80));
|
||||||
px,
|
|
||||||
py,
|
|
||||||
tile_size as _,
|
|
||||||
tile_size as _,
|
|
||||||
Color::from_rgba(0, 0, 0, 80),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
|
|
||||||
use macroquad::prelude::*;
|
use raylib::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type PosInt = i16;
|
pub type PosInt = i16;
|
||||||
|
@ -12,8 +12,8 @@ pub struct Pos {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pos {
|
impl Pos {
|
||||||
pub const fn to_vec(self) -> Vec2 {
|
pub const fn to_vec(self) -> Vector2 {
|
||||||
Vec2 {
|
Vector2 {
|
||||||
x: self.x as f32,
|
x: self.x as f32,
|
||||||
y: self.y as f32,
|
y: self.y as f32,
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,8 @@ impl From<(i32, i32)> for Pos {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec2> for Pos {
|
impl From<Vector2> for Pos {
|
||||||
fn from(vec: Vec2) -> Self {
|
fn from(vec: Vector2) -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: vec.x as PosInt,
|
x: vec.x as PosInt,
|
||||||
y: vec.y as PosInt,
|
y: vec.y as PosInt,
|
||||||
|
|
|
@ -31,7 +31,7 @@ pub enum OpenTile {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum PTile {
|
pub enum PTile {
|
||||||
Comparator(Comp),
|
Comparator(Comparison),
|
||||||
Math(MathOp),
|
Math(MathOp),
|
||||||
Silo,
|
Silo,
|
||||||
Flipper,
|
Flipper,
|
||||||
|
@ -59,7 +59,7 @@ pub enum MathOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum Comp {
|
pub enum Comparison {
|
||||||
LessThan,
|
LessThan,
|
||||||
GreaterThan,
|
GreaterThan,
|
||||||
Equal,
|
Equal,
|
||||||
|
@ -99,10 +99,10 @@ impl Tile {
|
||||||
'v' => Tile::Arrow(Direction::Down),
|
'v' => Tile::Arrow(Direction::Down),
|
||||||
'<' => Tile::Arrow(Direction::Left),
|
'<' => Tile::Arrow(Direction::Left),
|
||||||
'>' => Tile::Arrow(Direction::Right),
|
'>' => Tile::Arrow(Direction::Right),
|
||||||
'=' => Tile::Powerable(PTile::Comparator(Comp::Equal), Power::OFF),
|
'=' => Tile::Powerable(PTile::Comparator(Comparison::Equal), Power::OFF),
|
||||||
'!' => Tile::Powerable(PTile::Comparator(Comp::NotEqual), Power::OFF),
|
'!' => Tile::Powerable(PTile::Comparator(Comparison::NotEqual), Power::OFF),
|
||||||
'L' => Tile::Powerable(PTile::Comparator(Comp::LessThan), Power::OFF),
|
'L' => Tile::Powerable(PTile::Comparator(Comparison::LessThan), Power::OFF),
|
||||||
'G' => Tile::Powerable(PTile::Comparator(Comp::GreaterThan), Power::OFF),
|
'G' => Tile::Powerable(PTile::Comparator(Comparison::GreaterThan), Power::OFF),
|
||||||
'I' | 'P' => Tile::Powerable(PTile::IO, Power::OFF),
|
'I' | 'P' => Tile::Powerable(PTile::IO, Power::OFF),
|
||||||
'F' => Tile::Powerable(PTile::Flipper, Power::OFF),
|
'F' => Tile::Powerable(PTile::Flipper, Power::OFF),
|
||||||
'A' => Tile::Powerable(PTile::Math(MathOp::Add), Power::OFF),
|
'A' => Tile::Powerable(PTile::Math(MathOp::Add), Power::OFF),
|
||||||
|
@ -141,10 +141,10 @@ impl Tile {
|
||||||
},
|
},
|
||||||
Tile::Powerable(tile, _) => match tile {
|
Tile::Powerable(tile, _) => match tile {
|
||||||
PTile::Comparator(comp) => match comp {
|
PTile::Comparator(comp) => match comp {
|
||||||
Comp::LessThan => 'L',
|
Comparison::LessThan => 'L',
|
||||||
Comp::GreaterThan => 'G',
|
Comparison::GreaterThan => 'G',
|
||||||
Comp::Equal => '=',
|
Comparison::Equal => '=',
|
||||||
Comp::NotEqual => '!',
|
Comparison::NotEqual => '!',
|
||||||
},
|
},
|
||||||
PTile::Math(math) => match math {
|
PTile::Math(math) => match math {
|
||||||
MathOp::Add => 'A',
|
MathOp::Add => 'A',
|
||||||
|
@ -453,49 +453,49 @@ impl MathOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Comp {
|
impl Comparison {
|
||||||
pub const fn human_name(self) -> &'static str {
|
pub const fn human_name(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Comp::LessThan => "Comparator: Less than",
|
Comparison::LessThan => "Comparator: Less than",
|
||||||
Comp::GreaterThan => "Comparator: Greater than",
|
Comparison::GreaterThan => "Comparator: Greater than",
|
||||||
Comp::Equal => "Comparator: Equal",
|
Comparison::Equal => "Comparator: Equal",
|
||||||
Comp::NotEqual => "Comparator: Not Equal",
|
Comparison::NotEqual => "Comparator: Not Equal",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn texture_name_on(self) -> &'static str {
|
pub const fn texture_name_on(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Comp::LessThan => "lt_on",
|
Comparison::LessThan => "lt_on",
|
||||||
Comp::GreaterThan => "gt_on",
|
Comparison::GreaterThan => "gt_on",
|
||||||
Comp::Equal => "eq_on",
|
Comparison::Equal => "eq_on",
|
||||||
Comp::NotEqual => "neq_on",
|
Comparison::NotEqual => "neq_on",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn texture_name_off(self) -> &'static str {
|
pub const fn texture_name_off(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Comp::LessThan => "lt_off",
|
Comparison::LessThan => "lt_off",
|
||||||
Comp::GreaterThan => "gt_off",
|
Comparison::GreaterThan => "gt_off",
|
||||||
Comp::Equal => "eq_off",
|
Comparison::Equal => "eq_off",
|
||||||
Comp::NotEqual => "neq_off",
|
Comparison::NotEqual => "neq_off",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) {
|
pub fn next(&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Comp::LessThan => Comp::GreaterThan,
|
Comparison::LessThan => Comparison::GreaterThan,
|
||||||
Comp::GreaterThan => Comp::Equal,
|
Comparison::GreaterThan => Comparison::Equal,
|
||||||
Comp::Equal => Comp::NotEqual,
|
Comparison::Equal => Comparison::NotEqual,
|
||||||
Comp::NotEqual => Comp::LessThan,
|
Comparison::NotEqual => Comparison::LessThan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&mut self) {
|
pub fn prev(&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Comp::LessThan => Comp::NotEqual,
|
Comparison::LessThan => Comparison::NotEqual,
|
||||||
Comp::GreaterThan => Comp::LessThan,
|
Comparison::GreaterThan => Comparison::LessThan,
|
||||||
Comp::Equal => Comp::GreaterThan,
|
Comparison::Equal => Comparison::GreaterThan,
|
||||||
Comp::NotEqual => Comp::Equal,
|
Comparison::NotEqual => Comparison::Equal,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use macroquad::prelude::*;
|
use raylib::prelude::*;
|
||||||
|
|
||||||
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
|
@ -12,8 +12,6 @@ pub const BG_WIDGET: Color = gray(64);
|
||||||
pub const BG_WIDGET_ACTIVE: Color = rgb(80, 120, 180);
|
pub const BG_WIDGET_ACTIVE: Color = rgb(80, 120, 180);
|
||||||
pub const FG_MARBLE_VALUE: Color = rgb(255, 80, 40);
|
pub const FG_MARBLE_VALUE: Color = rgb(255, 80, 40);
|
||||||
pub const FG_CHAPTER_TITLE: Color = rgb(255, 160, 40);
|
pub const FG_CHAPTER_TITLE: Color = rgb(255, 160, 40);
|
||||||
pub const SLIDER_FILL: Color = rgb(255, 160, 40);
|
|
||||||
pub const LIGHTBLUE: Color = rgb(80, 190, 230);
|
|
||||||
|
|
||||||
pub const fn widget_bg(highlight: bool) -> Color {
|
pub const fn widget_bg(highlight: bool) -> Color {
|
||||||
if highlight {
|
if highlight {
|
||||||
|
@ -24,9 +22,9 @@ pub const fn widget_bg(highlight: bool) -> Color {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn rgb(r: u8, g: u8, b: u8) -> Color {
|
pub const fn rgb(r: u8, g: u8, b: u8) -> Color {
|
||||||
Color::from_rgba(r, g, b, 255)
|
Color::new(r, g, b, 255)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn gray(value: u8) -> Color {
|
pub const fn gray(value: u8) -> Color {
|
||||||
Color::from_rgba(value, value, value, 255)
|
Color::new(value, value, value, 255)
|
||||||
}
|
}
|
||||||
|
|
298
src/ui.rs
298
src/ui.rs
|
@ -2,25 +2,25 @@ use std::ops::Range;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
theme::*,
|
theme::*,
|
||||||
util::{draw_rectangle_rec, draw_scaled_texture, MouseInput, Scroll, Textures},
|
util::{draw_scaled_texture, rect, MouseInput, Scroll, Textures},
|
||||||
Globals,
|
Globals,
|
||||||
};
|
};
|
||||||
use macroquad::{color::colors, prelude::*};
|
use raylib::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ShapedText {
|
pub struct ShapedText {
|
||||||
text: String,
|
text: String,
|
||||||
max_width: f32,
|
max_width: i32,
|
||||||
font_size: f32,
|
font_size: i32,
|
||||||
lines: Vec<Range<usize>>,
|
lines: Vec<Range<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShapedText {
|
impl ShapedText {
|
||||||
pub fn new(font_size: f32) -> Self {
|
pub fn new(font_size: i32) -> Self {
|
||||||
Self {
|
Self {
|
||||||
text: String::new(),
|
text: String::new(),
|
||||||
font_size,
|
font_size,
|
||||||
max_width: 500.,
|
max_width: 500,
|
||||||
lines: Vec::new(),
|
lines: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,11 @@ impl ShapedText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn height(&self) -> f32 {
|
pub fn height(&self) -> i32 {
|
||||||
self.font_size * self.lines.len() as f32
|
self.font_size * self.lines.len() as i32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_width(&mut self, width: f32) {
|
pub fn update_width(&mut self, d: &RaylibHandle, width: i32) {
|
||||||
if self.max_width == width && !self.lines.is_empty() {
|
if self.max_width == width && !self.lines.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ impl ShapedText {
|
||||||
for (i, c) in self.text.char_indices() {
|
for (i, c) in self.text.char_indices() {
|
||||||
if c == ' ' {
|
if c == ' ' {
|
||||||
let line = &self.text[line_start..i];
|
let line = &self.text[line_start..i];
|
||||||
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
let new_line_length = d.measure_text(line, self.font_size);
|
||||||
if new_line_length <= self.max_width {
|
if new_line_length <= self.max_width {
|
||||||
line_end = i;
|
line_end = i;
|
||||||
} else {
|
} else {
|
||||||
|
@ -58,7 +58,7 @@ impl ShapedText {
|
||||||
}
|
}
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
let line = &self.text[line_start..i];
|
let line = &self.text[line_start..i];
|
||||||
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
let new_line_length = d.measure_text(line, self.font_size);
|
||||||
if new_line_length <= self.max_width {
|
if new_line_length <= self.max_width {
|
||||||
self.lines.push(line_start..i);
|
self.lines.push(line_start..i);
|
||||||
line_end = i + 1;
|
line_end = i + 1;
|
||||||
|
@ -73,7 +73,7 @@ impl ShapedText {
|
||||||
}
|
}
|
||||||
let i = self.text.len();
|
let i = self.text.len();
|
||||||
let line = &self.text[line_start..i];
|
let line = &self.text[line_start..i];
|
||||||
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
let new_line_length = d.measure_text(line, self.font_size);
|
||||||
if new_line_length <= self.max_width {
|
if new_line_length <= self.max_width {
|
||||||
self.lines.push(line_start..i);
|
self.lines.push(line_start..i);
|
||||||
} else {
|
} else {
|
||||||
|
@ -82,12 +82,12 @@ impl ShapedText {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, x: f32, y: f32) {
|
pub fn draw(&self, d: &mut RaylibDrawHandle, x: i32, y: i32) {
|
||||||
// draw_rectangle(x, y, self.max_width, 4, Color::RED);
|
// d.draw_rectangle(x, y, self.max_width, 4, Color::RED);
|
||||||
for (i, line) in self.lines.iter().enumerate() {
|
for (i, line) in self.lines.iter().enumerate() {
|
||||||
let line = &self.text[line.clone()];
|
let line = &self.text[line.clone()];
|
||||||
let line_y = y + self.font_size * i as f32;
|
let line_y = y + self.font_size * i as i32;
|
||||||
draw_text(line, x, line_y, self.font_size, colors::WHITE);
|
d.draw_text(line, x, line_y, self.font_size, Color::WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,25 +95,25 @@ impl ShapedText {
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Tooltip {
|
pub struct Tooltip {
|
||||||
text: Option<&'static str>,
|
text: Option<&'static str>,
|
||||||
mouse_x: f32,
|
mouse_x: i32,
|
||||||
mouse_y: f32,
|
mouse_y: i32,
|
||||||
screen_width: f32,
|
screen_width: i32,
|
||||||
screen_height: f32,
|
screen_height: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tooltip {
|
impl Tooltip {
|
||||||
pub fn init_frame(&mut self) {
|
pub fn init_frame(&mut self, d: &RaylibHandle) {
|
||||||
let (mouse_x, mouse_y) = mouse_position();
|
let p = d.get_mouse_position();
|
||||||
*self = Self {
|
*self = Self {
|
||||||
text: None,
|
text: None,
|
||||||
mouse_x,
|
mouse_x: p.x as i32,
|
||||||
mouse_y,
|
mouse_y: p.y as i32,
|
||||||
screen_width: screen_width(),
|
screen_width: d.get_screen_width(),
|
||||||
screen_height: screen_height(),
|
screen_height: d.get_screen_height(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, x: f32, y: f32, width: f32, height: f32, text: &'static str) {
|
pub fn add(&mut self, x: i32, y: i32, width: i32, height: i32, text: &'static str) {
|
||||||
if self.mouse_x >= x
|
if self.mouse_x >= x
|
||||||
&& self.mouse_y >= y
|
&& self.mouse_y >= y
|
||||||
&& self.mouse_x <= (x + width)
|
&& self.mouse_x <= (x + width)
|
||||||
|
@ -127,91 +127,122 @@ impl Tooltip {
|
||||||
self.text = None;
|
self.text = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_rec(&mut self, bounds: Rect, text: &'static str) {
|
pub fn add_rec(&mut self, bounds: Rectangle, text: &'static str) {
|
||||||
self.add(bounds.x, bounds.y, bounds.w, bounds.h, text);
|
self.add(
|
||||||
|
bounds.x as i32,
|
||||||
|
bounds.y as i32,
|
||||||
|
bounds.width as i32,
|
||||||
|
bounds.height as i32,
|
||||||
|
text,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self) {
|
pub fn draw(&self, d: &mut RaylibDrawHandle) {
|
||||||
if let Some(text) = self.text {
|
if let Some(text) = self.text {
|
||||||
let font_size = 20.0;
|
let font_size = 20;
|
||||||
let margin = 4.0;
|
let margin = 4;
|
||||||
let text_width = measure_text(text, None, font_size as _, 1.).width;
|
let text_width = d.measure_text(text, font_size);
|
||||||
let x = self
|
let x = self
|
||||||
.mouse_x
|
.mouse_x
|
||||||
.min(self.screen_width - text_width - margin * 2.);
|
.min(self.screen_width - text_width - margin * 2);
|
||||||
let y = self
|
let y = self
|
||||||
.mouse_y
|
.mouse_y
|
||||||
.min(self.screen_height - font_size - margin * 2.);
|
.min(self.screen_height - font_size - margin * 2);
|
||||||
draw_rectangle(
|
d.draw_rectangle(
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
text_width + margin * 2.,
|
text_width + margin * 2,
|
||||||
font_size + margin * 2.,
|
font_size + margin * 2,
|
||||||
BG_LIGHT,
|
BG_LIGHT,
|
||||||
);
|
);
|
||||||
draw_text(text, x + margin, y + margin, font_size, colors::WHITE);
|
d.draw_text(text, x + margin, y + margin, font_size, Color::WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_button(mouse: &MouseInput, x: f32, y: f32, width: f32, height: f32, val: &mut bool) {
|
pub fn toggle_button(
|
||||||
let margin = 5.;
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
val: &mut bool,
|
||||||
|
) {
|
||||||
|
let margin = 5;
|
||||||
let mouse_pos = mouse.pos();
|
let mouse_pos = mouse.pos();
|
||||||
let bounds = Rect::new(x, y, width, height);
|
let bounds = rect(x, y, width, height);
|
||||||
|
|
||||||
let hover = bounds.contains(mouse_pos);
|
let hover = bounds.check_collision_point_rec(mouse_pos);
|
||||||
draw_rectangle(x, y, width, height, widget_bg(hover));
|
d.draw_rectangle(x, y, width, height, widget_bg(hover));
|
||||||
let pressed = hover && mouse.left_click();
|
let pressed = hover && mouse.left_click();
|
||||||
if pressed {
|
if pressed {
|
||||||
*val = !*val;
|
*val = !*val;
|
||||||
}
|
}
|
||||||
if *val {
|
if *val {
|
||||||
draw_rectangle(
|
d.draw_rectangle(
|
||||||
x + margin,
|
x + margin,
|
||||||
y + margin,
|
y + margin,
|
||||||
width - margin * 2.,
|
width - margin * 2,
|
||||||
height - margin * 2.,
|
height - margin * 2,
|
||||||
colors::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simple_button(mouse: &MouseInput, x: f32, y: f32, width: f32, height: f32) -> bool {
|
pub fn simple_button(
|
||||||
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
) -> bool {
|
||||||
let mouse_pos = mouse.pos();
|
let mouse_pos = mouse.pos();
|
||||||
let bounds = Rect::new(x, y, width, height);
|
let bounds = rect(x, y, width, height);
|
||||||
let hover = bounds.contains(mouse_pos);
|
let hover = bounds.check_collision_point_rec(mouse_pos);
|
||||||
let pressed = hover && mouse.left_click();
|
let pressed = hover && mouse.left_click();
|
||||||
draw_rectangle(x, y, width, height, widget_bg(hover));
|
d.draw_rectangle(x, y, width, height, widget_bg(hover));
|
||||||
pressed
|
pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_button(mouse: &MouseInput, x: f32, y: f32, width: f32, text: &str) -> bool {
|
pub fn text_button(
|
||||||
let font_size = 20.;
|
d: &mut RaylibDrawHandle,
|
||||||
let margin = font_size / 4.;
|
mouse: &MouseInput,
|
||||||
let height = font_size + margin * 2.;
|
x: i32,
|
||||||
let clicked = simple_button(mouse, x, y, width, height);
|
y: i32,
|
||||||
draw_text(text, x + margin, y + margin, font_size, colors::WHITE);
|
width: i32,
|
||||||
|
text: &str,
|
||||||
|
) -> bool {
|
||||||
|
let font_size = 20;
|
||||||
|
let margin = font_size / 4;
|
||||||
|
let height = font_size + margin * 2;
|
||||||
|
let clicked = simple_button((d, mouse), x, y, width, height);
|
||||||
|
d.draw_text(text, x + margin, y + margin, font_size, Color::WHITE);
|
||||||
clicked
|
clicked
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tex32_button(
|
pub fn tex32_button(
|
||||||
mouse: &MouseInput,
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
(x, y): (f32, f32),
|
(x, y): (i32, i32),
|
||||||
texture: &Texture2D,
|
texture: &Texture2D,
|
||||||
(tooltip, text): (&mut Tooltip, &'static str),
|
(tooltip, text): (&mut Tooltip, &'static str),
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let size = 32.;
|
let size = 32;
|
||||||
let clicked = simple_button(mouse, x, y, size, size);
|
let clicked = simple_button((d, mouse), x, y, 32, 32);
|
||||||
draw_scaled_texture(texture, x, y, 2.);
|
draw_scaled_texture(d, texture, x, y, 2.);
|
||||||
tooltip.add(x, y, size, size, text);
|
tooltip.add(x, y, size, size, text);
|
||||||
clicked
|
clicked
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simple_option_button<T>(mouse: &MouseInput, bounds: Rect, option: T, current: &mut T) -> bool
|
pub fn simple_option_button<T>(
|
||||||
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
|
bounds: Rectangle,
|
||||||
|
option: T,
|
||||||
|
current: &mut T,
|
||||||
|
) -> bool
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
draw_rectangle_rec(bounds, widget_bg(&option == current));
|
d.draw_rectangle_rec(bounds, widget_bg(&option == current));
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
if mouse.left_click() && mouse.is_over(bounds) && current != &option {
|
if mouse.left_click() && mouse.is_over(bounds) && current != &option {
|
||||||
*current = option;
|
*current = option;
|
||||||
|
@ -221,33 +252,42 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_input(
|
pub fn text_input(
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
globals: &mut Globals,
|
globals: &mut Globals,
|
||||||
bounds: Rect,
|
bounds: Rectangle,
|
||||||
text: &mut String,
|
text: &mut String,
|
||||||
is_selected: &mut bool,
|
is_selected: &mut bool,
|
||||||
max_len: usize,
|
max_len: usize,
|
||||||
editable: bool,
|
editable: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
let font_size = 20.;
|
let font_size = 20;
|
||||||
draw_rectangle_rec(bounds, widget_bg(*is_selected));
|
d.draw_rectangle_rec(bounds, widget_bg(*is_selected));
|
||||||
draw_rectangle(
|
d.draw_rectangle_rec(
|
||||||
bounds.x + 2.,
|
Rectangle::new(
|
||||||
bounds.y + bounds.h - 5.,
|
bounds.x + 2.,
|
||||||
bounds.w - 4.,
|
bounds.y + bounds.height - 5.,
|
||||||
3.,
|
bounds.width - 4.,
|
||||||
|
3.,
|
||||||
|
),
|
||||||
BG_DARK,
|
BG_DARK,
|
||||||
);
|
);
|
||||||
draw_text(text, bounds.x + 4., bounds.y + 4., font_size, colors::WHITE);
|
d.draw_text(
|
||||||
|
text,
|
||||||
|
bounds.x as i32 + 4,
|
||||||
|
bounds.y as i32 + 4,
|
||||||
|
font_size,
|
||||||
|
Color::WHITE,
|
||||||
|
);
|
||||||
// blinking cursor
|
// blinking cursor
|
||||||
if *is_selected && get_time().fract() < 0.5 {
|
if *is_selected && d.get_time().fract() < 0.5 {
|
||||||
let width = measure_text(text, None, font_size as _, 1.).width;
|
let width = d.measure_text(text, font_size);
|
||||||
draw_rectangle(
|
d.draw_rectangle(
|
||||||
bounds.x + 6. + width,
|
bounds.x as i32 + 6 + width,
|
||||||
bounds.y + 4.,
|
bounds.y as i32 + 4,
|
||||||
2.,
|
2,
|
||||||
font_size,
|
font_size,
|
||||||
colors::WHITE,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if editable && globals.mouse.left_click() && (globals.mouse.is_over(bounds) || *is_selected) {
|
if editable && globals.mouse.left_click() && (globals.mouse.is_over(bounds) || *is_selected) {
|
||||||
|
@ -256,13 +296,13 @@ pub fn text_input(
|
||||||
|
|
||||||
if *is_selected {
|
if *is_selected {
|
||||||
globals.config.input.in_text_edit = true;
|
globals.config.input.in_text_edit = true;
|
||||||
if is_key_pressed(KeyCode::Escape) || is_key_pressed(KeyCode::Enter) {
|
if d.is_key_pressed(KeyboardKey::KEY_ESCAPE) || d.is_key_pressed(KeyboardKey::KEY_ENTER) {
|
||||||
*is_selected = false;
|
*is_selected = false;
|
||||||
}
|
}
|
||||||
if is_key_pressed(KeyCode::Backspace) && !text.is_empty() {
|
if d.is_key_pressed(KeyboardKey::KEY_BACKSPACE) && !text.is_empty() {
|
||||||
changed = true;
|
changed = true;
|
||||||
text.pop();
|
text.pop();
|
||||||
if is_key_down(KeyCode::LeftControl) {
|
if d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL) {
|
||||||
while let Some(c) = text.pop() {
|
while let Some(c) = text.pop() {
|
||||||
if c == ' ' {
|
if c == ' ' {
|
||||||
break;
|
break;
|
||||||
|
@ -271,7 +311,12 @@ pub fn text_input(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text.len() < max_len {
|
if text.len() < max_len {
|
||||||
let c = get_char_pressed();
|
let char_code = unsafe { ffi::GetCharPressed() };
|
||||||
|
let c = if char_code > 0 {
|
||||||
|
char::from_u32(char_code as u32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
if let Some(c) = c {
|
if let Some(c) = c {
|
||||||
changed = true;
|
changed = true;
|
||||||
text.push(c);
|
text.push(c);
|
||||||
|
@ -282,8 +327,8 @@ pub fn text_input(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scrollable_texture_option_button<T>(
|
pub fn scrollable_texture_option_button<T>(
|
||||||
mouse: &MouseInput,
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
pos: Vec2,
|
pos: Vector2,
|
||||||
texture: &Texture2D,
|
texture: &Texture2D,
|
||||||
option: T,
|
option: T,
|
||||||
current: &mut T,
|
current: &mut T,
|
||||||
|
@ -293,8 +338,13 @@ pub fn scrollable_texture_option_button<T>(
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
let bounds = Rect::new(pos.x, pos.y, 32. + border * 2., 32. + border * 2.);
|
let bounds = Rectangle {
|
||||||
draw_rectangle_rec(
|
x: pos.x,
|
||||||
|
y: pos.y,
|
||||||
|
width: 32. + border * 2.,
|
||||||
|
height: 32. + border * 2.,
|
||||||
|
};
|
||||||
|
d.draw_rectangle_rec(
|
||||||
bounds,
|
bounds,
|
||||||
if &option == current {
|
if &option == current {
|
||||||
BG_WIDGET_ACTIVE
|
BG_WIDGET_ACTIVE
|
||||||
|
@ -302,16 +352,12 @@ where
|
||||||
gray(16)
|
gray(16)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let params = DrawTextureParams {
|
d.draw_texture_ex(
|
||||||
dest_size: Some(Vec2::splat(32.)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
draw_texture_ex(
|
|
||||||
texture,
|
texture,
|
||||||
pos.x + border,
|
pos + Vector2::new(border, border),
|
||||||
pos.y + border,
|
0.,
|
||||||
colors::WHITE,
|
32. / texture.width as f32,
|
||||||
params,
|
Color::WHITE,
|
||||||
);
|
);
|
||||||
if clicked_override {
|
if clicked_override {
|
||||||
*current = option;
|
*current = option;
|
||||||
|
@ -325,32 +371,34 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_usize(
|
pub fn draw_usize(
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
textures: &Textures,
|
textures: &Textures,
|
||||||
mut number: usize,
|
mut number: usize,
|
||||||
(x, y): (f32, f32),
|
(x, y): (i32, i32),
|
||||||
digits: u8,
|
digits: i32,
|
||||||
scale: f32,
|
scale: i32,
|
||||||
) {
|
) {
|
||||||
for i in 0..digits {
|
for i in 0..digits {
|
||||||
draw_rectangle(
|
d.draw_rectangle(x + 10 * i * scale, y, 8 * scale, 16 * scale, BG_LIGHT);
|
||||||
x + 10. * i as f32 * scale,
|
|
||||||
y,
|
|
||||||
8. * scale,
|
|
||||||
16. * scale,
|
|
||||||
BG_LIGHT,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while (number != 0 || i == 0) && i < digits {
|
while (number != 0 || i == 0) && i < digits {
|
||||||
let texture = textures.get(&format!("digit_{}", number % 10));
|
let texture = textures.get(&format!("digit_{}", number % 10));
|
||||||
let x = x + (digits - i - 1) as f32 * 10. * scale;
|
let x = x + (digits - i - 1) * 10 * scale;
|
||||||
draw_scaled_texture(texture, x, y, scale);
|
draw_scaled_texture(d, texture, x, y, scale as f32);
|
||||||
number /= 10;
|
number /= 10;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_usize_small(textures: &Textures, mut num: usize, mut x: f32, y: f32, scale: f32) {
|
pub fn draw_usize_small(
|
||||||
|
d: &mut RaylibDrawHandle,
|
||||||
|
textures: &Textures,
|
||||||
|
mut num: usize,
|
||||||
|
mut x: i32,
|
||||||
|
y: i32,
|
||||||
|
scale: f32,
|
||||||
|
) {
|
||||||
const MAX_DIGITS: usize = 8;
|
const MAX_DIGITS: usize = 8;
|
||||||
let mut digits = [0; MAX_DIGITS];
|
let mut digits = [0; MAX_DIGITS];
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -361,29 +409,31 @@ pub fn draw_usize_small(textures: &Textures, mut num: usize, mut x: f32, y: f32,
|
||||||
}
|
}
|
||||||
let texture = textures.get("digits_small");
|
let texture = textures.get("digits_small");
|
||||||
for &digit in &digits[(MAX_DIGITS - i)..] {
|
for &digit in &digits[(MAX_DIGITS - i)..] {
|
||||||
let source = Rect::new(4. * digit as f32, 0., 4., 6.);
|
let source = Rectangle::new(4. * digit as f32, 0., 4., 6.);
|
||||||
let params = DrawTextureParams {
|
let dest = Rectangle::new(x as f32, y as f32, 4. * scale, 6. * scale);
|
||||||
dest_size: Some(Vec2::new(4. * scale, 6. * scale)),
|
d.draw_texture_pro(texture, source, dest, Vector2::zero(), 0., FG_MARBLE_VALUE);
|
||||||
source: Some(source),
|
x += 4 * scale as i32;
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
draw_texture_ex(texture, x, y, FG_MARBLE_VALUE, params);
|
|
||||||
x += 4. * scale;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slider(mouse: &MouseInput, bounds: Rect, value: &mut u8, min: u8, max: u8) -> bool {
|
pub fn slider(
|
||||||
|
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
||||||
|
bounds: Rectangle,
|
||||||
|
value: &mut u8,
|
||||||
|
min: u8,
|
||||||
|
max: u8,
|
||||||
|
) -> bool {
|
||||||
// draw state
|
// draw state
|
||||||
// the +1 makes the lowest state look slightly filled and the max state fully filled
|
// the +1 makes the lowest state look slightly filled and the max state fully filled
|
||||||
let percent = (*value - min + 1) as f32 / (max - min + 1) as f32;
|
let percent = (*value - min + 1) as f32 / (max - min + 1) as f32;
|
||||||
draw_rectangle_rec(bounds, BG_WIDGET);
|
d.draw_rectangle_rec(bounds, BG_WIDGET);
|
||||||
let mut filled_bounds = bounds;
|
let mut filled_bounds = bounds;
|
||||||
filled_bounds.w *= percent;
|
filled_bounds.width *= percent;
|
||||||
draw_rectangle_rec(filled_bounds, SLIDER_FILL);
|
d.draw_rectangle_rec(filled_bounds, Color::CYAN);
|
||||||
// interaction
|
// interaction
|
||||||
if mouse.is_over(bounds) {
|
if mouse.is_over(bounds) {
|
||||||
if mouse.left_hold() {
|
if mouse.left_hold() {
|
||||||
let percent = (mouse.pos().x - bounds.x) / bounds.w;
|
let percent = (mouse.pos().x - bounds.x) / bounds.width;
|
||||||
let new_value = min + (percent * (max - min + 1) as f32) as u8;
|
let new_value = min + (percent * (max - min + 1) as f32) as u8;
|
||||||
if *value != new_value {
|
if *value != new_value {
|
||||||
*value = new_value;
|
*value = new_value;
|
||||||
|
|
92
src/util.rs
92
src/util.rs
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::HashMap, fs::read_dir, path::PathBuf};
|
use std::{collections::HashMap, fs::read_dir, path::PathBuf};
|
||||||
|
|
||||||
use macroquad::{color::colors, prelude::*};
|
use raylib::prelude::*;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Textures {
|
pub struct Textures {
|
||||||
|
@ -8,13 +8,14 @@ pub struct Textures {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Textures {
|
impl Textures {
|
||||||
pub async fn load_dir(&mut self, folder: &str) {
|
pub fn load_dir(&mut self, folder: &str, rl: &mut RaylibHandle, thread: &RaylibThread) {
|
||||||
for d in read_dir(folder).unwrap().flatten() {
|
for d in read_dir(folder).unwrap().flatten() {
|
||||||
let path = d.path();
|
let path = d.path();
|
||||||
if path.is_file() {
|
if path.is_file() {
|
||||||
let name = path.file_stem().unwrap().to_string_lossy();
|
let name = path.file_stem().unwrap().to_string_lossy();
|
||||||
|
let texture = rl
|
||||||
let texture = load_texture(&format!("{folder}/{name}.png")).await.unwrap();
|
.load_texture(thread, &format!("{folder}/{name}.png"))
|
||||||
|
.unwrap();
|
||||||
self.map.insert(name.to_string(), texture);
|
self.map.insert(name.to_string(), texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,24 +32,15 @@ pub fn userdata_dir() -> PathBuf {
|
||||||
PathBuf::from("user")
|
PathBuf::from("user")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_rectangle_rec(bounds: Rect, color: Color) {
|
pub fn draw_scaled_texture(
|
||||||
draw_rectangle(bounds.x, bounds.y, bounds.w, bounds.h, color);
|
d: &mut RaylibDrawHandle,
|
||||||
}
|
texture: &Texture2D,
|
||||||
|
x: i32,
|
||||||
pub fn draw_scaled_texture_c(texture: &Texture2D, x: f32, y: f32, scale: f32, color: Color) {
|
y: i32,
|
||||||
let params = DrawTextureParams {
|
scale: f32,
|
||||||
dest_size: Some(Vec2::new(texture.width() * scale, texture.height() * scale)),
|
) {
|
||||||
..Default::default()
|
let pos = Vector2::new(x as f32, y as f32);
|
||||||
};
|
d.draw_texture_ex(texture, pos, 0., scale, Color::WHITE);
|
||||||
draw_texture_ex(texture, x, y, color, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_scaled_texture(texture: &Texture2D, x: f32, y: f32, scale: f32) {
|
|
||||||
let params = DrawTextureParams {
|
|
||||||
dest_size: Some(Vec2::new(texture.width() * scale, texture.height() * scale)),
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
draw_texture_ex(texture, x, y, colors::WHITE, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
|
pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
|
||||||
|
@ -59,21 +51,31 @@ pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn screen_centered_rect(width: f32, height: f32) -> Rect {
|
pub fn screen_centered_rect(rl: &RaylibHandle, width: i32, height: i32) -> Rectangle {
|
||||||
let w = screen_width();
|
let w = rl.get_screen_width();
|
||||||
let h = screen_height();
|
let h = rl.get_screen_height();
|
||||||
Rect::new(w / 2. - width / 2., h / 2. - height / 2., width, height)
|
Rectangle {
|
||||||
|
x: (w / 2 - width / 2) as f32,
|
||||||
|
y: (h / 2 - height / 2) as f32,
|
||||||
|
width: width as f32,
|
||||||
|
height: height as f32,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn screen_centered_rect_dyn(margin_x: f32, margin_y: f32) -> Rect {
|
pub fn screen_centered_rect_dyn(rl: &RaylibHandle, margin_x: i32, margin_y: i32) -> Rectangle {
|
||||||
let w = screen_width();
|
let w = rl.get_screen_width();
|
||||||
let h = screen_height();
|
let h = rl.get_screen_height();
|
||||||
Rect::new(margin_x, margin_y, w - margin_x * 2., h - margin_y * 2.)
|
Rectangle {
|
||||||
|
x: margin_x as f32,
|
||||||
|
y: margin_y as f32,
|
||||||
|
width: (w - margin_x * 2) as f32,
|
||||||
|
height: (h - margin_y * 2) as f32,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct MouseInput {
|
pub struct MouseInput {
|
||||||
pos: Vec2,
|
pos: Vector2,
|
||||||
left_click: bool,
|
left_click: bool,
|
||||||
left_hold: bool,
|
left_hold: bool,
|
||||||
left_release: bool,
|
left_release: bool,
|
||||||
|
@ -82,24 +84,24 @@ pub struct MouseInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MouseInput {
|
impl MouseInput {
|
||||||
pub fn update(&mut self) {
|
pub fn update(&mut self, rl: &RaylibHandle) {
|
||||||
self.pos = mouse_position().into();
|
self.pos = rl.get_mouse_position();
|
||||||
self.left_click = is_mouse_button_pressed(MouseButton::Left);
|
self.left_click = rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
|
||||||
self.left_hold = is_mouse_button_down(MouseButton::Left);
|
self.left_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT);
|
||||||
self.left_release = is_mouse_button_released(MouseButton::Left);
|
self.left_release = rl.is_mouse_button_released(MouseButton::MOUSE_BUTTON_LEFT);
|
||||||
self.right_hold = is_mouse_button_down(MouseButton::Right);
|
self.right_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_RIGHT);
|
||||||
self.scroll = get_scroll();
|
self.scroll = get_scroll(rl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_over(&self, rect: Rect) -> bool {
|
pub fn is_over(&self, rect: Rectangle) -> bool {
|
||||||
rect.contains(self.pos)
|
rect.check_collision_point_rec(self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
*self = Self::default();
|
*self = Self::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos(&self) -> Vec2 {
|
pub fn pos(&self) -> Vector2 {
|
||||||
self.pos
|
self.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,9 +132,9 @@ pub enum Scroll {
|
||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scroll() -> Option<Scroll> {
|
pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
|
||||||
const SCROLL_THRESHOLD: f32 = 0.5;
|
const SCROLL_THRESHOLD: f32 = 0.5;
|
||||||
let value = mouse_wheel().0;
|
let value = rl.get_mouse_wheel_move();
|
||||||
if value > SCROLL_THRESHOLD {
|
if value > SCROLL_THRESHOLD {
|
||||||
Some(Scroll::Up)
|
Some(Scroll::Up)
|
||||||
} else if value < -SCROLL_THRESHOLD {
|
} else if value < -SCROLL_THRESHOLD {
|
||||||
|
@ -141,3 +143,7 @@ pub fn get_scroll() -> Option<Scroll> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn rect(x: i32, y: i32, width: i32, height: i32) -> Rectangle {
|
||||||
|
Rectangle::new(x as f32, y as f32, width as f32, height as f32)
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue