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