Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
0b2a3991ed | |||
324d16cfc2 | |||
f4348599f6 |
15 changed files with 1037 additions and 1104 deletions
387
Cargo.lock
generated
387
Cargo.lock
generated
|
@ -3,13 +3,16 @@
|
||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "adler2"
|
||||||
version = "1.1.3"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
[[package]]
|
||||||
]
|
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"
|
||||||
|
@ -33,24 +36,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bindgen"
|
name = "bitflags"
|
||||||
version = "0.70.1"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cexpr",
|
|
||||||
"clang-sys",
|
|
||||||
"itertools",
|
|
||||||
"log",
|
|
||||||
"prettyplease",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"regex",
|
|
||||||
"rustc-hash",
|
|
||||||
"shlex",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
|
@ -68,22 +57,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "bytemuck"
|
||||||
version = "1.1.24"
|
version = "1.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
|
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||||
dependencies = [
|
|
||||||
"shlex",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cexpr"
|
name = "byteorder"
|
||||||
version = "0.6.0"
|
version = "1.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
dependencies = [
|
|
||||||
"nom",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -91,17 +74,6 @@ 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"
|
||||||
|
@ -112,19 +84,25 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cmake"
|
name = "color_quant"
|
||||||
version = "0.1.51"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fb1e43aa7fd152b1f968787f7dbcdeb306d1867ff373c69955211876c053f91a"
|
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crc32fast"
|
||||||
|
version = "1.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "equivalent"
|
||||||
version = "1.13.0"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
|
@ -142,6 +120,41 @@ 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"
|
||||||
|
@ -153,18 +166,33 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glob"
|
name = "glam"
|
||||||
version = "0.3.1"
|
version = "0.27.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
checksum = "9e05e7e6723e3455f4818c7b26e855439f7546cf617ef669d1adedb8669e5cb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "hashbrown"
|
||||||
version = "0.12.1"
|
version = "0.15.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"allocator-api2",
|
||||||
|
"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]]
|
||||||
|
@ -179,16 +207,6 @@ 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"
|
||||||
|
@ -211,12 +229,41 @@ 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",
|
||||||
"raylib",
|
"macroquad",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -228,19 +275,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "miniquad"
|
||||||
version = "0.2.1"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
checksum = "2fb3e758e46dbc45716a8a49ca9edc54b15bcca826277e80b1f690708f67f9e3"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"ndk-sys",
|
||||||
|
"objc-rs",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "miniz_oxide"
|
||||||
version = "7.1.3"
|
version = "0.8.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"adler2",
|
||||||
"minimal-lexical",
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[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]]
|
||||||
|
@ -265,7 +342,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",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
@ -281,7 +358,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",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -311,7 +388,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",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
"libc",
|
"libc",
|
||||||
"objc2",
|
"objc2",
|
||||||
|
@ -323,7 +400,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",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -335,7 +412,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",
|
"bitflags 2.6.0",
|
||||||
"block2",
|
"block2",
|
||||||
"objc2",
|
"objc2",
|
||||||
"objc2-foundation",
|
"objc2-foundation",
|
||||||
|
@ -366,19 +443,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "paste"
|
name = "png"
|
||||||
version = "1.0.15"
|
version = "0.17.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "prettyplease"
|
|
||||||
version = "0.2.22"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"bitflags 1.3.2",
|
||||||
"syn",
|
"crc32fast",
|
||||||
|
"fdeflate",
|
||||||
|
"flate2",
|
||||||
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -390,6 +464,12 @@ 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"
|
||||||
|
@ -399,81 +479,22 @@ 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",
|
"bitflags 2.6.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[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",
|
"bitflags 2.6.0",
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
|
@ -492,12 +513,6 @@ 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"
|
||||||
|
@ -531,10 +546,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shlex"
|
name = "simd-adler32"
|
||||||
version = "1.3.0"
|
version = "0.3.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
|
@ -554,24 +569,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "ttf-parser"
|
||||||
version = "1.0.69"
|
version = "0.21.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"
|
||||||
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"
|
||||||
|
@ -579,6 +580,28 @@ 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,7 +6,8 @@ default-run = "marble-machinations"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arboard = { version = "3.4.1", default-features = false }
|
arboard = { version = "3.4.1", default-features = false }
|
||||||
raylib = "5.5"
|
macroquad = "0.4"
|
||||||
|
# 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,8 +1,4 @@
|
||||||
use raylib::{
|
use macroquad::{color::colors, prelude::*};
|
||||||
color::Color,
|
|
||||||
drawing::{RaylibDraw, RaylibDrawHandle},
|
|
||||||
math::Vector2,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -71,18 +67,18 @@ impl Board {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_comments(&self, d: &mut RaylibDrawHandle, offset: Vector2, scale: f32) {
|
pub fn draw_comments(&self, offset: Vec2, scale: f32) {
|
||||||
let tile_size = (TILE_TEXTURE_SIZE * scale) as i32;
|
let tile_size = TILE_TEXTURE_SIZE * scale;
|
||||||
let font_size = 10 * (scale as i32).max(1);
|
let font_size = 10. * scale.max(1.);
|
||||||
let line_space = 12 * (scale as i32).max(1);
|
let line_space = 12. * scale.max(1.);
|
||||||
|
|
||||||
for comment in &self.comments {
|
for comment in &self.comments {
|
||||||
let x = comment.x * tile_size + offset.x as i32;
|
let x = comment.x as f32 * tile_size + offset.x;
|
||||||
let y = comment.y * tile_size + offset.y as i32;
|
let y = comment.y as f32 * tile_size + offset.y;
|
||||||
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 i32;
|
let y = y + line_space * i as f32;
|
||||||
d.draw_text(line, x, y, font_size, Color::ORANGE);
|
draw_text(line, x, y, font_size, colors::ORANGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use raylib::prelude::*;
|
use macroquad::{color::colors, 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: u32,
|
scroll_offset: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
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, d: &mut RaylibDrawHandle, globals: &mut Globals) -> MenuReturn {
|
pub fn draw_edit(&mut self, 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.saturating_sub(64),
|
Some(Scroll::Up) => self.scroll_offset = (self.scroll_offset - 64.).max(0.),
|
||||||
None => (),
|
None => (),
|
||||||
}
|
}
|
||||||
let mut y = -(self.scroll_offset as i32) + 15;
|
let mut y = -self.scroll_offset + 15.;
|
||||||
d.draw_text("Settings", 16, y, 30, FG_CHAPTER_TITLE);
|
draw_text("Settings", 16., y, 30., FG_CHAPTER_TITLE);
|
||||||
y += 40;
|
y += 40.;
|
||||||
|
|
||||||
if text_button(d, &globals.mouse, 10, y, 80, "apply") {
|
if text_button(&globals.mouse, 10., y, 80., "apply") {
|
||||||
return MenuReturn::StaySave;
|
return MenuReturn::StaySave;
|
||||||
}
|
}
|
||||||
if text_button(d, &globals.mouse, 100, y, 80, "done") {
|
if text_button(&globals.mouse, 100., y, 80., "done") {
|
||||||
return MenuReturn::ReturnSave;
|
return MenuReturn::ReturnSave;
|
||||||
}
|
}
|
||||||
if text_button(d, &globals.mouse, 190, y, 80, "cancel") {
|
if text_button(&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((d, &globals.mouse), 10, y, 30, 30, value);
|
toggle_button(&globals.mouse, 10., y, 30., 30., value);
|
||||||
d.draw_text(text, 50, y + 5, 20, Color::WHITE);
|
draw_text(text, 50., y + 5., 20., colors::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(d, globals, y);
|
self.input.draw_edit(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,17 +1,12 @@
|
||||||
use std::{collections::BTreeMap, mem::transmute, vec};
|
use std::{collections::BTreeMap, mem::transmute, vec};
|
||||||
|
|
||||||
use raylib::{
|
use macroquad::{color::colors, prelude::*};
|
||||||
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::{rect, screen_centered_rect},
|
util::{draw_rectangle_rec, screen_centered_rect},
|
||||||
Globals,
|
Globals,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,89 +127,89 @@ enum BindingEdit {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input {
|
impl Input {
|
||||||
pub fn draw_edit(&mut self, d: &mut RaylibDrawHandle, globals: &mut Globals, mut y: i32) {
|
pub fn draw_edit(&mut self, globals: &mut Globals, mut y: f32) {
|
||||||
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 {
|
||||||
// d.draw_rectangle(200, y, 20, 20, Color::LIMEGREEN);
|
// draw_rectangle(200, y, 20, 20, colors::LIMEGREEN);
|
||||||
// }
|
// }
|
||||||
d.draw_text(&format!("{action:?}"), 16, y, 20, Color::ORANGE);
|
draw_text(&format!("{action:?}"), 16., y, 20., colors::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(d, &globals.mouse, buttons_x, y, 80, "remove") {
|
if text_button(&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(d, &globals.mouse, buttons_x + 85, y, 45, "edit") {
|
if text_button(&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;
|
||||||
d.draw_text(&trigger, x, y + 5, 20, Color::LIMEGREEN);
|
draw_text(&trigger, x, y + 5., 20., colors::GREEN);
|
||||||
x += 10 + d.measure_text(&trigger, 20);
|
x += 10. + measure_text(&trigger, None, 20, 1.).width;
|
||||||
//
|
//
|
||||||
let modifiers = format!("{:?}", binding.modifiers);
|
let modifiers = format!("{:?}", binding.modifiers);
|
||||||
d.draw_text(&modifiers, x, y + 5, 20, Color::LIGHTBLUE);
|
draw_text(&modifiers, x, y + 5., 20., colors::BLUE);
|
||||||
x += 10 + d.measure_text(&modifiers, 20);
|
x += 10. + measure_text(&modifiers, None, 20, 1.).width;
|
||||||
//
|
//
|
||||||
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:?}");
|
||||||
d.draw_text(&conflict_text, x, y + 5, 20, Color::ORANGERED);
|
draw_text(&conflict_text, x, y + 5., 20., colors::ORANGE);
|
||||||
x += 10 + d.measure_text(&conflict_text, 20);
|
x += 10. + measure_text(&conflict_text, None, 20, 1.).width
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
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);
|
||||||
d.draw_text(&blocking_text, x, y + 5, 20, Color::GRAY);
|
draw_text(&blocking_text, x, y + 5., 20., colors::GRAY);
|
||||||
}
|
}
|
||||||
y += 32;
|
y += 32.;
|
||||||
}
|
}
|
||||||
if text_button(d, &globals.mouse, buttons_x, y, 130, "add binding") {
|
if text_button(&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(d);
|
globals.mouse.update();
|
||||||
let border = screen_centered_rect(d, 408, 128);
|
let border = screen_centered_rect(408., 128.);
|
||||||
d.draw_rectangle_rec(border, BG_LIGHT);
|
draw_rectangle_rec(border, BG_LIGHT);
|
||||||
let bounds = screen_centered_rect(d, 400, 120);
|
let bounds = screen_centered_rect(400., 120.);
|
||||||
d.draw_rectangle_rec(bounds, BG_DARK);
|
draw_rectangle_rec(bounds, BG_DARK);
|
||||||
let x = bounds.x as i32;
|
let x = bounds.x;
|
||||||
let y = bounds.y as i32;
|
let y = bounds.y;
|
||||||
d.draw_text(
|
draw_text(
|
||||||
&format!("editing binding for {action:?}"),
|
&format!("editing binding for {action:?}"),
|
||||||
x + 10,
|
x + 10.,
|
||||||
y + 5,
|
y + 5.,
|
||||||
20,
|
20.,
|
||||||
Color::WHITE,
|
colors::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(ok_btn_x, ok_btn_y, ok_btn_width, 30);
|
let ok_btn_rect = Rect::new(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(d) {
|
if key.just_pressed() {
|
||||||
*edit_state = BindingEdit::Adding(Binding {
|
*edit_state = BindingEdit::Adding(Binding {
|
||||||
blocking_modifiers: Vec::new(),
|
blocking_modifiers: Vec::new(),
|
||||||
modifiers: Vec::new(),
|
modifiers: Vec::new(),
|
||||||
|
@ -223,12 +218,12 @@ impl Input {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BindingEdit::Adding(binding) => {
|
BindingEdit::Adding(binding) => {
|
||||||
if key.just_pressed(d) {
|
if key.just_pressed() {
|
||||||
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(d) {
|
} else if key.released() {
|
||||||
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);
|
||||||
|
@ -240,7 +235,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(d) && !clicking_ok {
|
if key.just_pressed() && !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(),
|
||||||
|
@ -253,25 +248,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(_)) {
|
||||||
Color::GREEN
|
colors::GREEN
|
||||||
} else {
|
} else {
|
||||||
Color::ORANGE
|
colors::ORANGE
|
||||||
};
|
};
|
||||||
let text = format!("{:?} + {:?}", b.modifiers, b.trigger);
|
let text = format!("{:?} + {:?}", b.modifiers, b.trigger);
|
||||||
d.draw_text(&text, x + 5, y + 5, 20, colour);
|
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() {
|
||||||
d.draw_text(
|
draw_text(
|
||||||
&format!("conflicts: {conflicts:?}"),
|
&format!("conflicts: {conflicts:?}"),
|
||||||
x + 200,
|
x + 200.,
|
||||||
y + 40,
|
y + 40.,
|
||||||
20,
|
20.,
|
||||||
Color::ORANGERED,
|
colors::ORANGE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text_button(d, &globals.mouse, ok_btn_x, ok_btn_y, ok_btn_width, "ok") {
|
if text_button(&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() {
|
||||||
|
@ -283,17 +278,17 @@ impl Input {
|
||||||
self.update_modifier_blocks();
|
self.update_modifier_blocks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text_button(d, &globals.mouse, x + 100, y + 40, 80, "cancel") {
|
if text_button(&globals.mouse, x + 100., y + 40., 80., "cancel") {
|
||||||
self.editing_binding = None;
|
self.editing_binding = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, rl: &RaylibHandle) {
|
pub fn update(&mut self) {
|
||||||
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(rl) {
|
*state = if button.is_down() {
|
||||||
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,
|
||||||
|
@ -464,10 +459,10 @@ enum Button {
|
||||||
MouseLeft,
|
MouseLeft,
|
||||||
MouseRight,
|
MouseRight,
|
||||||
MouseMiddle,
|
MouseMiddle,
|
||||||
Mouse3,
|
// Mouse3,
|
||||||
Mouse4,
|
// Mouse4,
|
||||||
Mouse5,
|
// Mouse5,
|
||||||
Mouse6,
|
// Mouse6,
|
||||||
Apostrophe,
|
Apostrophe,
|
||||||
Comma,
|
Comma,
|
||||||
Minus,
|
Minus,
|
||||||
|
@ -574,14 +569,12 @@ enum Button {
|
||||||
KpEnter,
|
KpEnter,
|
||||||
KpEqual,
|
KpEqual,
|
||||||
Back,
|
Back,
|
||||||
VolumeUp,
|
|
||||||
VolumeDown,
|
|
||||||
//
|
//
|
||||||
_EnumSize,
|
_EnumSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RlInput {
|
enum RlInput {
|
||||||
Key(KeyboardKey),
|
Key(KeyCode),
|
||||||
Mouse(MouseButton),
|
Mouse(MouseButton),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,146 +589,143 @@ impl Button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_down(self, rl: &RaylibHandle) -> bool {
|
fn is_down(self) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => rl.is_key_down(key),
|
RlInput::Key(key) => is_key_down(key),
|
||||||
RlInput::Mouse(btn) => rl.is_mouse_button_down(btn),
|
RlInput::Mouse(btn) => is_mouse_button_down(btn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn just_pressed(self, rl: &RaylibHandle) -> bool {
|
fn just_pressed(self) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => rl.is_key_pressed(key),
|
RlInput::Key(key) => is_key_pressed(key),
|
||||||
RlInput::Mouse(btn) => rl.is_mouse_button_pressed(btn),
|
RlInput::Mouse(btn) => is_mouse_button_pressed(btn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn released(self, rl: &RaylibHandle) -> bool {
|
fn released(self) -> bool {
|
||||||
match self.to_raylib() {
|
match self.to_raylib() {
|
||||||
RlInput::Key(key) => rl.is_key_released(key),
|
RlInput::Key(key) => is_key_released(key),
|
||||||
RlInput::Mouse(btn) => rl.is_mouse_button_released(btn),
|
RlInput::Mouse(btn) => 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::MOUSE_BUTTON_LEFT),
|
Button::MouseLeft => Mouse(MouseButton::Left),
|
||||||
Button::MouseRight => Mouse(MouseButton::MOUSE_BUTTON_RIGHT),
|
Button::MouseRight => Mouse(MouseButton::Right),
|
||||||
Button::MouseMiddle => Mouse(MouseButton::MOUSE_BUTTON_MIDDLE),
|
Button::MouseMiddle => Mouse(MouseButton::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(KEY_APOSTROPHE),
|
Button::Apostrophe => Key(KeyCode::Apostrophe),
|
||||||
Button::Comma => Key(KEY_COMMA),
|
Button::Comma => Key(KeyCode::Comma),
|
||||||
Button::Minus => Key(KEY_MINUS),
|
Button::Minus => Key(KeyCode::Minus),
|
||||||
Button::Period => Key(KEY_PERIOD),
|
Button::Period => Key(KeyCode::Period),
|
||||||
Button::Slash => Key(KEY_SLASH),
|
Button::Slash => Key(KeyCode::Slash),
|
||||||
Button::Zero => Key(KEY_ZERO),
|
Button::Zero => Key(KeyCode::Key0),
|
||||||
Button::One => Key(KEY_ONE),
|
Button::One => Key(KeyCode::Key1),
|
||||||
Button::Two => Key(KEY_TWO),
|
Button::Two => Key(KeyCode::Key2),
|
||||||
Button::Three => Key(KEY_THREE),
|
Button::Three => Key(KeyCode::Key3),
|
||||||
Button::Four => Key(KEY_FOUR),
|
Button::Four => Key(KeyCode::Key4),
|
||||||
Button::Five => Key(KEY_FIVE),
|
Button::Five => Key(KeyCode::Key5),
|
||||||
Button::Six => Key(KEY_SIX),
|
Button::Six => Key(KeyCode::Key6),
|
||||||
Button::Seven => Key(KEY_SEVEN),
|
Button::Seven => Key(KeyCode::Key7),
|
||||||
Button::Eight => Key(KEY_EIGHT),
|
Button::Eight => Key(KeyCode::Key8),
|
||||||
Button::Nine => Key(KEY_NINE),
|
Button::Nine => Key(KeyCode::Key9),
|
||||||
Button::Semicolon => Key(KEY_SEMICOLON),
|
Button::Semicolon => Key(KeyCode::Semicolon),
|
||||||
Button::Equal => Key(KEY_EQUAL),
|
Button::Equal => Key(KeyCode::Equal),
|
||||||
Button::A => Key(KEY_A),
|
Button::A => Key(KeyCode::A),
|
||||||
Button::B => Key(KEY_B),
|
Button::B => Key(KeyCode::B),
|
||||||
Button::C => Key(KEY_C),
|
Button::C => Key(KeyCode::C),
|
||||||
Button::D => Key(KEY_D),
|
Button::D => Key(KeyCode::D),
|
||||||
Button::E => Key(KEY_E),
|
Button::E => Key(KeyCode::E),
|
||||||
Button::F => Key(KEY_F),
|
Button::F => Key(KeyCode::F),
|
||||||
Button::G => Key(KEY_G),
|
Button::G => Key(KeyCode::G),
|
||||||
Button::H => Key(KEY_H),
|
Button::H => Key(KeyCode::H),
|
||||||
Button::I => Key(KEY_I),
|
Button::I => Key(KeyCode::I),
|
||||||
Button::J => Key(KEY_J),
|
Button::J => Key(KeyCode::J),
|
||||||
Button::K => Key(KEY_K),
|
Button::K => Key(KeyCode::K),
|
||||||
Button::L => Key(KEY_L),
|
Button::L => Key(KeyCode::L),
|
||||||
Button::M => Key(KEY_M),
|
Button::M => Key(KeyCode::M),
|
||||||
Button::N => Key(KEY_N),
|
Button::N => Key(KeyCode::N),
|
||||||
Button::O => Key(KEY_O),
|
Button::O => Key(KeyCode::O),
|
||||||
Button::P => Key(KEY_P),
|
Button::P => Key(KeyCode::P),
|
||||||
Button::Q => Key(KEY_Q),
|
Button::Q => Key(KeyCode::Q),
|
||||||
Button::R => Key(KEY_R),
|
Button::R => Key(KeyCode::R),
|
||||||
Button::S => Key(KEY_S),
|
Button::S => Key(KeyCode::S),
|
||||||
Button::T => Key(KEY_T),
|
Button::T => Key(KeyCode::T),
|
||||||
Button::U => Key(KEY_U),
|
Button::U => Key(KeyCode::U),
|
||||||
Button::V => Key(KEY_V),
|
Button::V => Key(KeyCode::V),
|
||||||
Button::W => Key(KEY_W),
|
Button::W => Key(KeyCode::W),
|
||||||
Button::X => Key(KEY_X),
|
Button::X => Key(KeyCode::X),
|
||||||
Button::Y => Key(KEY_Y),
|
Button::Y => Key(KeyCode::Y),
|
||||||
Button::Z => Key(KEY_Z),
|
Button::Z => Key(KeyCode::Z),
|
||||||
Button::LeftBracket => Key(KEY_LEFT_BRACKET),
|
Button::LeftBracket => Key(KeyCode::LeftBracket),
|
||||||
Button::Backslash => Key(KEY_BACKSLASH),
|
Button::Backslash => Key(KeyCode::Backslash),
|
||||||
Button::RightBracket => Key(KEY_RIGHT_BRACKET),
|
Button::RightBracket => Key(KeyCode::RightBracket),
|
||||||
Button::Grave => Key(KEY_GRAVE),
|
Button::Grave => Key(KeyCode::GraveAccent),
|
||||||
Button::Space => Key(KEY_SPACE),
|
Button::Space => Key(KeyCode::Space),
|
||||||
Button::Escape => Key(KEY_ESCAPE),
|
Button::Escape => Key(KeyCode::Escape),
|
||||||
Button::Enter => Key(KEY_ENTER),
|
Button::Enter => Key(KeyCode::Enter),
|
||||||
Button::Tab => Key(KEY_TAB),
|
Button::Tab => Key(KeyCode::Tab),
|
||||||
Button::Backspace => Key(KEY_BACKSPACE),
|
Button::Backspace => Key(KeyCode::Backspace),
|
||||||
Button::Insert => Key(KEY_INSERT),
|
Button::Insert => Key(KeyCode::Insert),
|
||||||
Button::Delete => Key(KEY_DELETE),
|
Button::Delete => Key(KeyCode::Delete),
|
||||||
Button::Right => Key(KEY_RIGHT),
|
Button::Right => Key(KeyCode::Right),
|
||||||
Button::Left => Key(KEY_LEFT),
|
Button::Left => Key(KeyCode::Left),
|
||||||
Button::Down => Key(KEY_DOWN),
|
Button::Down => Key(KeyCode::Down),
|
||||||
Button::Up => Key(KEY_UP),
|
Button::Up => Key(KeyCode::Up),
|
||||||
Button::PageUp => Key(KEY_PAGE_UP),
|
Button::PageUp => Key(KeyCode::PageUp),
|
||||||
Button::PageDown => Key(KEY_PAGE_DOWN),
|
Button::PageDown => Key(KeyCode::PageDown),
|
||||||
Button::Home => Key(KEY_HOME),
|
Button::Home => Key(KeyCode::Home),
|
||||||
Button::End => Key(KEY_END),
|
Button::End => Key(KeyCode::End),
|
||||||
Button::CapsLock => Key(KEY_CAPS_LOCK),
|
Button::CapsLock => Key(KeyCode::CapsLock),
|
||||||
Button::ScrollLock => Key(KEY_SCROLL_LOCK),
|
Button::ScrollLock => Key(KeyCode::ScrollLock),
|
||||||
Button::NumLock => Key(KEY_NUM_LOCK),
|
Button::NumLock => Key(KeyCode::NumLock),
|
||||||
Button::PrintScreen => Key(KEY_PRINT_SCREEN),
|
Button::PrintScreen => Key(KeyCode::PrintScreen),
|
||||||
Button::Pause => Key(KEY_PAUSE),
|
Button::Pause => Key(KeyCode::Pause),
|
||||||
Button::F1 => Key(KEY_F1),
|
Button::F1 => Key(KeyCode::F1),
|
||||||
Button::F2 => Key(KEY_F2),
|
Button::F2 => Key(KeyCode::F2),
|
||||||
Button::F3 => Key(KEY_F3),
|
Button::F3 => Key(KeyCode::F3),
|
||||||
Button::F4 => Key(KEY_F4),
|
Button::F4 => Key(KeyCode::F4),
|
||||||
Button::F5 => Key(KEY_F5),
|
Button::F5 => Key(KeyCode::F5),
|
||||||
Button::F6 => Key(KEY_F6),
|
Button::F6 => Key(KeyCode::F6),
|
||||||
Button::F7 => Key(KEY_F7),
|
Button::F7 => Key(KeyCode::F7),
|
||||||
Button::F8 => Key(KEY_F8),
|
Button::F8 => Key(KeyCode::F8),
|
||||||
Button::F9 => Key(KEY_F9),
|
Button::F9 => Key(KeyCode::F9),
|
||||||
Button::F10 => Key(KEY_F10),
|
Button::F10 => Key(KeyCode::F10),
|
||||||
Button::F11 => Key(KEY_F11),
|
Button::F11 => Key(KeyCode::F11),
|
||||||
Button::F12 => Key(KEY_F12),
|
Button::F12 => Key(KeyCode::F12),
|
||||||
Button::LShift => Key(KEY_LEFT_SHIFT),
|
Button::LShift => Key(KeyCode::LeftShift),
|
||||||
Button::LCtrl => Key(KEY_LEFT_CONTROL),
|
Button::LCtrl => Key(KeyCode::LeftControl),
|
||||||
Button::LAlt => Key(KEY_LEFT_ALT),
|
Button::LAlt => Key(KeyCode::LeftAlt),
|
||||||
Button::LeftSuper => Key(KEY_LEFT_SUPER),
|
Button::LeftSuper => Key(KeyCode::LeftSuper),
|
||||||
Button::RShift => Key(KEY_RIGHT_SHIFT),
|
Button::RShift => Key(KeyCode::RightShift),
|
||||||
Button::RCtrl => Key(KEY_RIGHT_CONTROL),
|
Button::RCtrl => Key(KeyCode::RightControl),
|
||||||
Button::RAlt => Key(KEY_RIGHT_ALT),
|
Button::RAlt => Key(KeyCode::RightAlt),
|
||||||
Button::RightSuper => Key(KEY_RIGHT_SUPER),
|
Button::RightSuper => Key(KeyCode::RightSuper),
|
||||||
Button::Menu => Key(KEY_KB_MENU),
|
Button::Menu => Key(KeyCode::Menu),
|
||||||
Button::Kp0 => Key(KEY_KP_0),
|
Button::Kp0 => Key(KeyCode::Kp0),
|
||||||
Button::Kp1 => Key(KEY_KP_1),
|
Button::Kp1 => Key(KeyCode::Kp1),
|
||||||
Button::Kp2 => Key(KEY_KP_2),
|
Button::Kp2 => Key(KeyCode::Kp2),
|
||||||
Button::Kp3 => Key(KEY_KP_3),
|
Button::Kp3 => Key(KeyCode::Kp3),
|
||||||
Button::Kp4 => Key(KEY_KP_4),
|
Button::Kp4 => Key(KeyCode::Kp4),
|
||||||
Button::Kp5 => Key(KEY_KP_5),
|
Button::Kp5 => Key(KeyCode::Kp5),
|
||||||
Button::Kp6 => Key(KEY_KP_6),
|
Button::Kp6 => Key(KeyCode::Kp6),
|
||||||
Button::Kp7 => Key(KEY_KP_7),
|
Button::Kp7 => Key(KeyCode::Kp7),
|
||||||
Button::Kp8 => Key(KEY_KP_8),
|
Button::Kp8 => Key(KeyCode::Kp8),
|
||||||
Button::Kp9 => Key(KEY_KP_9),
|
Button::Kp9 => Key(KeyCode::Kp9),
|
||||||
Button::KpDecimal => Key(KEY_KP_DECIMAL),
|
Button::KpDecimal => Key(KeyCode::KpDecimal),
|
||||||
Button::KpDivide => Key(KEY_KP_DIVIDE),
|
Button::KpDivide => Key(KeyCode::KpDivide),
|
||||||
Button::KpMultiply => Key(KEY_KP_MULTIPLY),
|
Button::KpMultiply => Key(KeyCode::KpMultiply),
|
||||||
Button::KpSubtract => Key(KEY_KP_SUBTRACT),
|
Button::KpSubtract => Key(KeyCode::KpSubtract),
|
||||||
Button::KpAdd => Key(KEY_KP_ADD),
|
Button::KpAdd => Key(KeyCode::KpAdd),
|
||||||
Button::KpEnter => Key(KEY_KP_ENTER),
|
Button::KpEnter => Key(KeyCode::KpEnter),
|
||||||
Button::KpEqual => Key(KEY_KP_EQUAL),
|
Button::KpEqual => Key(KeyCode::KpEqual),
|
||||||
Button::Back => Key(KEY_BACK),
|
Button::Back => Key(KeyCode::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 raylib::{texture::Texture2D, RaylibHandle};
|
use macroquad::prelude::*;
|
||||||
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 fn new(rl: &mut RaylibHandle, thread: &raylib::prelude::RaylibThread) -> Self {
|
pub async fn new() -> Self {
|
||||||
let mut textures = Textures::default();
|
let mut textures = Textures::default();
|
||||||
textures.load_dir("assets", rl, thread);
|
textures.load_dir("assets").await;
|
||||||
textures.load_dir("assets/tiles", rl, thread);
|
textures.load_dir("assets/tiles").await;
|
||||||
textures.load_dir("assets/digits", rl, thread);
|
textures.load_dir("assets/digits").await;
|
||||||
|
|
||||||
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, rl: &RaylibHandle) {
|
pub fn update(&mut self) {
|
||||||
self.config.input.update(rl);
|
self.config.input.update();
|
||||||
self.mouse.update(rl);
|
self.mouse.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
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 raylib::prelude::*;
|
use macroquad::{color::colors, miniquad::window::set_mouse_cursor, 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: i32,
|
level_scroll: f32,
|
||||||
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,45 +32,43 @@ struct Game {
|
||||||
edit_settings: Option<Config>,
|
edit_settings: Option<Config>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[macroquad::main("what does thsi doa")]
|
||||||
let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
async fn main() {
|
||||||
rl.set_target_fps(60);
|
// let (mut rl, thread) = raylib::init().resizable().title(TITLE_TEXT).build();
|
||||||
rl.set_window_min_size(640, 480);
|
// set_target_fps(60);
|
||||||
rl.set_mouse_cursor(MouseCursor::MOUSE_CURSOR_CROSSHAIR);
|
// set_window_min_size(640, 480);
|
||||||
rl.set_exit_key(None);
|
set_mouse_cursor(miniquad::CursorIcon::Crosshair);
|
||||||
rl.set_trace_log(TraceLogLevel::LOG_WARNING);
|
|
||||||
|
|
||||||
let mut game = Game::new(&mut rl, &thread);
|
let mut game = Game::new().await;
|
||||||
game.run(&mut rl, &thread);
|
game.run().await
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
fn new(rl: &mut RaylibHandle, thread: &RaylibThread) -> Self {
|
async fn new() -> 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(rl, thread),
|
globals: Globals::new().await,
|
||||||
edit_settings: None,
|
edit_settings: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&mut self, rl: &mut RaylibHandle, thread: &RaylibThread) {
|
async fn run(&mut self) {
|
||||||
while !rl.window_should_close() {
|
loop {
|
||||||
let mut d = rl.begin_drawing(thread);
|
self.globals.update();
|
||||||
self.globals.update(&d);
|
|
||||||
if let Some(editor) = &mut self.open_editor {
|
if let Some(editor) = &mut self.open_editor {
|
||||||
editor.update(&d, &mut self.globals);
|
editor.update(&mut self.globals);
|
||||||
editor.draw(&mut d, &mut self.globals);
|
editor.draw(&mut self.globals);
|
||||||
match editor.get_exit_state() {
|
match editor.get_exit_state() {
|
||||||
ExitState::Dont => (),
|
ExitState::Dont => (),
|
||||||
ExitState::ExitAndSave => {
|
ExitState::ExitAndSave => {
|
||||||
|
@ -90,8 +88,8 @@ impl Game {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(config) = &mut self.edit_settings {
|
} else if let Some(config) = &mut self.edit_settings {
|
||||||
d.clear_background(BG_DARK);
|
clear_background(BG_DARK);
|
||||||
match config.draw_edit(&mut d, &mut self.globals) {
|
match config.draw_edit(&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();
|
||||||
|
@ -105,65 +103,65 @@ impl Game {
|
||||||
config::MenuReturn::ReturnCancel => self.edit_settings = None,
|
config::MenuReturn::ReturnCancel => self.edit_settings = None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.draw(&mut d);
|
self.draw();
|
||||||
}
|
}
|
||||||
|
next_frame().await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&mut self, d: &mut RaylibDrawHandle) {
|
fn draw(&mut self) {
|
||||||
d.clear_background(BG_DARK);
|
clear_background(BG_DARK);
|
||||||
|
|
||||||
let mut tooltip = Tooltip::default();
|
let mut tooltip = Tooltip::default();
|
||||||
tooltip.init_frame(d);
|
tooltip.init_frame();
|
||||||
|
|
||||||
d.draw_text(
|
draw_text(
|
||||||
TITLE_TEXT,
|
TITLE_TEXT,
|
||||||
d.get_screen_width() - 275,
|
screen_width() - 275.,
|
||||||
d.get_screen_height() - 20,
|
screen_height() - 20.,
|
||||||
20,
|
20.,
|
||||||
Color::GRAY,
|
colors::GRAY,
|
||||||
);
|
);
|
||||||
|
|
||||||
let level_list_width = (d.get_screen_width() / 3).min(400);
|
let level_list_width = (screen_width() / 3.).min(400.);
|
||||||
let screen_height = d.get_screen_height();
|
|
||||||
d.draw_rectangle(0, 0, level_list_width, screen_height, BG_MEDIUM);
|
draw_rectangle(0., 0., level_list_width, screen_height(), BG_MEDIUM);
|
||||||
|
|
||||||
if text_button(
|
if text_button(
|
||||||
d,
|
|
||||||
&self.globals.mouse,
|
&self.globals.mouse,
|
||||||
d.get_screen_width() - 100,
|
screen_width() - 100.,
|
||||||
d.get_screen_height() - 70,
|
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: i32 = 65;
|
const ENTRY_SPACING: f32 = 65.;
|
||||||
let fit_on_screen = (d.get_screen_height() / ENTRY_SPACING) as usize;
|
let fit_on_screen = (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 i32
|
.saturating_sub(fit_on_screen) as f32
|
||||||
* ENTRY_SPACING;
|
* ENTRY_SPACING;
|
||||||
if self.globals.mouse.pos().x < level_list_width as f32 {
|
if self.globals.mouse.pos().x < level_list_width {
|
||||||
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(5, y - 5, level_list_width - 10, ENTRY_SPACING - 5);
|
let bounds = Rect::new(5., y - 5., level_list_width - 10., ENTRY_SPACING - 5.);
|
||||||
d.draw_rectangle_rec(bounds, BG_DARK);
|
draw_rectangle_rec(bounds, BG_DARK);
|
||||||
d.draw_text(&chapter.title, 10, y, 30, FG_CHAPTER_TITLE);
|
draw_text(&chapter.title, 10., y, 30., FG_CHAPTER_TITLE);
|
||||||
let subtitle = format!("{} levels", chapter.levels.len());
|
let subtitle = format!("{} levels", chapter.levels.len());
|
||||||
d.draw_text(&subtitle, 10, y + 30, 20, Color::WHITE);
|
draw_text(&subtitle, 10., y + 30., 20., colors::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);
|
||||||
|
@ -177,7 +175,7 @@ impl Game {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (level_index, level) in chapter.levels.iter().enumerate() {
|
for (level_index, level) in chapter.levels.iter().enumerate() {
|
||||||
let bounds = rect(5, y - 5, level_list_width - 10, ENTRY_SPACING - 5);
|
let bounds = Rect::new(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);
|
||||||
|
|
||||||
|
@ -191,18 +189,18 @@ impl Game {
|
||||||
self.selected_solution = solutions.len().saturating_sub(1);
|
self.selected_solution = solutions.len().saturating_sub(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.draw_rectangle_rec(
|
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 = Color::WHITE;
|
let mut title_color = colors::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 = Color::LIGHTGREEN;
|
title_color = colors::GREEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.draw_text(level.name(), 10, y, 30, title_color);
|
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())
|
||||||
|
@ -210,11 +208,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 {
|
||||||
Color::GOLD
|
colors::GOLD
|
||||||
} else {
|
} else {
|
||||||
Color::LIGHTGRAY
|
colors::LIGHTGRAY
|
||||||
};
|
};
|
||||||
d.draw_text(&subtext, 10, y + 30, 20, subtext_color);
|
draw_text(&subtext, 10., y + 30., 20., subtext_color);
|
||||||
y += ENTRY_SPACING;
|
y += ENTRY_SPACING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,25 +222,31 @@ 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))
|
||||||
{
|
{
|
||||||
d.draw_text(level.name(), level_list_width + 10, 10, 40, Color::CYAN);
|
draw_text(
|
||||||
d.draw_text(level.id(), level_list_width + 10, 50, 10, Color::GRAY);
|
level.name(),
|
||||||
|
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(d, d.get_render_width() - level_list_width - 30);
|
.update_width(screen_width() - level_list_width - 30.);
|
||||||
self.level_desc_text.draw(d, level_list_width + 10, y);
|
self.level_desc_text.draw(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(
|
||||||
(d, &self.globals.mouse),
|
&self.globals.mouse,
|
||||||
rect(
|
Rect::new(
|
||||||
level_list_width + 10,
|
level_list_width + 10.,
|
||||||
solution_y,
|
solution_y,
|
||||||
entry_width,
|
entry_width,
|
||||||
solution_entry_height,
|
solution_entry_height,
|
||||||
|
@ -253,40 +257,39 @@ 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() {
|
||||||
Color::LIME
|
colors::LIME
|
||||||
} else {
|
} else {
|
||||||
Color::ORANGE
|
colors::ORANGE
|
||||||
};
|
};
|
||||||
d.draw_text(
|
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,
|
||||||
);
|
);
|
||||||
d.draw_text(
|
draw_text(
|
||||||
&solution.score_text(),
|
&solution.score_text(),
|
||||||
level_list_width + 15,
|
level_list_width + 15.,
|
||||||
solution_y + 25,
|
solution_y + 25.,
|
||||||
10,
|
10.,
|
||||||
Color::WHITE,
|
colors::WHITE,
|
||||||
);
|
);
|
||||||
if tex32_button(
|
if tex32_button(
|
||||||
(d, &self.globals.mouse),
|
&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",
|
||||||
|
@ -297,24 +300,23 @@ 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.;
|
||||||
d.draw_text(&text, x, y, 20, Color::ORANGE);
|
draw_text(&text, x, y, 20., colors::ORANGE);
|
||||||
if text_button(d, &self.globals.mouse, x, y + 30, 100, "yes") {
|
if text_button(&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(d, &self.globals.mouse, x + 110, y + 30, 100, "no") {
|
if text_button(&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 = Rectangle::new(column_x as f32, y as f32, 220., 30.);
|
let bounds = Rect::new(column_x, y, 220., 30.);
|
||||||
if text_input(
|
if text_input(
|
||||||
d,
|
|
||||||
&mut self.globals,
|
&mut self.globals,
|
||||||
bounds,
|
bounds,
|
||||||
&mut solution.name,
|
&mut solution.name,
|
||||||
|
@ -325,18 +327,18 @@ impl Game {
|
||||||
solution.save();
|
solution.save();
|
||||||
}
|
}
|
||||||
let id_text = format!("{}", solution.id());
|
let id_text = format!("{}", solution.id());
|
||||||
d.draw_text(&id_text, column_x, y + 35, 10, Color::GRAY);
|
draw_text(&id_text, column_x, y + 35., 10., colors::GRAY);
|
||||||
|
|
||||||
if text_button(d, &self.globals.mouse, column_x, y + 50, 220, "clone") {
|
if text_button(&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(d, &self.globals.mouse, column_x, y + 85, 220, "edit") {
|
if text_button(&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(d);
|
editor.center_view();
|
||||||
self.open_editor = Some(editor);
|
self.open_editor = Some(editor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +346,7 @@ impl Game {
|
||||||
self.solutions.insert(level.id().to_owned(), Vec::new());
|
self.solutions.insert(level.id().to_owned(), Vec::new());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tooltip.draw(d);
|
tooltip.draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_config(&self) {
|
fn save_config(&self) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use raylib::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod pos;
|
pub mod pos;
|
||||||
|
@ -99,26 +99,23 @@ impl Machine {
|
||||||
self.input = bytes;
|
self.input = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_marble_values(
|
pub fn draw_marble_values(&self, textures: &Textures, offset: Vec2, scale: f32) {
|
||||||
&self,
|
let tile_size = TILE_TEXTURE_SIZE * scale;
|
||||||
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 i32 * tile_size + offset.x as i32;
|
let px = x as f32 * tile_size + offset.x;
|
||||||
let py = y as i32 * tile_size + offset.y as i32;
|
let py = y as f32 * tile_size + offset.y;
|
||||||
if let Tile::Marble { value, dir } = tile {
|
if let Tile::Marble { value, dir } = tile {
|
||||||
let texture = textures.get(dir.arrow_texture_name());
|
let tex = textures.get(dir.arrow_texture_name());
|
||||||
let pos = Vector2::new(px as f32, py as f32);
|
let faded_white = Color::from_rgba(255, 255, 255, 100);
|
||||||
let faded_white = Color::new(255, 255, 255, 100);
|
let params = DrawTextureParams {
|
||||||
d.draw_texture_ex(texture, pos, 0., scale, faded_white);
|
dest_size: Some(Vec2::new(tex.width() * scale, tex.height() * scale)),
|
||||||
draw_usize_small(d, textures, value as usize, px, py, scale);
|
..Default::default()
|
||||||
|
};
|
||||||
|
draw_texture_ex(tex, px, py, faded_white, params);
|
||||||
|
draw_usize_small(textures, value as usize, px, py, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -544,10 +541,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 {
|
||||||
Comparison::LessThan => val_a < val_b,
|
Comp::LessThan => val_a < val_b,
|
||||||
Comparison::GreaterThan => val_a > val_b,
|
Comp::GreaterThan => val_a > val_b,
|
||||||
Comparison::Equal => val_a == val_b,
|
Comp::Equal => val_a == val_b,
|
||||||
Comparison::NotEqual => val_a != val_b,
|
Comp::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 raylib::prelude::*;
|
use macroquad::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use super::{tile::*, Pos, PosInt};
|
use super::{tile::*, Pos, PosInt};
|
||||||
|
@ -285,44 +285,43 @@ impl Grid {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub fn draw(&self, textures: &Textures, offset: Vec2, scale: f32, power_directions: bool) {
|
||||||
&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 = d.get_screen_width() / tile_size + 3;
|
let tiles_width = screen_width() as i32 / 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 = d.get_screen_height() / tile_size + 3;
|
let tiles_height = screen_height() as i32 / 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 + offset.x as i32;
|
let px = (x * tile_size) as f32 + offset.x;
|
||||||
let py = y * tile_size + offset.y as i32;
|
let py = (y * tile_size) as f32 + offset.y;
|
||||||
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(d, texture, px, py, scale);
|
draw_scaled_texture(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(d, texture, px, py, scale);
|
draw_scaled_texture(texture, px, py, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d.draw_rectangle(px, py, tile_size, tile_size, Color::new(0, 0, 0, 80));
|
draw_rectangle(
|
||||||
|
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 raylib::prelude::*;
|
use macroquad::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) -> Vector2 {
|
pub const fn to_vec(self) -> Vec2 {
|
||||||
Vector2 {
|
Vec2 {
|
||||||
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<Vector2> for Pos {
|
impl From<Vec2> for Pos {
|
||||||
fn from(vec: Vector2) -> Self {
|
fn from(vec: Vec2) -> 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(Comparison),
|
Comparator(Comp),
|
||||||
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 Comparison {
|
pub enum Comp {
|
||||||
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(Comparison::Equal), Power::OFF),
|
'=' => Tile::Powerable(PTile::Comparator(Comp::Equal), Power::OFF),
|
||||||
'!' => Tile::Powerable(PTile::Comparator(Comparison::NotEqual), Power::OFF),
|
'!' => Tile::Powerable(PTile::Comparator(Comp::NotEqual), Power::OFF),
|
||||||
'L' => Tile::Powerable(PTile::Comparator(Comparison::LessThan), Power::OFF),
|
'L' => Tile::Powerable(PTile::Comparator(Comp::LessThan), Power::OFF),
|
||||||
'G' => Tile::Powerable(PTile::Comparator(Comparison::GreaterThan), Power::OFF),
|
'G' => Tile::Powerable(PTile::Comparator(Comp::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 {
|
||||||
Comparison::LessThan => 'L',
|
Comp::LessThan => 'L',
|
||||||
Comparison::GreaterThan => 'G',
|
Comp::GreaterThan => 'G',
|
||||||
Comparison::Equal => '=',
|
Comp::Equal => '=',
|
||||||
Comparison::NotEqual => '!',
|
Comp::NotEqual => '!',
|
||||||
},
|
},
|
||||||
PTile::Math(math) => match math {
|
PTile::Math(math) => match math {
|
||||||
MathOp::Add => 'A',
|
MathOp::Add => 'A',
|
||||||
|
@ -453,49 +453,49 @@ impl MathOp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Comparison {
|
impl Comp {
|
||||||
pub const fn human_name(self) -> &'static str {
|
pub const fn human_name(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Comparison::LessThan => "Comparator: Less than",
|
Comp::LessThan => "Comparator: Less than",
|
||||||
Comparison::GreaterThan => "Comparator: Greater than",
|
Comp::GreaterThan => "Comparator: Greater than",
|
||||||
Comparison::Equal => "Comparator: Equal",
|
Comp::Equal => "Comparator: Equal",
|
||||||
Comparison::NotEqual => "Comparator: Not Equal",
|
Comp::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 {
|
||||||
Comparison::LessThan => "lt_on",
|
Comp::LessThan => "lt_on",
|
||||||
Comparison::GreaterThan => "gt_on",
|
Comp::GreaterThan => "gt_on",
|
||||||
Comparison::Equal => "eq_on",
|
Comp::Equal => "eq_on",
|
||||||
Comparison::NotEqual => "neq_on",
|
Comp::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 {
|
||||||
Comparison::LessThan => "lt_off",
|
Comp::LessThan => "lt_off",
|
||||||
Comparison::GreaterThan => "gt_off",
|
Comp::GreaterThan => "gt_off",
|
||||||
Comparison::Equal => "eq_off",
|
Comp::Equal => "eq_off",
|
||||||
Comparison::NotEqual => "neq_off",
|
Comp::NotEqual => "neq_off",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&mut self) {
|
pub fn next(&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Comparison::LessThan => Comparison::GreaterThan,
|
Comp::LessThan => Comp::GreaterThan,
|
||||||
Comparison::GreaterThan => Comparison::Equal,
|
Comp::GreaterThan => Comp::Equal,
|
||||||
Comparison::Equal => Comparison::NotEqual,
|
Comp::Equal => Comp::NotEqual,
|
||||||
Comparison::NotEqual => Comparison::LessThan,
|
Comp::NotEqual => Comp::LessThan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prev(&mut self) {
|
pub fn prev(&mut self) {
|
||||||
*self = match self {
|
*self = match self {
|
||||||
Comparison::LessThan => Comparison::NotEqual,
|
Comp::LessThan => Comp::NotEqual,
|
||||||
Comparison::GreaterThan => Comparison::LessThan,
|
Comp::GreaterThan => Comp::LessThan,
|
||||||
Comparison::Equal => Comparison::GreaterThan,
|
Comp::Equal => Comp::GreaterThan,
|
||||||
Comparison::NotEqual => Comparison::Equal,
|
Comp::NotEqual => Comp::Equal,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use raylib::prelude::*;
|
use macroquad::prelude::*;
|
||||||
|
|
||||||
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
pub const TILE_TEXTURE_SIZE: f32 = 16.0;
|
||||||
|
|
||||||
|
@ -12,6 +12,8 @@ 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 {
|
||||||
|
@ -22,9 +24,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::new(r, g, b, 255)
|
Color::from_rgba(r, g, b, 255)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn gray(value: u8) -> Color {
|
pub const fn gray(value: u8) -> Color {
|
||||||
Color::new(value, value, value, 255)
|
Color::from_rgba(value, value, value, 255)
|
||||||
}
|
}
|
||||||
|
|
294
src/ui.rs
294
src/ui.rs
|
@ -2,25 +2,25 @@ use std::ops::Range;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
theme::*,
|
theme::*,
|
||||||
util::{draw_scaled_texture, rect, MouseInput, Scroll, Textures},
|
util::{draw_rectangle_rec, draw_scaled_texture, MouseInput, Scroll, Textures},
|
||||||
Globals,
|
Globals,
|
||||||
};
|
};
|
||||||
use raylib::prelude::*;
|
use macroquad::{color::colors, prelude::*};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ShapedText {
|
pub struct ShapedText {
|
||||||
text: String,
|
text: String,
|
||||||
max_width: i32,
|
max_width: f32,
|
||||||
font_size: i32,
|
font_size: f32,
|
||||||
lines: Vec<Range<usize>>,
|
lines: Vec<Range<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ShapedText {
|
impl ShapedText {
|
||||||
pub fn new(font_size: i32) -> Self {
|
pub fn new(font_size: f32) -> 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) -> i32 {
|
pub fn height(&self) -> f32 {
|
||||||
self.font_size * self.lines.len() as i32
|
self.font_size * self.lines.len() as f32
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_width(&mut self, d: &RaylibHandle, width: i32) {
|
pub fn update_width(&mut self, width: f32) {
|
||||||
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 = d.measure_text(line, self.font_size);
|
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
||||||
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 = d.measure_text(line, self.font_size);
|
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
||||||
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 = d.measure_text(line, self.font_size);
|
let new_line_length = measure_text(line, None, self.font_size as _, 1.).width;
|
||||||
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, d: &mut RaylibDrawHandle, x: i32, y: i32) {
|
pub fn draw(&self, x: f32, y: f32) {
|
||||||
// d.draw_rectangle(x, y, self.max_width, 4, Color::RED);
|
// 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 i32;
|
let line_y = y + self.font_size * i as f32;
|
||||||
d.draw_text(line, x, line_y, self.font_size, Color::WHITE);
|
draw_text(line, x, line_y, self.font_size, colors::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: i32,
|
mouse_x: f32,
|
||||||
mouse_y: i32,
|
mouse_y: f32,
|
||||||
screen_width: i32,
|
screen_width: f32,
|
||||||
screen_height: i32,
|
screen_height: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tooltip {
|
impl Tooltip {
|
||||||
pub fn init_frame(&mut self, d: &RaylibHandle) {
|
pub fn init_frame(&mut self) {
|
||||||
let p = d.get_mouse_position();
|
let (mouse_x, mouse_y) = mouse_position();
|
||||||
*self = Self {
|
*self = Self {
|
||||||
text: None,
|
text: None,
|
||||||
mouse_x: p.x as i32,
|
mouse_x,
|
||||||
mouse_y: p.y as i32,
|
mouse_y,
|
||||||
screen_width: d.get_screen_width(),
|
screen_width: screen_width(),
|
||||||
screen_height: d.get_screen_height(),
|
screen_height: screen_height(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, x: i32, y: i32, width: i32, height: i32, text: &'static str) {
|
pub fn add(&mut self, x: f32, y: f32, width: f32, height: f32, 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,122 +127,91 @@ impl Tooltip {
|
||||||
self.text = None;
|
self.text = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_rec(&mut self, bounds: Rectangle, text: &'static str) {
|
pub fn add_rec(&mut self, bounds: Rect, text: &'static str) {
|
||||||
self.add(
|
self.add(bounds.x, bounds.y, bounds.w, bounds.h, text);
|
||||||
bounds.x as i32,
|
|
||||||
bounds.y as i32,
|
|
||||||
bounds.width as i32,
|
|
||||||
bounds.height as i32,
|
|
||||||
text,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&self, d: &mut RaylibDrawHandle) {
|
pub fn draw(&self) {
|
||||||
if let Some(text) = self.text {
|
if let Some(text) = self.text {
|
||||||
let font_size = 20;
|
let font_size = 20.0;
|
||||||
let margin = 4;
|
let margin = 4.0;
|
||||||
let text_width = d.measure_text(text, font_size);
|
let text_width = measure_text(text, None, font_size as _, 1.).width;
|
||||||
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.);
|
||||||
d.draw_rectangle(
|
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,
|
||||||
);
|
);
|
||||||
d.draw_text(text, x + margin, y + margin, font_size, Color::WHITE);
|
draw_text(text, x + margin, y + margin, font_size, colors::WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_button(
|
pub fn toggle_button(mouse: &MouseInput, x: f32, y: f32, width: f32, height: f32, val: &mut bool) {
|
||||||
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
let margin = 5.;
|
||||||
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(x, y, width, height);
|
let bounds = Rect::new(x, y, width, height);
|
||||||
|
|
||||||
let hover = bounds.check_collision_point_rec(mouse_pos);
|
let hover = bounds.contains(mouse_pos);
|
||||||
d.draw_rectangle(x, y, width, height, widget_bg(hover));
|
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 {
|
||||||
d.draw_rectangle(
|
draw_rectangle(
|
||||||
x + margin,
|
x + margin,
|
||||||
y + margin,
|
y + margin,
|
||||||
width - margin * 2,
|
width - margin * 2.,
|
||||||
height - margin * 2,
|
height - margin * 2.,
|
||||||
Color::WHITE,
|
colors::WHITE,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simple_button(
|
pub fn simple_button(mouse: &MouseInput, x: f32, y: f32, width: f32, height: f32) -> bool {
|
||||||
(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(x, y, width, height);
|
let bounds = Rect::new(x, y, width, height);
|
||||||
let hover = bounds.check_collision_point_rec(mouse_pos);
|
let hover = bounds.contains(mouse_pos);
|
||||||
let pressed = hover && mouse.left_click();
|
let pressed = hover && mouse.left_click();
|
||||||
d.draw_rectangle(x, y, width, height, widget_bg(hover));
|
draw_rectangle(x, y, width, height, widget_bg(hover));
|
||||||
pressed
|
pressed
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_button(
|
pub fn text_button(mouse: &MouseInput, x: f32, y: f32, width: f32, text: &str) -> bool {
|
||||||
d: &mut RaylibDrawHandle,
|
let font_size = 20.;
|
||||||
mouse: &MouseInput,
|
let margin = font_size / 4.;
|
||||||
x: i32,
|
let height = font_size + margin * 2.;
|
||||||
y: i32,
|
let clicked = simple_button(mouse, x, y, width, height);
|
||||||
width: i32,
|
draw_text(text, x + margin, y + margin, font_size, colors::WHITE);
|
||||||
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(
|
||||||
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
mouse: &MouseInput,
|
||||||
(x, y): (i32, i32),
|
(x, y): (f32, f32),
|
||||||
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((d, mouse), x, y, 32, 32);
|
let clicked = simple_button(mouse, x, y, size, size);
|
||||||
draw_scaled_texture(d, texture, x, y, 2.);
|
draw_scaled_texture(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>(
|
pub fn simple_option_button<T>(mouse: &MouseInput, bounds: Rect, option: T, current: &mut T) -> bool
|
||||||
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
|
||||||
bounds: Rectangle,
|
|
||||||
option: T,
|
|
||||||
current: &mut T,
|
|
||||||
) -> bool
|
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
d.draw_rectangle_rec(bounds, widget_bg(&option == current));
|
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;
|
||||||
|
@ -252,42 +221,33 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_input(
|
pub fn text_input(
|
||||||
d: &mut RaylibDrawHandle,
|
|
||||||
globals: &mut Globals,
|
globals: &mut Globals,
|
||||||
bounds: Rectangle,
|
bounds: Rect,
|
||||||
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.;
|
||||||
d.draw_rectangle_rec(bounds, widget_bg(*is_selected));
|
draw_rectangle_rec(bounds, widget_bg(*is_selected));
|
||||||
d.draw_rectangle_rec(
|
draw_rectangle(
|
||||||
Rectangle::new(
|
|
||||||
bounds.x + 2.,
|
bounds.x + 2.,
|
||||||
bounds.y + bounds.height - 5.,
|
bounds.y + bounds.h - 5.,
|
||||||
bounds.width - 4.,
|
bounds.w - 4.,
|
||||||
3.,
|
3.,
|
||||||
),
|
|
||||||
BG_DARK,
|
BG_DARK,
|
||||||
);
|
);
|
||||||
d.draw_text(
|
draw_text(text, bounds.x + 4., bounds.y + 4., font_size, colors::WHITE);
|
||||||
text,
|
|
||||||
bounds.x as i32 + 4,
|
|
||||||
bounds.y as i32 + 4,
|
|
||||||
font_size,
|
|
||||||
Color::WHITE,
|
|
||||||
);
|
|
||||||
// blinking cursor
|
// blinking cursor
|
||||||
if *is_selected && d.get_time().fract() < 0.5 {
|
if *is_selected && get_time().fract() < 0.5 {
|
||||||
let width = d.measure_text(text, font_size);
|
let width = measure_text(text, None, font_size as _, 1.).width;
|
||||||
d.draw_rectangle(
|
draw_rectangle(
|
||||||
bounds.x as i32 + 6 + width,
|
bounds.x + 6. + width,
|
||||||
bounds.y as i32 + 4,
|
bounds.y + 4.,
|
||||||
2,
|
2.,
|
||||||
font_size,
|
font_size,
|
||||||
Color::WHITE,
|
colors::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) {
|
||||||
|
@ -296,13 +256,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 d.is_key_pressed(KeyboardKey::KEY_ESCAPE) || d.is_key_pressed(KeyboardKey::KEY_ENTER) {
|
if is_key_pressed(KeyCode::Escape) || is_key_pressed(KeyCode::Enter) {
|
||||||
*is_selected = false;
|
*is_selected = false;
|
||||||
}
|
}
|
||||||
if d.is_key_pressed(KeyboardKey::KEY_BACKSPACE) && !text.is_empty() {
|
if is_key_pressed(KeyCode::Backspace) && !text.is_empty() {
|
||||||
changed = true;
|
changed = true;
|
||||||
text.pop();
|
text.pop();
|
||||||
if d.is_key_down(KeyboardKey::KEY_LEFT_CONTROL) {
|
if is_key_down(KeyCode::LeftControl) {
|
||||||
while let Some(c) = text.pop() {
|
while let Some(c) = text.pop() {
|
||||||
if c == ' ' {
|
if c == ' ' {
|
||||||
break;
|
break;
|
||||||
|
@ -311,12 +271,7 @@ pub fn text_input(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if text.len() < max_len {
|
if text.len() < max_len {
|
||||||
let char_code = unsafe { ffi::GetCharPressed() };
|
let c = get_char_pressed();
|
||||||
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);
|
||||||
|
@ -327,8 +282,8 @@ pub fn text_input(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scrollable_texture_option_button<T>(
|
pub fn scrollable_texture_option_button<T>(
|
||||||
(d, mouse): (&mut RaylibDrawHandle, &MouseInput),
|
mouse: &MouseInput,
|
||||||
pos: Vector2,
|
pos: Vec2,
|
||||||
texture: &Texture2D,
|
texture: &Texture2D,
|
||||||
option: T,
|
option: T,
|
||||||
current: &mut T,
|
current: &mut T,
|
||||||
|
@ -338,13 +293,8 @@ pub fn scrollable_texture_option_button<T>(
|
||||||
where
|
where
|
||||||
T: PartialEq,
|
T: PartialEq,
|
||||||
{
|
{
|
||||||
let bounds = Rectangle {
|
let bounds = Rect::new(pos.x, pos.y, 32. + border * 2., 32. + border * 2.);
|
||||||
x: pos.x,
|
draw_rectangle_rec(
|
||||||
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
|
||||||
|
@ -352,12 +302,16 @@ where
|
||||||
gray(16)
|
gray(16)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
d.draw_texture_ex(
|
let params = DrawTextureParams {
|
||||||
|
dest_size: Some(Vec2::splat(32.)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
draw_texture_ex(
|
||||||
texture,
|
texture,
|
||||||
pos + Vector2::new(border, border),
|
pos.x + border,
|
||||||
0.,
|
pos.y + border,
|
||||||
32. / texture.width as f32,
|
colors::WHITE,
|
||||||
Color::WHITE,
|
params,
|
||||||
);
|
);
|
||||||
if clicked_override {
|
if clicked_override {
|
||||||
*current = option;
|
*current = option;
|
||||||
|
@ -371,34 +325,32 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_usize(
|
pub fn draw_usize(
|
||||||
d: &mut RaylibDrawHandle,
|
|
||||||
textures: &Textures,
|
textures: &Textures,
|
||||||
mut number: usize,
|
mut number: usize,
|
||||||
(x, y): (i32, i32),
|
(x, y): (f32, f32),
|
||||||
digits: i32,
|
digits: u8,
|
||||||
scale: i32,
|
scale: f32,
|
||||||
) {
|
) {
|
||||||
for i in 0..digits {
|
for i in 0..digits {
|
||||||
d.draw_rectangle(x + 10 * i * scale, y, 8 * scale, 16 * scale, BG_LIGHT);
|
draw_rectangle(
|
||||||
|
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) * 10 * scale;
|
let x = x + (digits - i - 1) as f32 * 10. * scale;
|
||||||
draw_scaled_texture(d, texture, x, y, scale as f32);
|
draw_scaled_texture(texture, x, y, scale);
|
||||||
number /= 10;
|
number /= 10;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_usize_small(
|
pub fn draw_usize_small(textures: &Textures, mut num: usize, mut x: f32, y: f32, scale: f32) {
|
||||||
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;
|
||||||
|
@ -409,31 +361,29 @@ pub fn draw_usize_small(
|
||||||
}
|
}
|
||||||
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 = Rectangle::new(4. * digit as f32, 0., 4., 6.);
|
let source = Rect::new(4. * digit as f32, 0., 4., 6.);
|
||||||
let dest = Rectangle::new(x as f32, y as f32, 4. * scale, 6. * scale);
|
let params = DrawTextureParams {
|
||||||
d.draw_texture_pro(texture, source, dest, Vector2::zero(), 0., FG_MARBLE_VALUE);
|
dest_size: Some(Vec2::new(4. * scale, 6. * scale)),
|
||||||
x += 4 * scale as i32;
|
source: Some(source),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
draw_texture_ex(texture, x, y, FG_MARBLE_VALUE, params);
|
||||||
|
x += 4. * scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slider(
|
pub fn slider(mouse: &MouseInput, bounds: Rect, value: &mut u8, min: u8, max: u8) -> bool {
|
||||||
(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;
|
||||||
d.draw_rectangle_rec(bounds, BG_WIDGET);
|
draw_rectangle_rec(bounds, BG_WIDGET);
|
||||||
let mut filled_bounds = bounds;
|
let mut filled_bounds = bounds;
|
||||||
filled_bounds.width *= percent;
|
filled_bounds.w *= percent;
|
||||||
d.draw_rectangle_rec(filled_bounds, Color::CYAN);
|
draw_rectangle_rec(filled_bounds, SLIDER_FILL);
|
||||||
// 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.width;
|
let percent = (mouse.pos().x - bounds.x) / bounds.w;
|
||||||
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 raylib::prelude::*;
|
use macroquad::{color::colors, prelude::*};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Textures {
|
pub struct Textures {
|
||||||
|
@ -8,14 +8,13 @@ pub struct Textures {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Textures {
|
impl Textures {
|
||||||
pub fn load_dir(&mut self, folder: &str, rl: &mut RaylibHandle, thread: &RaylibThread) {
|
pub async fn load_dir(&mut self, folder: &str) {
|
||||||
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
|
|
||||||
.load_texture(thread, &format!("{folder}/{name}.png"))
|
let texture = load_texture(&format!("{folder}/{name}.png")).await.unwrap();
|
||||||
.unwrap();
|
|
||||||
self.map.insert(name.to_string(), texture);
|
self.map.insert(name.to_string(), texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,15 +31,24 @@ pub fn userdata_dir() -> PathBuf {
|
||||||
PathBuf::from("user")
|
PathBuf::from("user")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_scaled_texture(
|
pub fn draw_rectangle_rec(bounds: Rect, color: Color) {
|
||||||
d: &mut RaylibDrawHandle,
|
draw_rectangle(bounds.x, bounds.y, bounds.w, bounds.h, color);
|
||||||
texture: &Texture2D,
|
}
|
||||||
x: i32,
|
|
||||||
y: i32,
|
pub fn draw_scaled_texture_c(texture: &Texture2D, x: f32, y: f32, scale: f32, color: Color) {
|
||||||
scale: f32,
|
let params = DrawTextureParams {
|
||||||
) {
|
dest_size: Some(Vec2::new(texture.width() * scale, texture.height() * scale)),
|
||||||
let pos = Vector2::new(x as f32, y as f32);
|
..Default::default()
|
||||||
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 {
|
||||||
|
@ -51,31 +59,21 @@ pub fn get_free_id<T>(items: &[T], id_fn: fn(&T) -> usize) -> usize {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn screen_centered_rect(rl: &RaylibHandle, width: i32, height: i32) -> Rectangle {
|
pub fn screen_centered_rect(width: f32, height: f32) -> Rect {
|
||||||
let w = rl.get_screen_width();
|
let w = screen_width();
|
||||||
let h = rl.get_screen_height();
|
let h = screen_height();
|
||||||
Rectangle {
|
Rect::new(w / 2. - width / 2., h / 2. - height / 2., width, height)
|
||||||
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(rl: &RaylibHandle, margin_x: i32, margin_y: i32) -> Rectangle {
|
pub fn screen_centered_rect_dyn(margin_x: f32, margin_y: f32) -> Rect {
|
||||||
let w = rl.get_screen_width();
|
let w = screen_width();
|
||||||
let h = rl.get_screen_height();
|
let h = screen_height();
|
||||||
Rectangle {
|
Rect::new(margin_x, margin_y, w - margin_x * 2., h - margin_y * 2.)
|
||||||
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: Vector2,
|
pos: Vec2,
|
||||||
left_click: bool,
|
left_click: bool,
|
||||||
left_hold: bool,
|
left_hold: bool,
|
||||||
left_release: bool,
|
left_release: bool,
|
||||||
|
@ -84,24 +82,24 @@ pub struct MouseInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MouseInput {
|
impl MouseInput {
|
||||||
pub fn update(&mut self, rl: &RaylibHandle) {
|
pub fn update(&mut self) {
|
||||||
self.pos = rl.get_mouse_position();
|
self.pos = mouse_position().into();
|
||||||
self.left_click = rl.is_mouse_button_pressed(MouseButton::MOUSE_BUTTON_LEFT);
|
self.left_click = is_mouse_button_pressed(MouseButton::Left);
|
||||||
self.left_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT);
|
self.left_hold = is_mouse_button_down(MouseButton::Left);
|
||||||
self.left_release = rl.is_mouse_button_released(MouseButton::MOUSE_BUTTON_LEFT);
|
self.left_release = is_mouse_button_released(MouseButton::Left);
|
||||||
self.right_hold = rl.is_mouse_button_down(MouseButton::MOUSE_BUTTON_RIGHT);
|
self.right_hold = is_mouse_button_down(MouseButton::Right);
|
||||||
self.scroll = get_scroll(rl);
|
self.scroll = get_scroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_over(&self, rect: Rectangle) -> bool {
|
pub fn is_over(&self, rect: Rect) -> bool {
|
||||||
rect.check_collision_point_rec(self.pos)
|
rect.contains(self.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
*self = Self::default();
|
*self = Self::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pos(&self) -> Vector2 {
|
pub fn pos(&self) -> Vec2 {
|
||||||
self.pos
|
self.pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +130,9 @@ pub enum Scroll {
|
||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_scroll(rl: &RaylibHandle) -> Option<Scroll> {
|
pub fn get_scroll() -> Option<Scroll> {
|
||||||
const SCROLL_THRESHOLD: f32 = 0.5;
|
const SCROLL_THRESHOLD: f32 = 0.5;
|
||||||
let value = rl.get_mouse_wheel_move();
|
let value = mouse_wheel().0;
|
||||||
if value > SCROLL_THRESHOLD {
|
if value > SCROLL_THRESHOLD {
|
||||||
Some(Scroll::Up)
|
Some(Scroll::Up)
|
||||||
} else if value < -SCROLL_THRESHOLD {
|
} else if value < -SCROLL_THRESHOLD {
|
||||||
|
@ -143,7 +141,3 @@ pub fn get_scroll(rl: &RaylibHandle) -> 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