mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
47 Commits
908f0d01a6
...
devel
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e512d0e2a0 | ||
|
|
8161005096 | ||
|
|
ad073c10ff | ||
|
|
475f321100 | ||
|
|
6330b6b3b0 | ||
|
|
99ec1e8bcf | ||
|
|
c2a3310891 | ||
|
|
024d41727f | ||
|
|
7d55a2675b | ||
|
|
37fad1741e | ||
|
|
8867749e0e | ||
|
|
d890461777 | ||
|
|
bcdbc45931 | ||
|
|
b97242981c | ||
|
|
1d10f99e77 | ||
|
|
5901a4b4d9 | ||
|
|
9cd14d108c | ||
|
|
5d4b164b3b | ||
|
|
bbd8e775f1 | ||
|
|
90af90850a | ||
|
|
58db410ba4 | ||
|
|
fc75b88fab | ||
|
|
1727bf5f45 | ||
|
|
01ed547374 | ||
|
|
20d343a984 | ||
|
|
2ea2cec172 | ||
|
|
269041a7c6 | ||
|
|
6e83884c0a | ||
|
|
7edb77b41f | ||
|
|
737ffa522c | ||
|
|
0311cfb1f9 | ||
|
|
b0ee27fb74 | ||
|
|
d4eca0c93e | ||
|
|
a9f4aac875 | ||
|
|
8377056580 | ||
|
|
d541581012 | ||
|
|
72ef6dea07 | ||
|
|
bfadc39400 | ||
|
|
754d82d031 | ||
|
|
8ae072ea82 | ||
|
|
cec2168591 | ||
|
|
8d6acc5975 | ||
|
|
b20ecf5378 | ||
|
|
ade839e981 | ||
|
|
d625c279a6 | ||
|
|
5ea14be3fa | ||
|
|
64c2e55db4 |
@@ -8,6 +8,9 @@ indent_style = space
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.slint]
|
||||
indent_size = 4
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -10,7 +10,6 @@ vendor_*
|
||||
.~lock.*
|
||||
*.ods#
|
||||
*.patch
|
||||
*.log
|
||||
|
||||
# gnome extension
|
||||
node-modules
|
||||
@@ -21,3 +20,8 @@ desktop-extensions/gnome*/@types/gir-generated
|
||||
desktop-extensions/gnome*/node_modules
|
||||
desktop-extensions/gnome*/schemas/gschemas.compiled
|
||||
desktop-extensions/gnome*/*.zip
|
||||
|
||||
# agents and reference
|
||||
CLAUDE.md
|
||||
AGENTS.md
|
||||
/reference
|
||||
|
||||
@@ -90,7 +90,7 @@ pages:
|
||||
- rm -rf public
|
||||
- mkdir public
|
||||
- cp -R ci-target/doc/* public
|
||||
- cp extra/index.html public
|
||||
- if [ -f extra/index.html ]; then cp extra/index.html public; else echo "no extra/index.html to copy"; fi
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,5 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changes
|
||||
- Fix PPT sliders not updating
|
||||
|
||||
## [6.3.2]
|
||||
|
||||
### Changes
|
||||
- Improve the notification area, @shevchenko0013 strikes again!
|
||||
- Improve firmware attributes handling
|
||||
- Very good looking UI restyling from @shevchenko0013
|
||||
- Added support for GA402NV matrix: thanks @Ghoul4500
|
||||
- Fixed aura CLI interface
|
||||
- Fixed LEDs handling in rogcc
|
||||
|
||||
## [6.3.1]
|
||||
|
||||
### Changes
|
||||
- Removed a lighting mode that is unavailable in windows to G835L: thanks to @shevchenko0013 again!
|
||||
- Added translations for Ukranian language, thanks @shevchenko0013!
|
||||
- Added LEDs definition for G615LR, thanks @btnrv
|
||||
- Fix improper usage of Quiet when only LowPower is available
|
||||
|
||||
## [6.3.0]
|
||||
|
||||
### Changed
|
||||
|
||||
319
Cargo.lock
generated
319
Cargo.lock
generated
@@ -212,7 +212,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusctl"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"dmi_id",
|
||||
@@ -232,7 +232,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusd"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"cargo-husky",
|
||||
"concat-idents",
|
||||
@@ -259,7 +259,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusd-user"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"config-traits",
|
||||
"dirs",
|
||||
@@ -488,7 +488,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"pastey 0.1.1",
|
||||
"rayon",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"y4m",
|
||||
]
|
||||
@@ -816,9 +816,9 @@ checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.52"
|
||||
version = "1.2.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
|
||||
checksum = "6354c81bbfd62d9cfa9cb3c773c2b7b2a3a482d569de977fd0e961f6e7c00583"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -864,9 +864,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.42"
|
||||
version = "0.4.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||
checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
@@ -938,7 +938,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "config-traits"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ron",
|
||||
@@ -987,7 +987,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "const-field-offset"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"const-field-offset-macro",
|
||||
"field-offset",
|
||||
@@ -996,7 +996,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "const-field-offset-macro"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1036,16 +1036,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
@@ -1059,7 +1049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
@@ -1072,7 +1062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -1274,7 +1264,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "dmi_id"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"udev 0.8.0",
|
||||
@@ -1422,9 +1412,9 @@ checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.11"
|
||||
version = "0.22.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48"
|
||||
checksum = "df61bf483e837f88d5c2291dcf55c67be7e676b3a51acc48db3a7b163b91ed63"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
@@ -1502,9 +1492,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "femtovg"
|
||||
version = "0.19.3"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be5d925785ad33d7b0ae2b445d9f157c3ab42ff3c515fff0b46d53d4a86c43c5"
|
||||
checksum = "a125295d4de2b2473e731c4612599ba3cdf7e05af6bba16f324ba8ffbf093436"
|
||||
dependencies = [
|
||||
"bitflags 2.10.0",
|
||||
"bytemuck",
|
||||
@@ -1533,21 +1523,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.26"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
|
||||
checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
|
||||
checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
@@ -1631,7 +1620,7 @@ dependencies = [
|
||||
"objc2-core-text",
|
||||
"objc2-foundation 0.3.2",
|
||||
"read-fonts",
|
||||
"roxmltree 0.21.1",
|
||||
"roxmltree",
|
||||
"smallvec",
|
||||
"windows 0.58.0",
|
||||
"windows-core 0.58.0",
|
||||
@@ -1870,16 +1859,6 @@ dependencies = [
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
|
||||
dependencies = [
|
||||
"color_quant",
|
||||
"weezl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gif"
|
||||
version = "0.14.1"
|
||||
@@ -2237,7 +2216,7 @@ dependencies = [
|
||||
"hyper",
|
||||
"libc",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
@@ -2246,7 +2225,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-backend-linuxkms"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"calloop 0.14.3",
|
||||
"drm",
|
||||
@@ -2264,7 +2243,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-backend-selector"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"i-slint-backend-linuxkms",
|
||||
@@ -2277,7 +2256,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-backend-winit"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"block2 0.6.2",
|
||||
"cfg-if",
|
||||
@@ -2316,7 +2295,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-common"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"fontique",
|
||||
"ttf-parser 0.25.1",
|
||||
@@ -2325,7 +2304,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-compiler"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"annotate-snippets",
|
||||
"by_address",
|
||||
@@ -2353,7 +2332,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-core"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"auto_enums",
|
||||
"bitflags 2.10.0",
|
||||
@@ -2388,7 +2367,7 @@ dependencies = [
|
||||
"slab",
|
||||
"strum",
|
||||
"sys-locale",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"unicode-linebreak",
|
||||
"unicode-script",
|
||||
"unicode-segmentation",
|
||||
@@ -2396,13 +2375,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
"web-time",
|
||||
"webbrowser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "i-slint-core-macros"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"serde_json",
|
||||
@@ -2412,7 +2390,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-renderer-femtovg"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"const-field-offset",
|
||||
@@ -2434,7 +2412,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-renderer-skia"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cfg-if",
|
||||
@@ -2469,7 +2447,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "i-slint-renderer-software"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"clru",
|
||||
@@ -2632,8 +2610,8 @@ dependencies = [
|
||||
"rayon",
|
||||
"rgb",
|
||||
"tiff",
|
||||
"zune-core 0.5.0",
|
||||
"zune-jpeg 0.5.8",
|
||||
"zune-core 0.5.1",
|
||||
"zune-jpeg 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2648,9 +2626,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "imagesize"
|
||||
version = "0.13.0"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285"
|
||||
checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c"
|
||||
|
||||
[[package]]
|
||||
name = "imgref"
|
||||
@@ -2819,9 +2797,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.83"
|
||||
version = "0.3.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8"
|
||||
checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
@@ -2864,9 +2842,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kurbo"
|
||||
version = "0.11.3"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62"
|
||||
checksum = "ce9729cc38c18d86123ab736fd2e7151763ba226ac2490ec092d1dd148825e32"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"euclid",
|
||||
@@ -2875,9 +2853,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "kurbo"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce9729cc38c18d86123ab736fd2e7151763ba226ac2490ec092d1dd148825e32"
|
||||
checksum = "7564e90fe3c0d5771e1f0bc95322b21baaeaa0d9213fa6a0b61c99f8b17b3bfb"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"euclid",
|
||||
@@ -2924,9 +2902,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@@ -3244,7 +3222,7 @@ dependencies = [
|
||||
"objc2-foundation 0.3.2",
|
||||
"once_cell",
|
||||
"png 0.17.16",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
@@ -3360,9 +3338,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
@@ -4095,9 +4073,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.105"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -4216,9 +4194,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.43"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
@@ -4318,7 +4296,7 @@ dependencies = [
|
||||
"rand 0.9.2",
|
||||
"rand_chacha 0.9.0",
|
||||
"simd_helpers",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"v_frame",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -4456,11 +4434,11 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
||||
|
||||
[[package]]
|
||||
name = "resvg"
|
||||
version = "0.45.1"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8928798c0a55e03c9ca6c4c6846f76377427d2c1e1f7e6de3c06ae57942df43"
|
||||
checksum = "b563218631706d614e23059436526d005b50ab5f2d506b55a17eb65c5eb83419"
|
||||
dependencies = [
|
||||
"gif 0.13.3",
|
||||
"gif 0.14.1",
|
||||
"image-webp",
|
||||
"log",
|
||||
"pico-args",
|
||||
@@ -4468,7 +4446,7 @@ dependencies = [
|
||||
"svgtypes",
|
||||
"tiny-skia",
|
||||
"usvg",
|
||||
"zune-jpeg 0.4.21",
|
||||
"zune-jpeg 0.5.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4482,7 +4460,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog-control-center"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"asusd",
|
||||
"concat-idents",
|
||||
@@ -4502,8 +4480,6 @@ dependencies = [
|
||||
"rog_dbus",
|
||||
"rog_platform",
|
||||
"rog_profiles",
|
||||
"rog_slash",
|
||||
"ron",
|
||||
"serde",
|
||||
"slint",
|
||||
"slint-build",
|
||||
@@ -4515,7 +4491,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_anime"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"dmi_id",
|
||||
"gif 0.12.0",
|
||||
@@ -4529,7 +4505,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_aura"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"dmi_id",
|
||||
"log",
|
||||
@@ -4540,7 +4516,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_dbus"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"asusd",
|
||||
"rog_anime",
|
||||
@@ -4554,7 +4530,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_platform"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"concat-idents",
|
||||
"inotify",
|
||||
@@ -4567,7 +4543,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_profiles"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rog_platform",
|
||||
@@ -4578,7 +4554,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_scsi"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"ron",
|
||||
"serde",
|
||||
@@ -4588,7 +4564,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_simulators"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rog_anime",
|
||||
@@ -4598,7 +4574,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rog_slash"
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
dependencies = [
|
||||
"dmi_id",
|
||||
"serde",
|
||||
@@ -4631,12 +4607,6 @@ dependencies = [
|
||||
"text-size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
|
||||
|
||||
[[package]]
|
||||
name = "roxmltree"
|
||||
version = "0.21.1"
|
||||
@@ -4926,9 +4896,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
|
||||
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
||||
|
||||
[[package]]
|
||||
name = "skia-bindings"
|
||||
@@ -4977,7 +4947,7 @@ checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
|
||||
[[package]]
|
||||
name = "slint"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"const-field-offset",
|
||||
"i-slint-backend-selector",
|
||||
@@ -4997,7 +4967,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "slint-build"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"i-slint-compiler",
|
||||
@@ -5008,7 +4978,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "slint-macros"
|
||||
version = "1.15.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"i-slint-compiler",
|
||||
"proc-macro2",
|
||||
@@ -5070,7 +5040,7 @@ dependencies = [
|
||||
"log",
|
||||
"memmap2",
|
||||
"rustix 1.1.3",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
"wayland-csd-frame",
|
||||
@@ -5142,9 +5112,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
||||
checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
@@ -5244,11 +5214,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "svgtypes"
|
||||
version = "0.15.3"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc"
|
||||
checksum = "695b5790b3131dafa99b3bbfd25a216edb3d216dad9ca208d4657bfb8f2abc3d"
|
||||
dependencies = [
|
||||
"kurbo 0.11.3",
|
||||
"kurbo 0.13.0",
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
@@ -5332,7 +5302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b1e66e07de489fe43a46678dd0b8df65e0c973909df1b60ba33874e297ba9b9"
|
||||
dependencies = [
|
||||
"quick-xml 0.37.5",
|
||||
"thiserror 2.0.17",
|
||||
"thiserror 2.0.18",
|
||||
"windows 0.61.3",
|
||||
"windows-version",
|
||||
]
|
||||
@@ -5382,11 +5352,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.17"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl 2.0.17",
|
||||
"thiserror-impl 2.0.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5402,9 +5372,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.17"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5436,9 +5406,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.45"
|
||||
version = "0.3.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
|
||||
checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"num-conv",
|
||||
@@ -5449,9 +5419,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.7"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "tiny-skia"
|
||||
@@ -5528,7 +5498,7 @@ dependencies = [
|
||||
"libc",
|
||||
"mio 1.1.1",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.61.2",
|
||||
@@ -5780,9 +5750,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "typed-index-collections"
|
||||
version = "3.4.0"
|
||||
version = "3.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5318ee4ce62a4e948a33915574021a7a953d83e84fba6e25c72ffcfd7dad35ff"
|
||||
checksum = "898160f1dfd383b4e92e17f0512a7d62f3c51c44937b23b6ffc3a1614a8eaccd"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"serde",
|
||||
@@ -5942,19 +5912,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.45.1"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80be9b06fbae3b8b303400ab20778c80bbaf338f563afe567cf3c9eea17b47ef"
|
||||
checksum = "e419dff010bb12512b0ae9e3d2f318dfbdf0167fde7eb05465134d4e8756076f"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"data-url",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
"imagesize",
|
||||
"kurbo 0.11.3",
|
||||
"kurbo 0.13.0",
|
||||
"log",
|
||||
"pico-args",
|
||||
"roxmltree 0.20.0",
|
||||
"roxmltree",
|
||||
"rustybuzz",
|
||||
"simplecss",
|
||||
"siphasher",
|
||||
@@ -5975,9 +5945,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.19.0"
|
||||
version = "1.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
|
||||
checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde_core",
|
||||
@@ -6032,7 +6002,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "vtable"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"const-field-offset",
|
||||
"portable-atomic",
|
||||
@@ -6043,7 +6013,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "vtable-macro"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f181d5e7b200b8986ba856fa0574425e0d6389aa"
|
||||
source = "git+https://github.com/slint-ui/slint.git#f55d24727b3917ad6953f89a1dd32b48556b290e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -6077,18 +6047,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
version = "1.0.2+wasi-0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.106"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd"
|
||||
checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
@@ -6099,11 +6069,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.56"
|
||||
version = "0.4.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c"
|
||||
checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
@@ -6112,9 +6083,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.106"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3"
|
||||
checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -6122,9 +6093,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.106"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40"
|
||||
checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
@@ -6135,9 +6106,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.106"
|
||||
version = "0.2.108"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4"
|
||||
checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -6279,9 +6250,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.83"
|
||||
version = "0.3.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac"
|
||||
checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -6297,22 +6268,6 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webbrowser"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97"
|
||||
dependencies = [
|
||||
"core-foundation 0.10.1",
|
||||
"jni",
|
||||
"log",
|
||||
"ndk-context",
|
||||
"objc2 0.6.3",
|
||||
"objc2-foundation 0.3.2",
|
||||
"url",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "weezl"
|
||||
version = "0.1.12"
|
||||
@@ -6934,7 +6889,7 @@ dependencies = [
|
||||
"calloop 0.13.0",
|
||||
"cfg_aliases",
|
||||
"concurrent-queue",
|
||||
"core-foundation 0.9.4",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"cursor-icon",
|
||||
"dpi",
|
||||
@@ -6982,9 +6937,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
|
||||
[[package]]
|
||||
name = "write-fonts"
|
||||
@@ -7153,9 +7108,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "5.13.1"
|
||||
version = "5.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f79257df967b6779afa536788657777a0001f5b42524fcaf5038d4344df40b"
|
||||
checksum = "1bfeff997a0aaa3eb20c4652baf788d2dfa6d2839a0ead0b3ff69ce2f9c4bdd1"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-executor",
|
||||
@@ -7188,9 +7143,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "5.13.1"
|
||||
version = "5.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad23e2d2f91cae771c7af7a630a49e755f1eb74f8a46e9f6d5f7a146edf5a37"
|
||||
checksum = "0bbd5a90dbe8feee5b13def448427ae314ccd26a49cac47905cafefb9ff846f1"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
@@ -7220,18 +7175,18 @@ checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.33"
|
||||
version = "0.8.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd"
|
||||
checksum = "71ddd76bcebeed25db614f82bf31a9f4222d3fbba300e6fb6c00afa26cbd4d9d"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.33"
|
||||
version = "0.8.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1"
|
||||
checksum = "d8187381b52e32220d50b255276aa16a084ec0a9017a0ca2152a1f55c539758d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -7295,9 +7250,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.14"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea"
|
||||
checksum = "02aae0f83f69aafc94776e879363e9771d7ecbffe2c7fbb6c14c5e00dfe88439"
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
@@ -7307,9 +7262,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
||||
|
||||
[[package]]
|
||||
name = "zune-core"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773"
|
||||
checksum = "cb8a0807f7c01457d0379ba880ba6322660448ddebc890ce29bb64da71fb40f9"
|
||||
|
||||
[[package]]
|
||||
name = "zune-inflate"
|
||||
@@ -7331,18 +7286,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.5.8"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e35aee689668bf9bd6f6f3a6c60bb29ba1244b3b43adfd50edd554a371da37d5"
|
||||
checksum = "2959ca473aae96a14ecedf501d20b3608d2825ba280d5adb57d651721885b0c2"
|
||||
dependencies = [
|
||||
"zune-core 0.5.0",
|
||||
"zune-core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zvariant"
|
||||
version = "5.9.1"
|
||||
version = "5.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "326aaed414f04fe839777b4c443d4e94c74e7b3621093bd9c5e649ac8aa96543"
|
||||
checksum = "68b64ef4f40c7951337ddc7023dd03528a57a3ce3408ee9da5e948bd29b232c4"
|
||||
dependencies = [
|
||||
"endi",
|
||||
"enumflags2",
|
||||
@@ -7354,9 +7309,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zvariant_derive"
|
||||
version = "5.9.1"
|
||||
version = "5.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba44e1f8f4da9e6e2d25d2a60b116ef8b9d0be174a7685e55bb12a99866279a7"
|
||||
checksum = "484d5d975eb7afb52cc6b929c13d3719a20ad650fea4120e6310de3fc55e415c"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace.package]
|
||||
version = "6.3.0"
|
||||
version = "6.3.2"
|
||||
rust-version = "1.82"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
@@ -40,9 +40,6 @@ tokio = { version = "^1.39.0", default-features = false, features = [
|
||||
"time",
|
||||
"rt",
|
||||
"rt-multi-thread",
|
||||
"fs",
|
||||
"io-util",
|
||||
"io-util",
|
||||
] }
|
||||
concat-idents = "^1.1"
|
||||
dirs = "^4.0"
|
||||
|
||||
@@ -13,9 +13,7 @@ Now includes a GUI, `rog-control-center`.
|
||||
|
||||
Due to on-going driver work the minimum suggested kernel version is always **the latest*, as improvements and fixes are continuous.
|
||||
|
||||
Support for some new features is not avilable unless you run a patched kernel with the work I am doing [in this github repo](https://github.com/flukejones/linux/tree/wip/ally-6.13). Use the linked branch, or `wip/ally-6.12`. Everything that is done here is upstreamed eventually (a long process).
|
||||
|
||||
Z13 devices will need [these](https://lore.kernel.org/linux-input/20240416090402.31057-1-luke@ljones.dev/T/#t)
|
||||
Support for TDP is tied to the new asus-armoury driver: available mainline since linux 6.19: everything older is not supported.
|
||||
|
||||
## X11 support
|
||||
|
||||
@@ -180,3 +178,7 @@ Reference to any ASUS products, services, processes, or other information and/or
|
||||
The use of ROG and ASUS trademarks within this website and associated tools and libraries is only to provide a recognisable identifier to users to enable them to associate that these tools will work with ASUS ROG laptops.
|
||||
|
||||
---
|
||||
|
||||
## AI Disaclaimer
|
||||
|
||||
Portions of this code have been written by various AI tools and reviewed by the maintainer exaclty as with every other contribution.
|
||||
|
||||
547
asusctl/examples/anime-led-scan.rs
Normal file
547
asusctl/examples/anime-led-scan.rs
Normal file
@@ -0,0 +1,547 @@
|
||||
//! LED scanning tool for discovering AniMe Matrix buffer-to-LED mappings.
|
||||
//!
|
||||
//! This tool lights up one buffer index at a time, allowing you to observe
|
||||
//! which physical LED corresponds to each buffer position. This is essential
|
||||
//! for mapping new device types like G835L where the exact layout is unknown.
|
||||
//!
|
||||
//! You might want to use it slowly, as it sometimes doesn't work properly.
|
||||
//! Maybe there's better ways to make this reliable but for now it works for my use case.
|
||||
//!
|
||||
//! # Usage
|
||||
//! ```
|
||||
//! cargo run --example anime-led-scan -- [options]
|
||||
//! ```
|
||||
//!
|
||||
//! # Controls
|
||||
//! - `n` or `Enter`: Next index
|
||||
//! - `p` or `Backspace`: Previous index
|
||||
//! - `j` followed by number: Jump to specific index
|
||||
//! - `+` / `-`: Adjust step size (default 1)
|
||||
//! - `s`: Save current index to notes file
|
||||
//! - `r`: Mark current index as row start
|
||||
//! - `q` or `Ctrl+C`: Quit
|
||||
//!
|
||||
//! # Output
|
||||
//! Creates a `led-scan-notes.txt` file with recorded observations.
|
||||
|
||||
use std::env;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{self, BufRead, Write};
|
||||
|
||||
use rog_anime::usb::{get_anime_type, Brightness};
|
||||
use rog_anime::{AnimeDataBuffer, AnimeType};
|
||||
use rog_dbus::zbus_anime::AnimeProxyBlocking;
|
||||
use zbus::blocking::Connection;
|
||||
|
||||
/// Saved device state for restoration on exit
|
||||
struct SavedState {
|
||||
builtins_enabled: bool,
|
||||
brightness: Brightness,
|
||||
display_enabled: bool,
|
||||
}
|
||||
|
||||
fn print_help(scan_len: usize, buffer_len: usize) {
|
||||
println!("\n=== LED Scan Tool ===");
|
||||
println!(
|
||||
"Scan range: 0-{} (buffer size: {})",
|
||||
scan_len - 1,
|
||||
buffer_len
|
||||
);
|
||||
println!("Commands:");
|
||||
println!(" n, Enter - Next index");
|
||||
println!(" p, Backspace - Previous index");
|
||||
println!(" j <num> - Jump to index");
|
||||
println!(" + / - - Increase/decrease step size");
|
||||
println!(" s - Save note for current index");
|
||||
println!(" r - Mark as row start");
|
||||
println!(" a - Auto-scan (runs through all indices)");
|
||||
println!(" f - Fill all buffer bytes");
|
||||
println!(" f <start> <end> - Fill range (inclusive)");
|
||||
println!(" p1/p2/p3 - Fill pane 1/2/3 only (each is 627 bytes)");
|
||||
println!(" hold - Hold current LED (press Enter to release)");
|
||||
println!(" hold <s> <e> - Hold range (press Enter to release)");
|
||||
println!(" c - Clear display");
|
||||
println!(" row - Step through rows (G835L, provisional)");
|
||||
println!(" row <n> - Show specific row (G835L, provisional)");
|
||||
println!(" allrows - Light all rows sequentially (G835L)");
|
||||
println!(" rowmap - Print the full row mapping (G835L)");
|
||||
println!(" h - Show this help");
|
||||
println!(" q - Quit and restore state");
|
||||
println!();
|
||||
}
|
||||
|
||||
fn save_note(index: usize, note: &str) -> io::Result<()> {
|
||||
let mut file = OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open("led-scan-notes.txt")?;
|
||||
writeln!(file, "Index {}: {}", index, note)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_single_led(
|
||||
proxy: &AnimeProxyBlocking,
|
||||
anime_type: AnimeType,
|
||||
index: usize,
|
||||
brightness: u8,
|
||||
) {
|
||||
let mut buffer = AnimeDataBuffer::new(anime_type);
|
||||
let data = buffer.data_mut();
|
||||
if index < data.len() {
|
||||
data[index] = brightness;
|
||||
}
|
||||
if let Err(e) = proxy.write(buffer) {
|
||||
eprintln!("Error writing to device: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn clear_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType) {
|
||||
let buffer = AnimeDataBuffer::new(anime_type);
|
||||
let _ = proxy.write(buffer);
|
||||
}
|
||||
|
||||
fn fill_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType, brightness: u8) {
|
||||
let mut buffer = AnimeDataBuffer::new(anime_type);
|
||||
let data = buffer.data_mut();
|
||||
for byte in data.iter_mut() {
|
||||
*byte = brightness;
|
||||
}
|
||||
if let Err(e) = proxy.write(buffer) {
|
||||
eprintln!("Error writing to device: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill a range of LEDs. Both start and end are INCLUSIVE.
|
||||
fn fill_range(
|
||||
proxy: &AnimeProxyBlocking,
|
||||
anime_type: AnimeType,
|
||||
start: usize,
|
||||
end: usize,
|
||||
brightness: u8,
|
||||
) {
|
||||
let mut buffer = AnimeDataBuffer::new(anime_type);
|
||||
let data = buffer.data_mut();
|
||||
for i in start..=end.min(data.len().saturating_sub(1)) {
|
||||
data[i] = brightness;
|
||||
}
|
||||
if let Err(e) = proxy.write(buffer) {
|
||||
eprintln!("Error writing to device: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
fn fill_pane(proxy: &AnimeProxyBlocking, anime_type: AnimeType, pane: usize, brightness: u8) {
|
||||
const PANE_LEN: usize = 627;
|
||||
let start = pane * PANE_LEN;
|
||||
let end = start + PANE_LEN - 1;
|
||||
fill_range(proxy, anime_type, start, end, brightness);
|
||||
}
|
||||
|
||||
/// G835L row pattern (PROVISIONAL - needs hardware verification):
|
||||
/// - Rows 0-1: 1 LED each
|
||||
/// - Rows 2-3: 2 LEDs each
|
||||
/// - ... (pairs of rows with same length)
|
||||
/// - Rows 26-27: 14 LEDs each
|
||||
/// - Rows 28+: 15 LEDs each (constant)
|
||||
///
|
||||
/// Returns (start_index, end_index_inclusive, row_length)
|
||||
fn g835l_row_bounds(row: usize) -> (usize, usize, usize) {
|
||||
let triangle_rows = 28;
|
||||
let triangle_leds = 210;
|
||||
|
||||
if row < triangle_rows {
|
||||
let length = row / 2 + 1;
|
||||
let mut start = 0usize;
|
||||
for r in 0..row {
|
||||
start += r / 2 + 1;
|
||||
}
|
||||
(start, start + length - 1, length)
|
||||
} else {
|
||||
let rows_after_triangle = row - triangle_rows;
|
||||
let start = triangle_leds + rows_after_triangle * 15;
|
||||
(start, start + 14, 15)
|
||||
}
|
||||
}
|
||||
|
||||
fn g835l_total_rows() -> usize {
|
||||
28 + 40
|
||||
}
|
||||
|
||||
fn save_state(proxy: &AnimeProxyBlocking) -> SavedState {
|
||||
SavedState {
|
||||
builtins_enabled: proxy.builtins_enabled().unwrap_or(false),
|
||||
brightness: proxy.brightness().unwrap_or(Brightness::Med),
|
||||
display_enabled: proxy.enable_display().unwrap_or(true),
|
||||
}
|
||||
}
|
||||
|
||||
fn restore_state(proxy: &AnimeProxyBlocking, state: &SavedState) {
|
||||
let _ = proxy.set_builtins_enabled(state.builtins_enabled);
|
||||
let _ = proxy.set_brightness(state.brightness);
|
||||
let _ = proxy.set_enable_display(state.display_enabled);
|
||||
let _ = proxy.run_main_loop(true);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
let mut start_index = 0usize;
|
||||
let mut brightness = 200u8;
|
||||
let mut scan_limit: Option<usize> = None;
|
||||
|
||||
let mut i = 1;
|
||||
while i < args.len() {
|
||||
match args[i].as_str() {
|
||||
"--start" | "-s" => {
|
||||
if i + 1 < args.len() {
|
||||
start_index = args[i + 1].parse().unwrap_or(0);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
"--brightness" | "-b" => {
|
||||
if i + 1 < args.len() {
|
||||
brightness = args[i + 1].parse().unwrap_or(200);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
"--limit" | "-l" => {
|
||||
if i + 1 < args.len() {
|
||||
scan_limit = args[i + 1].parse().ok();
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
"--help" | "-h" => {
|
||||
println!("LED Scan Tool for AniMe Matrix");
|
||||
println!();
|
||||
println!("Usage: anime-led-scan [options]");
|
||||
println!();
|
||||
println!("Options:");
|
||||
println!(" -s, --start <N> Start at index N (default: 0)");
|
||||
println!(" -b, --brightness <N> LED brightness 0-255 (default: 200)");
|
||||
println!(" -l, --limit <N> Cap scan range to N indices (e.g. 810 for G835L)");
|
||||
println!(" -h, --help Show this help");
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let conn = match Connection::system() {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to D-Bus: {}", e);
|
||||
eprintln!("Make sure asusd is running.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let proxy = match AnimeProxyBlocking::new(&conn) {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create Anime proxy: {}", e);
|
||||
eprintln!("Make sure asusd supports your device.");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let anime_type = get_anime_type();
|
||||
let buffer_len = anime_type.data_length();
|
||||
let scan_len = scan_limit.unwrap_or(buffer_len).min(buffer_len);
|
||||
|
||||
println!("=== LED Scan Tool ===");
|
||||
println!("Device type: {:?}", anime_type);
|
||||
println!("Buffer length: {} bytes", buffer_len);
|
||||
println!("Scan range: 0-{}", scan_len - 1);
|
||||
println!("Brightness: {}", brightness);
|
||||
println!();
|
||||
|
||||
// Save current state for restoration
|
||||
let saved_state = save_state(&proxy);
|
||||
println!("Saved device state for restoration on exit.");
|
||||
|
||||
// Stop system animations
|
||||
if let Err(e) = proxy.run_main_loop(false) {
|
||||
eprintln!("Warning: Could not stop main loop: {}", e);
|
||||
}
|
||||
println!("Stopped system animations.");
|
||||
|
||||
print_help(scan_len, buffer_len);
|
||||
|
||||
let mut current_index = start_index.min(scan_len - 1);
|
||||
let mut step = 1usize;
|
||||
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
|
||||
let stdin = io::stdin();
|
||||
let mut input = String::new();
|
||||
|
||||
loop {
|
||||
input.clear();
|
||||
print!("> ");
|
||||
io::stdout().flush().unwrap();
|
||||
|
||||
if stdin.lock().read_line(&mut input).is_err() {
|
||||
break;
|
||||
}
|
||||
|
||||
let cmd = input.trim();
|
||||
|
||||
match cmd {
|
||||
"q" | "quit" | "exit" => {
|
||||
clear_display(&proxy, anime_type);
|
||||
restore_state(&proxy, &saved_state);
|
||||
println!("Restored device state. Goodbye!");
|
||||
break;
|
||||
}
|
||||
"n" | "" => {
|
||||
current_index = (current_index + step).min(scan_len - 1);
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
}
|
||||
"p" => {
|
||||
current_index = current_index.saturating_sub(step);
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
}
|
||||
"+" => {
|
||||
step = step.saturating_mul(2).max(1);
|
||||
println!("Step size: {}", step);
|
||||
}
|
||||
"-" => {
|
||||
step = step.saturating_div(2).max(1);
|
||||
println!("Step size: {}", step);
|
||||
}
|
||||
"r" => {
|
||||
if let Err(e) = save_note(current_index, "ROW START") {
|
||||
eprintln!("Error saving note: {}", e);
|
||||
} else {
|
||||
println!("Saved: Index {} marked as ROW START", current_index);
|
||||
}
|
||||
}
|
||||
"h" | "help" | "?" => {
|
||||
print_help(scan_len, buffer_len);
|
||||
}
|
||||
cmd if cmd.starts_with('j') => {
|
||||
let num_str = cmd.trim_start_matches('j').trim();
|
||||
if let Ok(idx) = num_str.parse::<usize>() {
|
||||
if idx < scan_len {
|
||||
current_index = idx;
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
} else {
|
||||
println!("Index {} out of range (max: {})", idx, scan_len - 1);
|
||||
}
|
||||
} else {
|
||||
println!("Usage: j <number>");
|
||||
}
|
||||
}
|
||||
cmd if cmd.starts_with('s') && !cmd.starts_with("show") => {
|
||||
let note = cmd.trim_start_matches('s').trim();
|
||||
let note = if note.is_empty() { "observed" } else { note };
|
||||
if let Err(e) = save_note(current_index, note) {
|
||||
eprintln!("Error saving note: {}", e);
|
||||
} else {
|
||||
println!("Saved note for index {}", current_index);
|
||||
}
|
||||
}
|
||||
"a" => {
|
||||
println!("Auto-scan mode (0 to {})...", scan_len - 1);
|
||||
let delay = std::time::Duration::from_millis(10);
|
||||
for idx in current_index..scan_len {
|
||||
write_single_led(&proxy, anime_type, idx, brightness);
|
||||
print!("\rIndex: {} / {} ", idx, scan_len - 1);
|
||||
io::stdout().flush().unwrap();
|
||||
std::thread::sleep(delay);
|
||||
current_index = idx;
|
||||
}
|
||||
println!();
|
||||
println!("Auto-scan complete. Current index: {}", current_index);
|
||||
}
|
||||
"c" => {
|
||||
clear_display(&proxy, anime_type);
|
||||
println!("Display cleared");
|
||||
}
|
||||
"f" => {
|
||||
fill_display(&proxy, anime_type, brightness);
|
||||
println!("All buffer bytes filled at brightness {}", brightness);
|
||||
}
|
||||
"p1" => {
|
||||
fill_pane(&proxy, anime_type, 0, brightness);
|
||||
println!("Pane 1 (indices 0-626) filled");
|
||||
}
|
||||
"p2" => {
|
||||
fill_pane(&proxy, anime_type, 1, brightness);
|
||||
println!("Pane 2 (indices 627-1253) filled");
|
||||
}
|
||||
"p3" => {
|
||||
fill_pane(&proxy, anime_type, 2, brightness);
|
||||
println!("Pane 3 (indices 1254-1880) filled");
|
||||
}
|
||||
cmd if cmd.starts_with("f ") => {
|
||||
let parts: Vec<&str> = cmd.split_whitespace().collect();
|
||||
if parts.len() == 3 {
|
||||
if let (Ok(start), Ok(end)) =
|
||||
(parts[1].parse::<usize>(), parts[2].parse::<usize>())
|
||||
{
|
||||
fill_range(&proxy, anime_type, start, end, brightness);
|
||||
println!("Filled indices {} to {}", start, end);
|
||||
} else {
|
||||
println!("Usage: f <start> <end>");
|
||||
}
|
||||
} else {
|
||||
println!("Usage: f <start> <end>");
|
||||
}
|
||||
}
|
||||
"show" => {
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
}
|
||||
"row" => {
|
||||
if anime_type != AnimeType::G835L {
|
||||
println!("Warning: Row commands use G835L mapping (provisional). You can add to this code to support other types. `examples/anime-led-scan.rs[402:425]`");
|
||||
}
|
||||
println!("Row stepping mode. Press Enter for next row, 'q' to quit.");
|
||||
let total = g835l_total_rows();
|
||||
for row_num in 0..total {
|
||||
let (start, end, len) = g835l_row_bounds(row_num);
|
||||
if end >= scan_len {
|
||||
println!("Row {} exceeds scan limit, stopping.", row_num);
|
||||
break;
|
||||
}
|
||||
println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len);
|
||||
fill_range(&proxy, anime_type, start, end, brightness);
|
||||
input.clear();
|
||||
print!("(Enter=next, q=quit) > ");
|
||||
io::stdout().flush().unwrap();
|
||||
if stdin.lock().read_line(&mut input).is_err() {
|
||||
break;
|
||||
}
|
||||
if input.trim() == "q" {
|
||||
break;
|
||||
}
|
||||
clear_display(&proxy, anime_type);
|
||||
}
|
||||
println!("Row stepping done.");
|
||||
}
|
||||
cmd if cmd.starts_with("row ") => {
|
||||
if anime_type != AnimeType::G835L {
|
||||
println!("Warning: Row commands use G835L mapping (provisional).");
|
||||
}
|
||||
let row_str = cmd.trim_start_matches("row ").trim();
|
||||
if let Ok(row_num) = row_str.parse::<usize>() {
|
||||
let total = g835l_total_rows();
|
||||
if row_num < total {
|
||||
let (start, end, len) = g835l_row_bounds(row_num);
|
||||
if end < scan_len {
|
||||
println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len);
|
||||
fill_range(&proxy, anime_type, start, end, brightness);
|
||||
} else {
|
||||
println!("Row {} exceeds scan limit", row_num);
|
||||
}
|
||||
} else {
|
||||
println!("Row {} out of range (max: {})", row_num, total - 1);
|
||||
}
|
||||
} else {
|
||||
println!("Usage: row <number>");
|
||||
}
|
||||
}
|
||||
"allrows" => {
|
||||
if anime_type != AnimeType::G835L {
|
||||
println!("Warning: Row commands use G835L mapping (provisional).");
|
||||
}
|
||||
println!("Lighting all rows sequentially (200ms each)...");
|
||||
let total = g835l_total_rows();
|
||||
let delay = std::time::Duration::from_millis(200);
|
||||
for row_num in 0..total {
|
||||
let (start, end, len) = g835l_row_bounds(row_num);
|
||||
if end >= scan_len {
|
||||
println!("\nRow {} exceeds scan limit, stopping.", row_num);
|
||||
break;
|
||||
}
|
||||
print!(
|
||||
"\rRow {}/{}: indices {}-{} ({} LEDs) ",
|
||||
row_num,
|
||||
total - 1,
|
||||
start,
|
||||
end,
|
||||
len
|
||||
);
|
||||
io::stdout().flush().unwrap();
|
||||
fill_range(&proxy, anime_type, start, end, brightness);
|
||||
std::thread::sleep(delay);
|
||||
clear_display(&proxy, anime_type);
|
||||
}
|
||||
println!("\nDone.");
|
||||
}
|
||||
"rowmap" => {
|
||||
if anime_type != AnimeType::G835L {
|
||||
println!("Warning: Row map is for G835L (provisional).");
|
||||
}
|
||||
println!("G835L Row Map:");
|
||||
let total = g835l_total_rows();
|
||||
for row_num in 0..total {
|
||||
let (start, end, len) = g835l_row_bounds(row_num);
|
||||
let marker = if end >= scan_len {
|
||||
" (exceeds limit)"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
println!(
|
||||
" Row {:2}: indices {:4}-{:4} ({:2} LEDs){}",
|
||||
row_num, start, end, len, marker
|
||||
);
|
||||
}
|
||||
}
|
||||
"hold" => {
|
||||
// Single write, wait for Enter to release
|
||||
println!("Holding index {}. Press Enter to release...", current_index);
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
input.clear();
|
||||
let _ = stdin.lock().read_line(&mut input);
|
||||
clear_display(&proxy, anime_type);
|
||||
println!("Released.");
|
||||
}
|
||||
cmd if cmd.starts_with("hold ") => {
|
||||
let arg = cmd.trim_start_matches("hold ").trim();
|
||||
let (start, end): (usize, usize) = match arg {
|
||||
"p1" | "1" => (0, 626),
|
||||
"p2" | "2" => (627, 1253),
|
||||
_ => {
|
||||
let parts: Vec<&str> = arg.split_whitespace().collect();
|
||||
if parts.len() == 2 {
|
||||
if let (Ok(s), Ok(e)) = (parts[0].parse(), parts[1].parse()) {
|
||||
(s, e)
|
||||
} else {
|
||||
println!("Usage: hold p1, hold p2, or hold <start> <end>");
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
println!("Usage: hold p1, hold p2, or hold <start> <end>");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
};
|
||||
println!("Holding range {}-{}. Press Enter to release...", start, end);
|
||||
fill_range(&proxy, anime_type, start, end, brightness);
|
||||
input.clear();
|
||||
let _ = stdin.lock().read_line(&mut input);
|
||||
clear_display(&proxy, anime_type);
|
||||
println!("Released.");
|
||||
}
|
||||
_ => {
|
||||
if let Ok(idx) = cmd.parse::<usize>() {
|
||||
if idx < scan_len {
|
||||
current_index = idx;
|
||||
write_single_led(&proxy, anime_type, current_index, brightness);
|
||||
println!(">>> Index: {} (step: {})", current_index, step);
|
||||
} else {
|
||||
println!("Index {} out of range (max: {})", idx, scan_len - 1);
|
||||
}
|
||||
} else {
|
||||
println!("Unknown command: '{}'. Type 'h' for help.", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@ pub struct AnimeGif {
|
||||
pub bright: f32,
|
||||
#[argh(
|
||||
option,
|
||||
default = "1",
|
||||
default = "0",
|
||||
description = "how many loops to play - 0 is infinite"
|
||||
)]
|
||||
pub loops: u32,
|
||||
@@ -144,7 +144,7 @@ pub struct AnimeGifDiagonal {
|
||||
pub bright: f32,
|
||||
#[argh(
|
||||
option,
|
||||
default = "1",
|
||||
default = "0",
|
||||
description = "how many loops to play - 0 is infinite"
|
||||
)]
|
||||
pub loops: u32,
|
||||
|
||||
@@ -8,7 +8,7 @@ use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed};
|
||||
#[derive(FromArgs, Debug, Clone)]
|
||||
#[argh(
|
||||
subcommand,
|
||||
name = "aura-power-old",
|
||||
name = "power-tuf",
|
||||
description = "aura power (old ROGs and TUF laptops)"
|
||||
)]
|
||||
pub struct LedPowerCommand1 {
|
||||
@@ -38,7 +38,7 @@ pub struct LedPowerCommand1 {
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug, Clone)]
|
||||
#[argh(subcommand, name = "aura-power", description = "aura power")]
|
||||
#[argh(subcommand, name = "power", description = "aura power")]
|
||||
pub struct LedPowerCommand2 {
|
||||
#[argh(subcommand)]
|
||||
pub command: Option<SetAuraZoneEnabled>,
|
||||
@@ -312,6 +312,133 @@ pub struct TwoColourSpeed {
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Two-colour star effect (separate subcommand name)
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(subcommand, name = "stars", description = "two-colour star effect")]
|
||||
pub struct StarsTwoColour {
|
||||
#[argh(option, description = "set the first RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(option, description = "set the second RGB value e.g. ff00ff")]
|
||||
pub colour2: Colour,
|
||||
|
||||
#[argh(option, description = "set the speed: low, med, high")]
|
||||
pub speed: Speed,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Rain effect (single-speed, separate subcommand name)
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(
|
||||
subcommand,
|
||||
name = "rain",
|
||||
description = "single speed-based rain effect"
|
||||
)]
|
||||
pub struct RainSingleSpeed {
|
||||
#[argh(option, description = "set the speed: low, med, high")]
|
||||
pub speed: Speed,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Laser (single-colour with speed) separate subcommand
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(
|
||||
subcommand,
|
||||
name = "laser",
|
||||
description = "single-colour effect with speed"
|
||||
)]
|
||||
pub struct LaserSingleColourSpeed {
|
||||
#[argh(option, short = 'c', description = "set the RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(option, description = "set the speed: low, med, high")]
|
||||
pub speed: Speed,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Ripple (single-colour with speed) separate subcommand
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(
|
||||
subcommand,
|
||||
name = "ripple",
|
||||
description = "single-colour effect with speed"
|
||||
)]
|
||||
pub struct RippleSingleColourSpeed {
|
||||
#[argh(option, short = 'c', description = "set the RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(option, description = "set the speed: low, med, high")]
|
||||
pub speed: Speed,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Pulse / Comet / Flash variants (single-colour) separate subcommands
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(subcommand, name = "pulse", description = "single-colour pulse effect")]
|
||||
pub struct PulseSingleColour {
|
||||
#[argh(option, short = 'c', description = "set the RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(subcommand, name = "comet", description = "single-colour comet effect")]
|
||||
pub struct CometSingleColour {
|
||||
#[argh(option, short = 'c', description = "set the RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[argh(subcommand, name = "flash", description = "single-colour flash effect")]
|
||||
pub struct FlashSingleColour {
|
||||
#[argh(option, short = 'c', description = "set the RGB value e.g. ff00ff")]
|
||||
pub colour: Colour,
|
||||
|
||||
#[argh(
|
||||
option,
|
||||
default = "AuraZone::None",
|
||||
description = "set the zone for this effect e.g. 0, 1, one, logo, lightbar-left"
|
||||
)]
|
||||
pub zone: AuraZone,
|
||||
}
|
||||
|
||||
/// Multi-zone colour settings
|
||||
#[derive(FromArgs, Debug, Clone, Default)]
|
||||
#[allow(dead_code)]
|
||||
@@ -359,14 +486,14 @@ pub enum SetAuraBuiltin {
|
||||
Breathe(TwoColourSpeed), // 1
|
||||
RainbowCycle(SingleSpeed), // 2
|
||||
RainbowWave(SingleSpeedDirection), // 3
|
||||
Stars(TwoColourSpeed), // 4
|
||||
Rain(SingleSpeed), // 5
|
||||
Stars(StarsTwoColour), // 4
|
||||
Rain(RainSingleSpeed), // 5
|
||||
Highlight(SingleColourSpeed), // 6
|
||||
Laser(SingleColourSpeed), // 7
|
||||
Ripple(SingleColourSpeed), // 8
|
||||
Pulse(SingleColour), // 10
|
||||
Comet(SingleColour), // 11
|
||||
Flash(SingleColour), // 12
|
||||
Laser(LaserSingleColourSpeed), // 7
|
||||
Ripple(RippleSingleColourSpeed), // 8
|
||||
Pulse(PulseSingleColour), // 10
|
||||
Comet(CometSingleColour), // 11
|
||||
Flash(FlashSingleColour), // 12
|
||||
}
|
||||
|
||||
impl Default for SetAuraBuiltin {
|
||||
@@ -428,6 +555,79 @@ impl From<&SingleSpeedDirection> for AuraEffect {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&StarsTwoColour> for AuraEffect {
|
||||
fn from(aura: &StarsTwoColour) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
colour2: aura.colour2,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&RainSingleSpeed> for AuraEffect {
|
||||
fn from(aura: &RainSingleSpeed) -> Self {
|
||||
Self {
|
||||
speed: aura.speed,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&LaserSingleColourSpeed> for AuraEffect {
|
||||
fn from(aura: &LaserSingleColourSpeed) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
speed: aura.speed,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&RippleSingleColourSpeed> for AuraEffect {
|
||||
fn from(aura: &RippleSingleColourSpeed) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
speed: aura.speed,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PulseSingleColour> for AuraEffect {
|
||||
fn from(aura: &PulseSingleColour) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&CometSingleColour> for AuraEffect {
|
||||
fn from(aura: &CometSingleColour) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&FlashSingleColour> for AuraEffect {
|
||||
fn from(aura: &FlashSingleColour) -> Self {
|
||||
Self {
|
||||
colour1: aura.colour,
|
||||
zone: aura.zone,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&SetAuraBuiltin> for AuraEffect {
|
||||
fn from(aura: &SetAuraBuiltin) -> Self {
|
||||
match aura {
|
||||
|
||||
@@ -18,9 +18,7 @@ pub struct CliStart {
|
||||
#[derive(FromArgs, Debug)]
|
||||
#[argh(subcommand)]
|
||||
pub enum CliCommand {
|
||||
Aura(LedModeCommand),
|
||||
AuraPowerOld(LedPowerCommand1),
|
||||
AuraPower(LedPowerCommand2),
|
||||
Aura(AuraCommand),
|
||||
Brightness(BrightnessCommand),
|
||||
Profile(ProfileCommand),
|
||||
FanCurve(FanCurveCommand),
|
||||
@@ -99,7 +97,7 @@ pub struct ProfileSetCommand {
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug, Default)]
|
||||
#[argh(subcommand, name = "aura", description = "led mode commands")]
|
||||
#[argh(subcommand, name = "effect", description = "led mode commands")]
|
||||
pub struct LedModeCommand {
|
||||
#[argh(switch, description = "switch to next aura mode")]
|
||||
pub next_mode: bool,
|
||||
@@ -111,6 +109,21 @@ pub struct LedModeCommand {
|
||||
pub command: Option<SetAuraBuiltin>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug)]
|
||||
#[argh(subcommand, name = "aura", description = "aura device commands")]
|
||||
pub struct AuraCommand {
|
||||
#[argh(subcommand)]
|
||||
pub command: AuraSubCommand,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug)]
|
||||
#[argh(subcommand)]
|
||||
pub enum AuraSubCommand {
|
||||
Power(LedPowerCommand2),
|
||||
PowerTuf(LedPowerCommand1),
|
||||
Effect(LedModeCommand),
|
||||
}
|
||||
|
||||
#[derive(FromArgs, Debug, Default)]
|
||||
#[argh(
|
||||
subcommand,
|
||||
|
||||
@@ -186,9 +186,11 @@ fn do_parsed(
|
||||
conn: Connection,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match &parsed.command {
|
||||
CliCommand::Aura(mode) => handle_led_mode(mode)?,
|
||||
CliCommand::AuraPowerOld(pow) => handle_led_power1(pow)?,
|
||||
CliCommand::AuraPower(pow) => handle_led_power2(pow)?,
|
||||
CliCommand::Aura(a) => match &a.command {
|
||||
crate::cli_opts::AuraSubCommand::Effect(mode) => handle_led_mode(mode)?,
|
||||
crate::cli_opts::AuraSubCommand::PowerTuf(pow) => handle_led_power1(pow)?,
|
||||
crate::cli_opts::AuraSubCommand::Power(pow) => handle_led_power2(pow)?,
|
||||
},
|
||||
CliCommand::Brightness(cmd) => handle_brightness(cmd)?,
|
||||
CliCommand::Profile(cmd) => handle_throttle_profile(&conn, supported_properties, cmd)?,
|
||||
CliCommand::FanCurve(cmd) => handle_fan_curve(&conn, cmd)?,
|
||||
@@ -720,7 +722,7 @@ fn handle_led_power1(power: &LedPowerCommand1) -> Result<(), Box<dyn std::error:
|
||||
&& !power.keyboard
|
||||
&& !power.lightbar
|
||||
{
|
||||
println!("Missing arg or command; run 'asusctl aura-power-old --help' for usage");
|
||||
println!("Missing arg or command; run 'asusctl aura power-tuf --help' for usage");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -773,7 +775,7 @@ fn handle_led_power2(power: &LedPowerCommand2) -> Result<(), Box<dyn std::error:
|
||||
}
|
||||
|
||||
if power.command.is_none() {
|
||||
println!("Missing arg or command; run 'asusctl aura-power --help' for usage");
|
||||
println!("Missing arg or command; run 'asusctl aura power --help' for usage");
|
||||
println!("Commands available");
|
||||
return Ok(());
|
||||
}
|
||||
@@ -968,52 +970,72 @@ fn print_firmware_attr(attr: &AsusArmouryProxyBlocking) -> Result<(), Box<dyn st
|
||||
let name = attr.name()?;
|
||||
println!("{}:", <&str>::from(name));
|
||||
|
||||
let attrs = attr.available_attrs()?;
|
||||
if attrs.contains(&"min_value".to_string())
|
||||
&& attrs.contains(&"max_value".to_string())
|
||||
&& attrs.contains(&"current_value".to_string())
|
||||
{
|
||||
let c = attr.current_value()?;
|
||||
let min = attr.min_value()?;
|
||||
let max = attr.max_value()?;
|
||||
println!(" current: {min}..[{c}]..{max}");
|
||||
if attrs.contains(&"default_value".to_string()) {
|
||||
println!(" default: {}\n", attr.default_value()?);
|
||||
// Be resilient to DBus read failures: if any read fails, show "unavailable"
|
||||
let attrs = attr.available_attrs().unwrap_or_default();
|
||||
|
||||
let has_min = attrs.contains(&"min_value".to_string());
|
||||
let has_max = attrs.contains(&"max_value".to_string());
|
||||
let has_current = attrs.contains(&"current_value".to_string());
|
||||
let has_possible = attrs.contains(&"possible_values".to_string());
|
||||
let has_default = attrs.contains(&"default_value".to_string());
|
||||
|
||||
if has_min && has_max && has_current {
|
||||
let c = attr.current_value().ok();
|
||||
let min = attr.min_value().ok();
|
||||
let max = attr.max_value().ok();
|
||||
match (min, c, max) {
|
||||
(Some(min), Some(c), Some(max)) => println!(" current: {min}..[{c}]..{max}"),
|
||||
_ => println!(" current: unavailable"),
|
||||
}
|
||||
|
||||
if has_default {
|
||||
match attr.default_value().ok() {
|
||||
Some(d) => println!(" default: {}\n", d),
|
||||
None => println!(" default: unavailable\n"),
|
||||
}
|
||||
} else {
|
||||
println!();
|
||||
}
|
||||
} else if attrs.contains(&"possible_values".to_string())
|
||||
&& attrs.contains(&"current_value".to_string())
|
||||
{
|
||||
let c = attr.current_value()?;
|
||||
let v = attr.possible_values()?;
|
||||
for p in v.iter().enumerate() {
|
||||
if p.0 == 0 {
|
||||
print!(" current: [");
|
||||
} else if has_possible && has_current {
|
||||
let c = attr.current_value().ok();
|
||||
let v = attr.possible_values().ok();
|
||||
if let (Some(c), Some(v)) = (c, v) {
|
||||
for p in v.iter().enumerate() {
|
||||
if p.0 == 0 {
|
||||
print!(" current: [");
|
||||
}
|
||||
if *p.1 == c {
|
||||
print!("({c})");
|
||||
} else {
|
||||
print!("{}", p.1);
|
||||
}
|
||||
if p.0 < v.len() - 1 {
|
||||
print!(",");
|
||||
}
|
||||
if p.0 == v.len() - 1 {
|
||||
print!("]");
|
||||
}
|
||||
}
|
||||
if *p.1 == c {
|
||||
print!("({c})");
|
||||
if has_default {
|
||||
match attr.default_value().ok() {
|
||||
Some(d) => println!(" default: {}\n", d),
|
||||
None => println!(" default: unavailable\n"),
|
||||
}
|
||||
} else {
|
||||
print!("{}", p.1);
|
||||
println!("\n");
|
||||
}
|
||||
if p.0 < v.len() - 1 {
|
||||
print!(",");
|
||||
}
|
||||
if p.0 == v.len() - 1 {
|
||||
print!("]");
|
||||
}
|
||||
}
|
||||
if attrs.contains(&"default_value".to_string()) {
|
||||
println!(" default: {}\n", attr.default_value()?);
|
||||
} else {
|
||||
println!("\n");
|
||||
println!(" current: unavailable\n");
|
||||
}
|
||||
} else if has_current {
|
||||
match attr.current_value().ok() {
|
||||
Some(c) => println!(" current: {c}\n"),
|
||||
None => println!(" current: unavailable\n"),
|
||||
}
|
||||
} else if attrs.contains(&"current_value".to_string()) {
|
||||
let c = attr.current_value()?;
|
||||
println!(" current: {c}\n");
|
||||
} else {
|
||||
println!();
|
||||
println!(" unavailable\n");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@ use std::sync::Arc;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::asus_armoury::{AttrValue, Attribute, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::asus_armoury::{
|
||||
AttrValue, Attribute, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
|
||||
};
|
||||
use rog_platform::platform::{PlatformProfile, RogPlatform};
|
||||
use rog_platform::power::AsusPower;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -168,82 +170,71 @@ impl ArmouryAttributeRegistry {
|
||||
impl crate::Reloadable for AsusArmouryAttribute {
|
||||
async fn reload(&mut self) -> Result<(), RogError> {
|
||||
info!("Reloading {}", self.attr.name());
|
||||
let name: FirmwareAttribute = self.attr.name().into();
|
||||
let attribute: FirmwareAttribute = self.attr.name().into();
|
||||
let name = self.attr.name();
|
||||
|
||||
// Treat dGPU attributes the same as PPT attributes for power-profile
|
||||
// behaviour so they follow AC/DC tuning groups.
|
||||
if name.is_ppt() || name.is_dgpu() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default()
|
||||
== 1;
|
||||
|
||||
let apply_value = {
|
||||
let config = self.config.lock().await;
|
||||
config
|
||||
.select_tunings_ref(power_plugged, profile)
|
||||
.and_then(|tuning| {
|
||||
if tuning.enabled {
|
||||
tuning.group.get(&self.name()).copied()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
let config = self.config.lock().await;
|
||||
let apply_value = match attribute.property_type() {
|
||||
FirmwareAttributeType::Ppt => {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
};
|
||||
.unwrap_or_default()
|
||||
== 1;
|
||||
|
||||
if let Some(tune) = apply_value {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(tune))
|
||||
.map_err(|e| {
|
||||
error!("Could not set {} value: {e:?}", self.attr.name());
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
info!(
|
||||
"Restored PPT armoury setting {} to {:?}",
|
||||
self.attr.name(),
|
||||
tune
|
||||
);
|
||||
} else {
|
||||
info!("Ignored restoring PPT armoury setting {} as tuning group is disabled or no saved value", self.attr.name());
|
||||
let apply_value = {
|
||||
config.select_tunings_ref(power_plugged, profile).and_then(
|
||||
|tuning| match tuning.enabled {
|
||||
true => tuning.group.get(&self.name()).copied(),
|
||||
false => None,
|
||||
},
|
||||
)
|
||||
};
|
||||
|
||||
apply_value.map_or(AttrValue::None, AttrValue::Integer)
|
||||
}
|
||||
} else {
|
||||
// Handle non-PPT attributes (boolean and other settings)
|
||||
if let Some(saved_value) = self.config.lock().await.armoury_settings.get(&name) {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(*saved_value))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Error restoring armoury setting {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
FirmwareAttributeType::Gpu => {
|
||||
info!("Reload called on GPU attribute {name}: doing nothing");
|
||||
AttrValue::None
|
||||
}
|
||||
_ => {
|
||||
info!("Reload called on firmware attribute {name}");
|
||||
match config.armoury_settings.get(&attribute) {
|
||||
Some(saved_value) => AttrValue::Integer(*saved_value),
|
||||
None => AttrValue::None,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match apply_value {
|
||||
AttrValue::None => {
|
||||
info!(
|
||||
"Restored armoury setting {} to {:?}",
|
||||
self.attr.name(),
|
||||
saved_value
|
||||
);
|
||||
} else {
|
||||
info!(
|
||||
"No saved armoury setting for {}: skipping restore",
|
||||
"No saved value for attribute {}: skipping.",
|
||||
self.attr.name()
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
info!("Applying value {apply_value:?} to attribute {name}");
|
||||
self.attr.set_current_value(&apply_value).map_err(|e| {
|
||||
error!("Could not set {name} value: {e:?}");
|
||||
self.attr.base_path_exists();
|
||||
e
|
||||
})?;
|
||||
|
||||
info!("Restored asus-armoury setting {name} to {apply_value:?}");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// If return is `-1` on a property then there is avilable value for that
|
||||
/// If return is `-1` on a property then there is available value for that
|
||||
/// property
|
||||
#[interface(name = "xyz.ljones.AsusArmoury")]
|
||||
impl AsusArmouryAttribute {
|
||||
@@ -293,7 +284,7 @@ impl AsusArmouryAttribute {
|
||||
|
||||
async fn restore_default(&self) -> fdo::Result<()> {
|
||||
self.attr.restore_default()?;
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
if self.name().property_type() == FirmwareAttributeType::Ppt {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
@@ -352,7 +343,7 @@ impl AsusArmouryAttribute {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn current_value(&self) -> fdo::Result<i32> {
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
if self.name().property_type() == FirmwareAttributeType::Ppt {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
@@ -387,66 +378,62 @@ impl AsusArmouryAttribute {
|
||||
|
||||
#[zbus(property)]
|
||||
async fn set_current_value(&mut self, value: i32) -> fdo::Result<()> {
|
||||
if self.name().is_ppt() || self.name().is_dgpu() {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut config = self.config.lock().await;
|
||||
let tuning = config.select_tunings(power_plugged == 1, profile);
|
||||
|
||||
if let Some(tune) = tuning.group.get_mut(&self.name()) {
|
||||
*tune = value;
|
||||
} else {
|
||||
tuning.group.insert(self.name(), value);
|
||||
debug!("Store tuning config for {} = {:?}", self.attr.name(), value);
|
||||
}
|
||||
if tuning.enabled {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(value))
|
||||
let name = self.attr.name();
|
||||
let apply_value = match self.name().property_type() {
|
||||
FirmwareAttributeType::Ppt => {
|
||||
let profile: PlatformProfile = self.platform.get_platform_profile()?.into();
|
||||
let power_plugged = self
|
||||
.power
|
||||
.get_online()
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Could not set value to PPT property {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
error!("Could not get power status: {e:?}");
|
||||
e
|
||||
})?;
|
||||
} else {
|
||||
warn!(
|
||||
"Tuning group is disabled: skipping setting value to PPT property {}",
|
||||
self.attr.name()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.attr
|
||||
.set_current_value(&AttrValue::Integer(value))
|
||||
.map_err(|e| {
|
||||
error!(
|
||||
"Could not set value {value} to attribute {}: {e:?}",
|
||||
self.attr.name()
|
||||
);
|
||||
e
|
||||
})?;
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut settings = self.config.lock().await;
|
||||
settings
|
||||
.armoury_settings
|
||||
.entry(self.name())
|
||||
.and_modify(|setting| {
|
||||
debug!("Set config for {} = {value}", self.attr.name());
|
||||
*setting = value;
|
||||
})
|
||||
.or_insert_with(|| {
|
||||
debug!("Adding config for {} = {value}", self.attr.name());
|
||||
value
|
||||
});
|
||||
}
|
||||
let mut config = self.config.lock().await;
|
||||
let tuning = config.select_tunings(power_plugged == 1, profile);
|
||||
|
||||
if let Some(tune) = tuning.group.get_mut(&self.name()) {
|
||||
*tune = value;
|
||||
} else {
|
||||
tuning.group.insert(self.name(), value);
|
||||
debug!("Store tuning config for {name} = {:?}", value);
|
||||
}
|
||||
|
||||
match tuning.enabled {
|
||||
true => {
|
||||
debug!("Tuning is enabled: setting value to PPT property {name} = {value}");
|
||||
AttrValue::Integer(value)
|
||||
}
|
||||
false => {
|
||||
warn!("Tuning is disabled: skipping setting value to PPT property {name}");
|
||||
AttrValue::None
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let mut settings = self.config.lock().await;
|
||||
settings
|
||||
.armoury_settings
|
||||
.entry(self.name())
|
||||
.and_modify(|setting| {
|
||||
debug!("Set config for {name} = {value}");
|
||||
*setting = value;
|
||||
})
|
||||
.or_insert_with(|| {
|
||||
debug!("Adding config for {name} = {value}");
|
||||
value
|
||||
});
|
||||
|
||||
AttrValue::Integer(value)
|
||||
}
|
||||
};
|
||||
|
||||
self.attr.set_current_value(&apply_value).map_err(|e| {
|
||||
error!("Could not set value {value} to attribute {name}: {e:?}");
|
||||
e
|
||||
})?;
|
||||
|
||||
// write config after setting value
|
||||
self.config.lock().await.write();
|
||||
@@ -515,7 +502,7 @@ pub async fn set_config_or_default(
|
||||
) {
|
||||
for attr in attrs.attributes().iter() {
|
||||
let name: FirmwareAttribute = attr.name().into();
|
||||
if name.is_ppt() || name.is_dgpu() {
|
||||
if name.property_type() == FirmwareAttributeType::Ppt {
|
||||
let tuning = config.select_tunings(power_plugged, profile);
|
||||
if !tuning.enabled {
|
||||
debug!("Tuning group is not enabled, skipping");
|
||||
|
||||
@@ -33,7 +33,6 @@ pub struct AuraConfig {
|
||||
}
|
||||
|
||||
impl StdConfig for AuraConfig {
|
||||
/// Detect the keyboard type and load from default DB if data available
|
||||
fn new() -> Self {
|
||||
panic!("This should not be used");
|
||||
}
|
||||
|
||||
@@ -182,7 +182,6 @@ impl AuraZbus {
|
||||
self.0.set_brightness(config.brightness.into()).await?;
|
||||
config.set_builtin(effect);
|
||||
config.write();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -208,9 +207,10 @@ impl AuraZbus {
|
||||
let mut config = self.0.config.lock().await;
|
||||
for opt in options.states {
|
||||
let zone = opt.zone;
|
||||
for config in config.enabled.states.iter_mut() {
|
||||
if config.zone == zone {
|
||||
*config = opt;
|
||||
for state in config.enabled.states.iter_mut() {
|
||||
if state.zone == zone {
|
||||
*state = opt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,6 +196,7 @@ impl DeviceHandle {
|
||||
Some(Arc::new(Mutex::new(k)))
|
||||
});
|
||||
|
||||
// Load saved mode, colours, brightness, power from disk; apply on reload
|
||||
let mut config = AuraConfig::load_and_update_config(prod_id);
|
||||
config.led_type = aura_type;
|
||||
let aura = Aura {
|
||||
|
||||
@@ -4,7 +4,9 @@ use std::sync::Arc;
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use log::{debug, error, info, warn};
|
||||
use rog_platform::asus_armoury::{AttrValue, FirmwareAttribute, FirmwareAttributes};
|
||||
use rog_platform::asus_armoury::{
|
||||
AttrValue, FirmwareAttribute, FirmwareAttributeType, FirmwareAttributes,
|
||||
};
|
||||
use rog_platform::cpu::{CPUControl, CPUGovernor, CPUEPP};
|
||||
use rog_platform::platform::{PlatformProfile, Properties, RogPlatform};
|
||||
use rog_platform::power::AsusPower;
|
||||
@@ -459,8 +461,18 @@ impl CtrlPlatform {
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
policy: PlatformProfile,
|
||||
) -> Result<(), FdoErr> {
|
||||
self.config.lock().await.platform_profile_on_battery = policy;
|
||||
self.set_platform_profile(ctxt, policy).await?;
|
||||
// If the requested profile isn't available on this platform, and it's
|
||||
// `Quiet`, fall back to `LowPower` so we don't write an unavailable
|
||||
// profile into the config file.
|
||||
let mut chosen = policy;
|
||||
if let Ok(choices) = self.platform.get_platform_profile_choices() {
|
||||
if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) {
|
||||
chosen = PlatformProfile::LowPower;
|
||||
}
|
||||
}
|
||||
|
||||
self.config.lock().await.platform_profile_on_battery = chosen;
|
||||
self.set_platform_profile(ctxt, chosen).await?;
|
||||
self.config.lock().await.write();
|
||||
Ok(())
|
||||
}
|
||||
@@ -488,8 +500,16 @@ impl CtrlPlatform {
|
||||
#[zbus(signal_context)] ctxt: SignalEmitter<'_>,
|
||||
policy: PlatformProfile,
|
||||
) -> Result<(), FdoErr> {
|
||||
self.config.lock().await.platform_profile_on_ac = policy;
|
||||
self.set_platform_profile(ctxt, policy).await?;
|
||||
// Mirror the same fallback behavior for AC profile changes.
|
||||
let mut chosen = policy;
|
||||
if let Ok(choices) = self.platform.get_platform_profile_choices() {
|
||||
if chosen == PlatformProfile::Quiet && !choices.contains(&PlatformProfile::Quiet) {
|
||||
chosen = PlatformProfile::LowPower;
|
||||
}
|
||||
}
|
||||
|
||||
self.config.lock().await.platform_profile_on_ac = chosen;
|
||||
self.set_platform_profile(ctxt, chosen).await?;
|
||||
self.config.lock().await.write();
|
||||
Ok(())
|
||||
}
|
||||
@@ -599,7 +619,7 @@ impl CtrlPlatform {
|
||||
|
||||
for attr in self.attributes.attributes() {
|
||||
let name: FirmwareAttribute = attr.name().into();
|
||||
if name.is_ppt() {
|
||||
if name.property_type() == FirmwareAttributeType::Ppt {
|
||||
// reset stored value
|
||||
if let Some(tune) = self
|
||||
.config
|
||||
@@ -634,6 +654,15 @@ impl CtrlPlatform {
|
||||
.enabled = enable;
|
||||
self.config.lock().await.write();
|
||||
|
||||
// Re-emit armoury attribute limits so GUI sees updated min/max for PPT
|
||||
// attributes which can change when enabling/disabling PPT tuning groups.
|
||||
// Fire-and-forget: we don't want to fail the property call if emit fails.
|
||||
let _ = self
|
||||
.armoury_registry
|
||||
.emit_limits(&self.connection)
|
||||
.await
|
||||
.map_err(|e| log::error!("Failed to emit armoury limits: {e:?}"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -692,6 +721,13 @@ impl ReloadAndNotify for CtrlPlatform {
|
||||
*config = data;
|
||||
config.base_charge_control_end_threshold =
|
||||
base_charge_control_end_threshold.unwrap_or_default();
|
||||
|
||||
// Ensure any armoury limits changes from the new config are emitted
|
||||
let _ = self
|
||||
.armoury_registry
|
||||
.emit_limits(&self.connection)
|
||||
.await
|
||||
.map_err(|e| log::error!("Failed to emit armoury limits after reload: {e:?}"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -19,11 +19,4 @@ LABEL="asusd_start"
|
||||
ACTION=="add|change", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
|
||||
ACTION=="add|remove", DRIVER=="asus-nb-wmi", TAG+="systemd", ENV{SYSTEMD_WANTS}+="asusd.service"
|
||||
|
||||
# ASUS Custom Fan Curve Control - Grant user write access
|
||||
# This allows rog-control-center to adjust fan curves without sudo
|
||||
SUBSYSTEM=="hwmon", ATTR{name}=="asus_custom_fan_curve", \
|
||||
RUN+="/bin/sh -c 'chmod 0666 /sys%p/pwm*'", \
|
||||
RUN+="/bin/sh -c 'chmod 0666 /sys%p/temp*_auto_point*_pwm'", \
|
||||
RUN+="/bin/sh -c 'chmod 0666 /sys%p/temp*_auto_point*_temp'"
|
||||
|
||||
LABEL="asusd_end"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
%global debug_package %{nil}
|
||||
%endif
|
||||
|
||||
%define version 6.3.0
|
||||
%define version 6.3.2
|
||||
%define specrelease %{?dist}
|
||||
%define pkg_release 1%{specrelease}
|
||||
|
||||
|
||||
23
extra/index.html
Normal file
23
extra/index.html
Normal file
@@ -0,0 +1,23 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<title>asusctl docs</title>
|
||||
<!-- Redirect to the generated crate docs -->
|
||||
<meta http-equiv="refresh" content="0;url=asusctl/index.html">
|
||||
<link rel="canonical" href="asusctl/index.html">
|
||||
<style>
|
||||
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; color:#222; display:flex; align-items:center; justify-content:center; height:100vh; margin:0 }
|
||||
.box { text-align:center }
|
||||
a { color: #0366d6 }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<h1>asusctl documentation</h1>
|
||||
<p>Redirecting to the generated docs — if your browser doesn't redirect automatically, <a href="asusctl/index.html">click here</a>.</p>
|
||||
<p>If you expected a different landing page, update <code>extra/index.html</code> accordingly.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
0
rog-anime/data/g835l/images/.gitkeep
Normal file
0
rog-anime/data/g835l/images/.gitkeep
Normal file
BIN
rog-anime/data/g835l/templates/custom-image-template.png
Normal file
BIN
rog-anime/data/g835l/templates/custom-image-template.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 518 B |
@@ -96,12 +96,17 @@ impl AnimeType {
|
||||
let board_name = DMIID::new().unwrap_or_default().board_name.to_uppercase();
|
||||
if board_name.contains("GA401I") || board_name.contains("GA401Q") {
|
||||
AnimeType::GA401
|
||||
} else if board_name.contains("GA402R") || board_name.contains("GA402X") {
|
||||
} else if board_name.contains("GA402R")
|
||||
|| board_name.contains("GA402X")
|
||||
|| board_name.contains("GA402N")
|
||||
{
|
||||
AnimeType::GA402
|
||||
} else if board_name.contains("GU604V") {
|
||||
AnimeType::GU604
|
||||
} else if board_name.contains("G635L") || board_name.contains("G635L") {
|
||||
} else if board_name.contains("G635L") {
|
||||
AnimeType::G635L
|
||||
} else if board_name.contains("G835L") {
|
||||
AnimeType::G835L
|
||||
} else {
|
||||
AnimeType::Unsupported
|
||||
}
|
||||
@@ -111,7 +116,9 @@ impl AnimeType {
|
||||
pub fn width(&self) -> usize {
|
||||
match self {
|
||||
AnimeType::GU604 => 70,
|
||||
AnimeType::G835L => 74,
|
||||
// TODO: Find G635L W*H
|
||||
AnimeType::G635L => 68,
|
||||
AnimeType::G835L => 68,
|
||||
_ => 74,
|
||||
}
|
||||
}
|
||||
@@ -121,7 +128,8 @@ impl AnimeType {
|
||||
match self {
|
||||
AnimeType::GA401 => 36,
|
||||
AnimeType::GU604 => 43,
|
||||
AnimeType::G835L => 39,
|
||||
AnimeType::G635L => 34,
|
||||
AnimeType::G835L => 34,
|
||||
_ => 39,
|
||||
}
|
||||
}
|
||||
@@ -130,8 +138,9 @@ impl AnimeType {
|
||||
pub fn data_length(&self) -> usize {
|
||||
match self {
|
||||
AnimeType::GA401 => PANE_LEN * 2,
|
||||
AnimeType::GU604 => PANE_LEN * 3,
|
||||
AnimeType::G835L => PANE_LEN * 3,
|
||||
// G835L has 810 LEDs: 210 (triangle) + 600 (staggered rectangle)
|
||||
AnimeType::G635L => 810, // TODO: This is provisional until we have a G635L to test on
|
||||
AnimeType::G835L => 810,
|
||||
_ => PANE_LEN * 3,
|
||||
}
|
||||
}
|
||||
@@ -195,29 +204,35 @@ impl TryFrom<AnimeDataBuffer> for AnimePacketType {
|
||||
}
|
||||
|
||||
let mut buffers = match anime.anime {
|
||||
AnimeType::GA401 => vec![[0; 640]; 2],
|
||||
AnimeType::GA402
|
||||
| AnimeType::GU604
|
||||
| AnimeType::G635L
|
||||
| AnimeType::G835L
|
||||
| AnimeType::Unsupported => {
|
||||
AnimeType::GA401 | AnimeType::G635L | AnimeType::G835L => vec![[0; 640]; 2],
|
||||
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported => {
|
||||
vec![[0; 640]; 3]
|
||||
}
|
||||
};
|
||||
|
||||
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
|
||||
buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk);
|
||||
// G835L has different packing: 627 bytes in pane 1, 183 bytes in pane 2
|
||||
if anime.anime == AnimeType::G835L || anime.anime == AnimeType::G635L {
|
||||
let data = anime.data.as_slice();
|
||||
// Pane 1: first 627 bytes
|
||||
let pane1_len = PANE_LEN.min(data.len());
|
||||
buffers[0][BLOCK_START..BLOCK_START + pane1_len].copy_from_slice(&data[..pane1_len]);
|
||||
// Pane 2: remaining bytes (183)
|
||||
if data.len() > PANE_LEN {
|
||||
let pane2_len = data.len() - PANE_LEN;
|
||||
buffers[1][BLOCK_START..BLOCK_START + pane2_len].copy_from_slice(&data[PANE_LEN..]);
|
||||
}
|
||||
} else {
|
||||
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
|
||||
buffers[idx][BLOCK_START..BLOCK_START + chunk.len()].copy_from_slice(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
buffers[0][..7].copy_from_slice(&USB_PREFIX1);
|
||||
buffers[1][..7].copy_from_slice(&USB_PREFIX2);
|
||||
|
||||
if matches!(
|
||||
anime.anime,
|
||||
AnimeType::GA402
|
||||
| AnimeType::GU604
|
||||
| AnimeType::G635L
|
||||
| AnimeType::G835L
|
||||
| AnimeType::Unsupported
|
||||
AnimeType::GA402 | AnimeType::GU604 | AnimeType::Unsupported
|
||||
) {
|
||||
buffers[2][..7].copy_from_slice(&USB_PREFIX3);
|
||||
}
|
||||
|
||||
@@ -146,6 +146,8 @@ impl AnimeDiagonal {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => self.to_ga401_packets(),
|
||||
AnimeType::GU604 => self.to_gu604_packets(),
|
||||
AnimeType::G635L => self.to_g835l_packets(), // TODO: Verify with G635L model
|
||||
AnimeType::G835L => self.to_g835l_packets(),
|
||||
_ => self.to_ga402_packets(),
|
||||
}
|
||||
}
|
||||
@@ -381,4 +383,80 @@ impl AnimeDiagonal {
|
||||
|
||||
AnimeDataBuffer::from_vec(crate::AnimeType::GA402, buf)
|
||||
}
|
||||
|
||||
/// G835L diagonal packing - inverted geometry (rows grow then constant)
|
||||
/// Triangle (rows 0-27): pairs grow from 1→14 LEDs
|
||||
/// Rectangle (rows 28-67): constant 15 LEDs
|
||||
///
|
||||
/// Diagonal PNG layout for G835L:
|
||||
/// - Image height = 34 (row pairs)
|
||||
/// - Image width = 68 (half-step X grid)
|
||||
/// - Even/odd rows are interleaved in X (staggered by 0.5 LED = 1 px)
|
||||
fn to_g835l_packets(&self) -> Result<AnimeDataBuffer> {
|
||||
use log::debug;
|
||||
|
||||
let mut buf = vec![0u8; AnimeType::G835L.data_length()];
|
||||
let mut buf_idx = 0usize;
|
||||
|
||||
debug!(
|
||||
"G835L packing: image dimensions {}x{}, buffer size {}",
|
||||
self.1.first().map(|r| r.len()).unwrap_or(0),
|
||||
self.1.len(),
|
||||
buf.len()
|
||||
);
|
||||
|
||||
// Helper: get row length for G835L
|
||||
fn row_length(row: usize) -> usize {
|
||||
if row < 28 {
|
||||
row / 2 + 1
|
||||
} else {
|
||||
15
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: starting X (in LED units) for the row
|
||||
fn first_x(row: usize) -> usize {
|
||||
if row < 28 {
|
||||
0
|
||||
} else {
|
||||
(row - 28) / 2
|
||||
}
|
||||
}
|
||||
|
||||
// Process all 68 rows
|
||||
for row in 0..68 {
|
||||
let len = row_length(row);
|
||||
let img_y = row / 2;
|
||||
let base_x = first_x(row);
|
||||
let stagger = row % 2;
|
||||
|
||||
for i in 0..len {
|
||||
// Half-step X grid: even rows on even pixels, odd rows on odd pixels.
|
||||
let img_x = (base_x + i) * 2 + stagger;
|
||||
|
||||
// Read from image, clamp to bounds
|
||||
let val = if img_y < self.1.len() && img_x < self.1[img_y].len() {
|
||||
self.1[img_y][img_x]
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
// Log first LED of each row for debugging
|
||||
if i == 0 {
|
||||
debug!(
|
||||
"Row {}: len={}, first LED at img[{}][{}] = {}",
|
||||
row, len, img_y, img_x, val
|
||||
);
|
||||
}
|
||||
|
||||
if buf_idx < buf.len() {
|
||||
buf[buf_idx] = val;
|
||||
}
|
||||
buf_idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
debug!("G835L packing complete: {} bytes written", buf_idx);
|
||||
AnimeDataBuffer::from_vec(AnimeType::G835L, buf)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,8 +137,8 @@ impl AnimeImage {
|
||||
fn scale_y(anime_type: AnimeType) -> f32 {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => 0.3,
|
||||
AnimeType::GU604 => 0.28,
|
||||
_ => 0.283,
|
||||
AnimeType::GA402 => 0.283,
|
||||
_ => 0.28,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ impl AnimeImage {
|
||||
/// square grid, so `first_x` is the x position on that grid where the
|
||||
/// LED is actually positioned in relation to the Y.
|
||||
///
|
||||
/// For GA401/GA402/GU604 (shrinking pattern - diagonal cuts in from left):
|
||||
/// ```text
|
||||
/// +------------+
|
||||
/// | |
|
||||
@@ -162,6 +163,19 @@ impl AnimeImage {
|
||||
/// ^ ------+
|
||||
/// first_x
|
||||
/// ```
|
||||
///
|
||||
/// For G835L/G635L (inverted pattern - triangle grows then rectangle shifts):
|
||||
/// ```text
|
||||
/// ● <- Row 0: first_x = 0, width = 1
|
||||
/// ● <- Row 1: first_x = 0 (stagger), width = 1
|
||||
/// ● ● <- Row 2: first_x = 0, width = 2
|
||||
/// ● ● <- Row 3: first_x = 0 (stagger), width = 2
|
||||
/// ... <- Triangle continues, first_x = 0 for rows 0-27
|
||||
/// ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● <- Row 28+: first_x grows
|
||||
/// ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● <- Rectangle shifts right
|
||||
/// ```
|
||||
/// Triangle (rows 0-27): first_x = 0 (no cumulative shift)
|
||||
/// Rectangle (rows 28-67): first_x = (y - 28) / 2 (shifts right)
|
||||
fn first_x(anime_type: AnimeType, y: u32) -> u32 {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => {
|
||||
@@ -179,6 +193,16 @@ impl AnimeImage {
|
||||
// and then their offset grows by one every two rows
|
||||
(y - 9) / 2
|
||||
}
|
||||
AnimeType::G635L | AnimeType::G835L => {
|
||||
// G835L/G635L have inverted geometry - triangle at top-left, rectangle shifts right
|
||||
// Triangle (rows 0-27): no cumulative shift, just alternating stagger
|
||||
// Rectangle (rows 28-67): shifts right by ~0.5px per row
|
||||
if y < 28 {
|
||||
0
|
||||
} else {
|
||||
(y - 28) / 2
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// first 11 rows start at zero
|
||||
if y <= 11 {
|
||||
@@ -221,6 +245,16 @@ impl AnimeImage {
|
||||
}
|
||||
38 - Self::first_x(anime_type, y) + y % 2
|
||||
}
|
||||
AnimeType::G635L | AnimeType::G835L => {
|
||||
// G835L/G635L rows GROW then stay constant (inverted from other devices)
|
||||
// Triangle (rows 0-27): pairs of rows with same length, 1→14
|
||||
// Rectangle (rows 28-67): constant 15 LEDs
|
||||
if y < 28 {
|
||||
y / 2 + 1
|
||||
} else {
|
||||
15
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if y <= 11 {
|
||||
return 34;
|
||||
@@ -235,8 +269,9 @@ impl AnimeImage {
|
||||
match anime_type {
|
||||
// 33.0 = Longest row LED count (physical) plus half-pixel offset
|
||||
AnimeType::GA401 => (33.0 + 0.5) * Self::scale_x(anime_type),
|
||||
|
||||
AnimeType::GU604 => (38.0 + 0.5) * Self::scale_x(anime_type),
|
||||
AnimeType::G635L => (33.0 + 0.5) * Self::scale_x(anime_type),
|
||||
AnimeType::G835L => (33.0 + 0.5) * Self::scale_x(anime_type),
|
||||
_ => (35.0 + 0.5) * Self::scale_x(anime_type),
|
||||
}
|
||||
}
|
||||
@@ -246,6 +281,8 @@ impl AnimeImage {
|
||||
match anime_type {
|
||||
AnimeType::GA401 => 55,
|
||||
AnimeType::GU604 => 62,
|
||||
AnimeType::G635L => 68,
|
||||
AnimeType::G835L => 68,
|
||||
_ => 61,
|
||||
}
|
||||
}
|
||||
@@ -256,6 +293,8 @@ impl AnimeImage {
|
||||
// 54.0 = End column LED count (physical) plus one dead pixel
|
||||
AnimeType::GA401 => (54.0 + 1.0) * Self::scale_y(anime_type),
|
||||
AnimeType::GU604 => 62.0 * Self::scale_y(anime_type),
|
||||
AnimeType::G635L => 68.0 * Self::scale_y(anime_type),
|
||||
AnimeType::G835L => 68.0 * Self::scale_y(anime_type),
|
||||
// GA402 may not have dead pixels and require only the physical LED count
|
||||
_ => 61.0 * Self::scale_y(anime_type),
|
||||
}
|
||||
@@ -269,8 +308,8 @@ impl AnimeImage {
|
||||
1 | 3 => 35, // Some rows are padded
|
||||
_ => 36 - y / 2,
|
||||
},
|
||||
AnimeType::GU604 => AnimeImage::width(anime_type, y),
|
||||
// GA402 does not have padding, equivalent to width
|
||||
|
||||
// Other devices don't have dead pixels
|
||||
_ => AnimeImage::width(anime_type, y),
|
||||
}
|
||||
}
|
||||
@@ -405,13 +444,35 @@ impl AnimeImage {
|
||||
let transform =
|
||||
Mat3::from_scale_angle_translation(self.scale, self.angle, self.translation);
|
||||
|
||||
let pos_in_leds = Mat3::from_translation(Vec2::new(20.0, 20.0));
|
||||
let pos_in_leds = Mat3::from_translation(self.led_center());
|
||||
// Get LED-to-image coords
|
||||
let led_from_px = pos_in_leds * led_from_cm * transform * cm_from_px * center;
|
||||
|
||||
led_from_px.inverse()
|
||||
}
|
||||
|
||||
fn led_center(&self) -> Vec2 {
|
||||
if !matches!(self.anime_type, AnimeType::G635L | AnimeType::G835L) {
|
||||
return Vec2::new(20.0, 20.0);
|
||||
}
|
||||
|
||||
let mut min = Vec2::splat(f32::INFINITY);
|
||||
let mut max = Vec2::splat(f32::NEG_INFINITY);
|
||||
for led in self.led_pos.iter().flatten() {
|
||||
let pos = Vec2::new(led.x(), led.y());
|
||||
min = min.min(pos);
|
||||
max = max.max(pos);
|
||||
}
|
||||
|
||||
if min.x.is_finite() {
|
||||
let mut center = (min + max) * 0.5;
|
||||
center.y += 1.0;
|
||||
center
|
||||
} else {
|
||||
Vec2::new(20.0, 20.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate the base image from inputs. The result can be displayed as is
|
||||
/// or updated via scale, position, or angle then displayed again after
|
||||
/// `update()`.
|
||||
|
||||
@@ -247,7 +247,10 @@ pub fn get_anime_type() -> AnimeType {
|
||||
|
||||
if board_name.contains("GA401I") || board_name.contains("GA401Q") {
|
||||
AnimeType::GA401
|
||||
} else if board_name.contains("GA402R") || board_name.contains("GA402X") {
|
||||
} else if board_name.contains("GA402R")
|
||||
|| board_name.contains("GA402X")
|
||||
|| board_name.contains("GA402N")
|
||||
{
|
||||
AnimeType::GA402
|
||||
} else if board_name.contains("GU604V") {
|
||||
AnimeType::GU604
|
||||
|
||||
BIN
rog-anime/tests/data/g835l-diagonal-fullbright.png
Normal file
BIN
rog-anime/tests/data/g835l-diagonal-fullbright.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 205 B |
BIN
rog-anime/tests/data/g835l-diagonal.gif
Normal file
BIN
rog-anime/tests/data/g835l-diagonal.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
BIN
rog-anime/tests/data/g835l-diagonal.png
Normal file
BIN
rog-anime/tests/data/g835l-diagonal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 B |
556
rog-anime/tests/g835l.rs
Normal file
556
rog-anime/tests/g835l.rs
Normal file
@@ -0,0 +1,556 @@
|
||||
// TODO: This is a provisional copy paste of GA401
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use rog_anime::*;
|
||||
|
||||
#[test]
|
||||
fn g835l_image_edge_packet_check() {
|
||||
let pkt0_check = [
|
||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt1_check = [
|
||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut matrix = AnimeImage::new(
|
||||
Vec2::new(1.0, 1.0),
|
||||
0.0,
|
||||
Vec2::default(),
|
||||
0.0,
|
||||
vec![Pixel::default(); 1000],
|
||||
100,
|
||||
AnimeType::G835L,
|
||||
)
|
||||
.unwrap();
|
||||
matrix.edge_outline();
|
||||
let data = AnimeDataBuffer::try_from(&matrix).unwrap();
|
||||
let pkt = AnimePacketType::try_from(data).unwrap();
|
||||
|
||||
assert_eq!(pkt[0], pkt0_check);
|
||||
assert_eq!(pkt[1], pkt1_check);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g835l_diagonal_packet_check() {
|
||||
let pkt0_check = [
|
||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt1_check = [
|
||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.push("tests/data/g835l-diagonal.png");
|
||||
|
||||
let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G835L).unwrap();
|
||||
let data = matrix.into_data_buffer(AnimeType::G835L).unwrap();
|
||||
let pkt = AnimePacketType::try_from(data).unwrap();
|
||||
|
||||
assert_eq!(pkt[0], pkt0_check);
|
||||
assert_eq!(pkt[1], pkt1_check);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g835l_diagonal_fullbright_packet_check() {
|
||||
let pkt0_check = [
|
||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt1_check = [
|
||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.push("tests/data/g835l-diagonal-fullbright.png");
|
||||
|
||||
let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G835L).unwrap();
|
||||
let data = matrix.into_data_buffer(AnimeType::G835L).unwrap();
|
||||
let pkt = AnimePacketType::try_from(data).unwrap();
|
||||
|
||||
assert_eq!(pkt[0], pkt0_check);
|
||||
assert_eq!(pkt[1], pkt1_check);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn g835l_diagonal_gif_wave_packet_check() {
|
||||
let pkt0_frame0_check = [
|
||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x7f, 0x92, 0x84, 0xa2, 0x95, 0xac, 0x8a,
|
||||
0xa0, 0xaf, 0x97, 0xa4, 0xa8, 0x91, 0x9c, 0x9e, 0x99, 0x98, 0x98, 0x91, 0x82, 0x99,
|
||||
0x97, 0x8d, 0x7c, 0x67, 0x99, 0x8d, 0x7a, 0x63, 0x4a, 0xa0, 0x92, 0x7d, 0x63, 0x48,
|
||||
0x2e, 0x9a, 0x83, 0x67, 0x4a, 0x2e, 0x17, 0xa6, 0x8d, 0x70, 0x50, 0x32, 0x19, 0x08,
|
||||
0x9a, 0x7b, 0x5a, 0x3b, 0x20, 0x0c, 0x02, 0xa8, 0x89, 0x67, 0x46, 0x2a, 0x15, 0x09,
|
||||
0x07, 0x97, 0x75, 0x54, 0x37, 0x21, 0x13, 0x10, 0x16, 0xa6, 0x84, 0x63, 0x45, 0x2e,
|
||||
0x20, 0x1c, 0x21, 0x2e, 0x91, 0x71, 0x54, 0x3d, 0x2f, 0x2a, 0x2e, 0x3a, 0x4c, 0x9d,
|
||||
0x7d, 0x61, 0x4c, 0x3e, 0x39, 0x3d, 0x49, 0x5a, 0x6d, 0x87, 0x6d, 0x58, 0x4c, 0x48,
|
||||
0x4c, 0x58, 0x69, 0x7c, 0x8e, 0x8e, 0x75, 0x63, 0x58, 0x55, 0x5a, 0x67, 0x78, 0x8b,
|
||||
0x9d, 0xab, 0x7a, 0x69, 0x60, 0x5f, 0x66, 0x74, 0x86, 0x9a, 0xac, 0xba, 0xc1, 0x7a,
|
||||
0x6c, 0x65, 0x66, 0x6f, 0x7f, 0x93, 0xa7, 0xba, 0xc9, 0xd0, 0xce, 0x6a, 0x65, 0x69,
|
||||
0x74, 0x86, 0x9c, 0xb2, 0xc7, 0xd6, 0xde, 0xdd, 0xd2, 0x63, 0x61, 0x67, 0x75, 0x89,
|
||||
0xa1, 0xba, 0xd0, 0xe1, 0xea, 0xea, 0xe0, 0xcc, 0x59, 0x61, 0x71, 0x88, 0xa2, 0xbd,
|
||||
0xd5, 0xe8, 0xf3, 0xf4, 0xec, 0xd9, 0xbf, 0x4e, 0x58, 0x6a, 0x82, 0x9e, 0xbc, 0xd6,
|
||||
0xeb, 0xf8, 0xfc, 0xf4, 0xe4, 0xca, 0xac, 0x4b, 0x5f, 0x79, 0x97, 0xb6, 0xd3, 0xea,
|
||||
0xf9, 0xfe, 0xf9, 0xea, 0xd3, 0xb6, 0x96, 0x3d, 0x51, 0x6c, 0x8c, 0xad, 0xcb, 0xe4,
|
||||
0xf6, 0xfd, 0xfa, 0xed, 0xd8, 0xbd, 0x9f, 0x82, 0x43, 0x5e, 0x7f, 0xa1, 0xc0, 0xdb,
|
||||
0xee, 0xf7, 0xf6, 0xeb, 0xd8, 0xc0, 0xa4, 0x89, 0x71, 0x50, 0x70, 0x92, 0xb3, 0xcf,
|
||||
0xe3, 0xee, 0xee, 0xe6, 0xd5, 0xbe, 0xa4, 0x8c, 0x76, 0x67, 0x62, 0x84, 0xa5, 0xc1,
|
||||
0xd5, 0xe1, 0xe3, 0xdc, 0xcd, 0xb8, 0xa1, 0x8a, 0x77, 0x6a, 0x64, 0x76, 0x96, 0xb2,
|
||||
0xc7, 0xd3, 0xd5, 0xcf, 0xc1, 0xae, 0x99, 0x84, 0x73, 0x68, 0x65, 0x6a, 0x89, 0xa4,
|
||||
0xb8, 0xc4, 0xc6, 0xc0, 0xb3, 0xa1, 0x8d, 0x7a, 0x6b, 0x63, 0x62, 0x69, 0x78, 0x98,
|
||||
0xab, 0xb5, 0xb8, 0xb1, 0xa4, 0x93, 0x7f, 0x6e, 0x60, 0x59, 0x5b, 0x64, 0x75, 0x8c,
|
||||
0xa0, 0xa9, 0xaa, 0xa3, 0x95, 0x83, 0x70, 0x5f, 0x53, 0x4d, 0x50, 0x5b, 0x6e, 0x87,
|
||||
0xa4, 0xa0, 0x9f, 0x96, 0x87, 0x74, 0x61, 0x50, 0x44, 0x3f, 0x42, 0x4f, 0x64, 0x7e,
|
||||
0x9d, 0xbc, 0x97, 0x8c, 0x7c, 0x68, 0x53, 0x41, 0x34, 0x2f, 0x33, 0x41, 0x56, 0x73,
|
||||
0x93, 0xb3, 0xd1, 0x86, 0x74, 0x5e, 0x47, 0x34, 0x27, 0x21, 0x25, 0x32, 0x48, 0x65,
|
||||
0x86, 0xa7, 0xc6, 0xe0, 0x70, 0x57, 0x3f, 0x2a, 0x1b, 0x14, 0x17, 0x24, 0x39, 0x56,
|
||||
0x77, 0x99, 0xb9, 0xd4, 0xe6, 0x56, 0x3b, 0x24, 0x13, 0x0a, 0x0c, 0x17, 0x2c, 0x48,
|
||||
0x69, 0x8b, 0xab, 0xc6, 0xd9, 0xe3, 0x3b, 0x22, 0x0f, 0x04, 0x04, 0x0e, 0x21, 0x3c,
|
||||
0x5b, 0x7d, 0x9c, 0xb7, 0xca, 0xd5, 0xd6, 0x25, 0x0f, 0x03, 0x00, 0x08, 0x19, 0x32,
|
||||
0x50, 0x70, 0x8f, 0xa9, 0xbc, 0xc6, 0xc7, 0xc0, 0x14, 0x05, 0x01, 0x06, 0x15, 0x2c,
|
||||
0x49, 0x67, 0x84, 0x9c, 0xae, 0xb7, 0xb8, 0xb0, 0xa2, 0x0c, 0x05, 0x09, 0x16, 0x2b,
|
||||
0x45, 0x61, 0x7c, 0x93, 0xa3, 0xab, 0xaa, 0xa2, 0x93, 0x81, 0x0e, 0x10, 0x1b, 0x2e,
|
||||
0x46, 0x60, 0x78, 0x8d, 0x9b, 0xa1, 0x9e, 0x94, 0x85, 0x72, 0x5f, 0x1b, 0x24, 0x35,
|
||||
0x4b, 0x62, 0x79, 0x8b, 0x96, 0x9a, 0x96, 0x8a, 0x79, 0x65, 0x50, 0x3f, 0x30, 0x40,
|
||||
0x54, 0x6a, 0x7e, 0x8d, 0x97, 0x98, 0x91, 0x84, 0x70, 0x5a, 0x44, 0x32, 0x26, 0x4d,
|
||||
0x60, 0x74, 0x87, 0x94, 0x9b, 0x9a, 0x91, 0x81, 0x6c, 0x53, 0x3c, 0x28, 0x1a, 0x15,
|
||||
0x6e, 0x82, 0x93, 0x9f, 0xa4, 0xa1, 0x96, 0x83, 0x6b, 0x51, 0x37, 0x21, 0x11, 0x0a,
|
||||
0x0e, 0x91, 0xa1, 0xac, 0xb0, 0xab, 0x9e, 0x89, 0x6f, 0x53, 0x37, 0x1e, 0x0d, 0x04,
|
||||
0x05, 0x11, 0xb0, 0xbb, 0xbe, 0xb8, 0xaa, 0x93, 0x77, 0x59, 0x3a, 0x20, 0x0c, 0x01,
|
||||
0x01, 0x0a, 0x1d, 0xca, 0xcd, 0xc7, 0xb7, 0xa0, 0x83, 0x62, 0x42, 0x26, 0x10, 0x03,
|
||||
0x01, 0x08, 0x19, 0x31, 0xdc, 0xd6, 0xc6, 0xae, 0x90, 0x6f, 0x4e, 0x30, 0x18, 0x0a,
|
||||
0x05, 0x0a, 0x19, 0x2f, 0x4a, 0xe4, 0xd4, 0xbd, 0x9f, 0x7d, 0x5b, 0x3c, 0x24, 0x14,
|
||||
0x0d, 0x11, 0x1e, 0x32, 0x4a, 0x64, 0xe1, 0xcb, 0xad, 0x8c, 0x6a, 0x4b, 0x31, 0x20,
|
||||
0x19, 0x1b, 0x26, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt1_frame0_check = [
|
||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x4f, 0x66, 0x7c, 0xd6, 0xba, 0x99, 0x78,
|
||||
0x59, 0x40, 0x2f, 0x27, 0x28, 0x32, 0x42, 0x57, 0x6d, 0x80, 0x8f, 0xc4, 0xa5, 0x85,
|
||||
0x67, 0x4f, 0x3e, 0x35, 0x37, 0x40, 0x4f, 0x63, 0x77, 0x89, 0x96, 0x9b, 0xad, 0x8f,
|
||||
0x73, 0x5c, 0x4c, 0x44, 0x46, 0x4f, 0x5e, 0x71, 0x84, 0x94, 0xa0, 0xa3, 0x9f, 0x96,
|
||||
0x7b, 0x66, 0x58, 0x52, 0x54, 0x5e, 0x6e, 0x80, 0x93, 0xa2, 0xac, 0xaf, 0xa9, 0x9a,
|
||||
0x80, 0x6d, 0x61, 0x5c, 0x60, 0x6c, 0x7c, 0x8f, 0xa2, 0xb2, 0xbb, 0xbd, 0xb5, 0xa5,
|
||||
0x8e, 0x70, 0x66, 0x64, 0x6a, 0x77, 0x89, 0x9d, 0xb1, 0xc1, 0xca, 0xcb, 0xc4, 0xb3,
|
||||
0x9a, 0x7c, 0x66, 0x67, 0x6f, 0x7e, 0x92, 0xa8, 0xbd, 0xce, 0xd9, 0xda, 0xd3, 0xc1,
|
||||
0xa8, 0x8a, 0x68, 0x65, 0x70, 0x82, 0x98, 0xb0, 0xc7, 0xd9, 0xe5, 0xe8, 0xe1, 0xd0,
|
||||
0xb7, 0x98, 0x76, 0x54, 0x6d, 0x81, 0x99, 0xb3, 0xcd, 0xe1, 0xee, 0xf3, 0xed, 0xdd,
|
||||
0xc5, 0xa6, 0x85, 0x63, 0x45, 0x7b, 0x96, 0xb3, 0xce, 0xe5, 0xf4, 0xfa, 0xf6, 0xe8,
|
||||
0xd1, 0xb4, 0x93, 0x71, 0x53, 0x3b, 0x8f, 0xad, 0xcb, 0xe4, 0xf5, 0xfe, 0xfc, 0xef,
|
||||
0xda, 0xbe, 0x9f, 0x7f, 0x61, 0x4a, 0x3b, 0xa5, 0xc4, 0xdf, 0xf2, 0xfd, 0xfd, 0xf2,
|
||||
0xdf, 0xc5, 0xa8, 0x89, 0x6e, 0x57, 0x49, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt0_frame16_check = [
|
||||
0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x95, 0x88, 0x92, 0x75, 0x81, 0x60, 0x8f,
|
||||
0x6d, 0x4c, 0x7c, 0x5a, 0x3c, 0x8a, 0x69, 0x4a, 0x32, 0x77, 0x59, 0x41, 0x32, 0x83,
|
||||
0x66, 0x50, 0x40, 0x3a, 0x72, 0x5c, 0x4e, 0x49, 0x4c, 0x79, 0x66, 0x59, 0x56, 0x5a,
|
||||
0x65, 0x6c, 0x61, 0x5f, 0x66, 0x72, 0x84, 0x6d, 0x66, 0x66, 0x6e, 0x7d, 0x90, 0xa5,
|
||||
0x65, 0x68, 0x72, 0x83, 0x99, 0xaf, 0xc5, 0x61, 0x65, 0x72, 0x86, 0x9d, 0xb6, 0xcd,
|
||||
0xdf, 0x5f, 0x6e, 0x84, 0x9d, 0xb9, 0xd2, 0xe6, 0xf2, 0x55, 0x66, 0x7d, 0x99, 0xb7,
|
||||
0xd2, 0xe8, 0xf7, 0xfc, 0x5a, 0x73, 0x91, 0xb1, 0xce, 0xe6, 0xf7, 0xfe, 0xfb, 0x4c,
|
||||
0x67, 0x86, 0xa7, 0xc6, 0xe0, 0xf3, 0xfc, 0xfb, 0xf0, 0x58, 0x78, 0x9a, 0xbb, 0xd6,
|
||||
0xeb, 0xf6, 0xf7, 0xed, 0xdc, 0x4a, 0x6a, 0x8c, 0xad, 0xca, 0xdf, 0xec, 0xee, 0xe7,
|
||||
0xd7, 0xc1, 0x5b, 0x7d, 0x9f, 0xbc, 0xd2, 0xdf, 0xe3, 0xdd, 0xcf, 0xbb, 0xa4, 0x4f,
|
||||
0x70, 0x90, 0xad, 0xc3, 0xd0, 0xd5, 0xd0, 0xc3, 0xb1, 0x9b, 0x87, 0x64, 0x83, 0x9f,
|
||||
0xb4, 0xc1, 0xc6, 0xc1, 0xb5, 0xa3, 0x90, 0x7c, 0x6d, 0x5c, 0x79, 0x93, 0xa7, 0xb3,
|
||||
0xb7, 0xb2, 0xa6, 0x95, 0x81, 0x6f, 0x61, 0x59, 0x73, 0x8b, 0x9d, 0xa7, 0xa9, 0xa3,
|
||||
0x97, 0x85, 0x72, 0x60, 0x53, 0x4c, 0x4e, 0x70, 0x86, 0x96, 0x9e, 0x9f, 0x97, 0x89,
|
||||
0x77, 0x63, 0x51, 0x44, 0x3e, 0x40, 0x4b, 0x86, 0x93, 0x99, 0x97, 0x8e, 0x7e, 0x6a,
|
||||
0x55, 0x43, 0x35, 0x2f, 0x31, 0x3d, 0x51, 0x8a, 0x95, 0x99, 0x94, 0x88, 0x76, 0x61,
|
||||
0x4a, 0x36, 0x27, 0x20, 0x22, 0x2e, 0x43, 0x5f, 0x9b, 0x9c, 0x96, 0x87, 0x73, 0x5b,
|
||||
0x43, 0x2d, 0x1c, 0x14, 0x15, 0x20, 0x34, 0x50, 0x71, 0xa4, 0x9b, 0x8b, 0x74, 0x5a,
|
||||
0x3f, 0x27, 0x15, 0x0b, 0x0a, 0x14, 0x27, 0x42, 0x62, 0x84, 0xa5, 0x92, 0x7a, 0x5d,
|
||||
0x40, 0x26, 0x11, 0x05, 0x03, 0x0b, 0x1d, 0x36, 0x55, 0x76, 0x96, 0x9d, 0x83, 0x64,
|
||||
0x45, 0x29, 0x12, 0x04, 0x00, 0x06, 0x15, 0x2d, 0x4b, 0x6a, 0x89, 0xa4, 0x8f, 0x6f,
|
||||
0x4e, 0x30, 0x18, 0x07, 0x01, 0x05, 0x12, 0x28, 0x44, 0x62, 0x7f, 0x98, 0xab, 0x7c,
|
||||
0x5a, 0x3b, 0x21, 0x0f, 0x06, 0x08, 0x14, 0x27, 0x41, 0x5c, 0x77, 0x8f, 0xa0, 0xa9,
|
||||
0x68, 0x48, 0x2d, 0x1a, 0x10, 0x10, 0x19, 0x2b, 0x42, 0x5c, 0x74, 0x89, 0x98, 0xa0,
|
||||
0x9e, 0x57, 0x3b, 0x27, 0x1c, 0x1b, 0x23, 0x33, 0x48, 0x5f, 0x76, 0x88, 0x95, 0x9a,
|
||||
0x97, 0x8c, 0x4a, 0x36, 0x2a, 0x28, 0x2f, 0x3e, 0x51, 0x67, 0x7b, 0x8c, 0x96, 0x99,
|
||||
0x93, 0x86, 0x73, 0x44, 0x39, 0x37, 0x3e, 0x4b, 0x5e, 0x72, 0x85, 0x93, 0x9b, 0x9c,
|
||||
0x94, 0x84, 0x6f, 0x57, 0x48, 0x46, 0x4d, 0x5b, 0x6c, 0x80, 0x91, 0x9e, 0xa4, 0xa3,
|
||||
0x99, 0x87, 0x70, 0x55, 0x3b, 0x54, 0x5c, 0x6a, 0x7c, 0x8f, 0xa0, 0xac, 0xb1, 0xad,
|
||||
0xa1, 0x8e, 0x74, 0x58, 0x3b, 0x22, 0x69, 0x78, 0x8b, 0x9e, 0xaf, 0xbb, 0xbf, 0xbb,
|
||||
0xad, 0x98, 0x7d, 0x5e, 0x40, 0x24, 0x0f, 0x84, 0x98, 0xac, 0xbe, 0xca, 0xce, 0xc9,
|
||||
0xbb, 0xa5, 0x89, 0x68, 0x48, 0x2b, 0x14, 0x05, 0xa2, 0xb8, 0xcb, 0xd8, 0xdd, 0xd8,
|
||||
0xca, 0xb3, 0x96, 0x75, 0x54, 0x35, 0x1c, 0x0c, 0x05, 0xc0, 0xd5, 0xe3, 0xea, 0xe6,
|
||||
0xd8, 0xc2, 0xa5, 0x84, 0x61, 0x42, 0x28, 0x16, 0x0e, 0x10, 0xdb, 0xec, 0xf4, 0xf1,
|
||||
0xe5, 0xd0, 0xb3, 0x92, 0x70, 0x50, 0x36, 0x23, 0x1a, 0x1b, 0x24, 0xf0, 0xfa, 0xfa,
|
||||
0xef, 0xdb, 0xc0, 0xa0, 0x7e, 0x5f, 0x45, 0x32, 0x28, 0x28, 0x31, 0x40, 0xfc, 0xfe,
|
||||
0xf5, 0xe3, 0xc9, 0xab, 0x8b, 0x6c, 0x53, 0x41, 0x37, 0x37, 0x3f, 0x4e, 0x61, 0xfd,
|
||||
0xf7, 0xe7, 0xcf, 0xb3, 0x94, 0x78, 0x60, 0x4f, 0x46, 0x46, 0x4e, 0x5d, 0x6f, 0x82,
|
||||
0xf4, 0xe7, 0xd1, 0xb7, 0x9b, 0x80, 0x6a, 0x5a, 0x53, 0x54, 0x5d, 0x6c, 0x7e, 0x91,
|
||||
0xa1, 0xe2, 0xce, 0xb6, 0x9c, 0x84, 0x70, 0x62, 0x5d, 0x60, 0x6a, 0x7a, 0x8d, 0xa0,
|
||||
0xb1, 0xbb, 0xc8, 0xb2, 0x9a, 0x84, 0x72, 0x67, 0x64, 0x69, 0x75, 0x86, 0x9b, 0xaf,
|
||||
0xbf, 0xca, 0xcd, 0xa9, 0x93, 0x7f, 0x70, 0x67, 0x66, 0x6d, 0x7c, 0x8f, 0xa5, 0xbb,
|
||||
0xcd, 0xd8, 0xdc, 0xd5, 0x89, 0x76, 0x69, 0x63, 0x64, 0x6e, 0x7e, 0x94, 0xac, 0xc4,
|
||||
0xd8, 0xe5, 0xe9, 0xe3, 0xd4, 0x6b, 0x5f, 0x5a, 0x5e, 0x6a, 0x7d, 0x95, 0xaf, 0xc9,
|
||||
0xdf, 0xed, 0xf3, 0xef, 0xe1, 0xca, 0x52, 0x4f, 0x54, 0x62, 0x77, 0x91, 0xae, 0xca,
|
||||
0xe1, 0xf2, 0xfa, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
let pkt1_frame16_check = [
|
||||
0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0xeb, 0xd6, 0xb9, 0x41, 0x47, 0x56, 0x6d,
|
||||
0x89, 0xa8, 0xc6, 0xe0, 0xf3, 0xfd, 0xfd, 0xf2, 0xde, 0xc4, 0xa4, 0x39, 0x49, 0x61,
|
||||
0x7e, 0x9f, 0xbe, 0xda, 0xef, 0xfb, 0xfd, 0xf5, 0xe3, 0xca, 0xad, 0x8f, 0x3a, 0x53,
|
||||
0x71, 0x92, 0xb3, 0xd1, 0xe7, 0xf5, 0xf9, 0xf3, 0xe3, 0xcd, 0xb2, 0x95, 0x7b, 0x44,
|
||||
0x62, 0x84, 0xa6, 0xc4, 0xdc, 0xec, 0xf1, 0xed, 0xdf, 0xcb, 0xb2, 0x98, 0x80, 0x6d,
|
||||
0x54, 0x76, 0x97, 0xb6, 0xcf, 0xdf, 0xe6, 0xe3, 0xd7, 0xc5, 0xae, 0x96, 0x80, 0x6f,
|
||||
0x66, 0x68, 0x89, 0xa7, 0xc0, 0xd1, 0xd8, 0xd6, 0xcc, 0xbb, 0xa6, 0x90, 0x7c, 0x6e,
|
||||
0x66, 0x67, 0x7c, 0x9a, 0xb2, 0xc2, 0xc9, 0xc8, 0xbe, 0xae, 0x9a, 0x86, 0x74, 0x68,
|
||||
0x63, 0x65, 0x70, 0x8e, 0xa4, 0xb4, 0xba, 0xb8, 0xaf, 0x9f, 0x8c, 0x79, 0x69, 0x5e,
|
||||
0x5b, 0x60, 0x6d, 0x81, 0x9a, 0xa8, 0xad, 0xaa, 0x9f, 0x90, 0x7d, 0x6a, 0x5b, 0x52,
|
||||
0x50, 0x57, 0x66, 0x7c, 0x96, 0x9e, 0xa2, 0x9d, 0x92, 0x81, 0x6e, 0x5b, 0x4c, 0x43,
|
||||
0x42, 0x4a, 0x5b, 0x73, 0x8f, 0xae, 0x9a, 0x94, 0x86, 0x74, 0x60, 0x4c, 0x3d, 0x34,
|
||||
0x33, 0x3c, 0x4d, 0x66, 0x85, 0xa5, 0xc4, 0x8e, 0x7f, 0x6a, 0x54, 0x40, 0x2f, 0x25,
|
||||
0x24, 0x2d, 0x3f, 0x58, 0x78, 0x99, 0xba, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||
path.push("tests/data/g835l-diagonal.gif");
|
||||
|
||||
let gif =
|
||||
AnimeGif::from_diagonal_gif(&path, AnimTime::Count(1), 1.0, AnimeType::G835L).unwrap();
|
||||
assert_eq!(gif.frame_count(), 48);
|
||||
|
||||
let pkt = AnimePacketType::try_from(gif.frames()[0].frame().clone()).unwrap();
|
||||
assert_eq!(pkt[0], pkt0_frame0_check);
|
||||
assert_eq!(pkt[1], pkt1_frame0_check);
|
||||
|
||||
let pkt = AnimePacketType::try_from(gif.frames()[16].frame().clone()).unwrap();
|
||||
assert_eq!(pkt[0], pkt0_frame16_check);
|
||||
assert_eq!(pkt[1], pkt1_frame16_check);
|
||||
}
|
||||
}
|
||||
@@ -125,7 +125,7 @@
|
||||
advanced_type: r#None,
|
||||
power_zones: [Keyboard],
|
||||
),
|
||||
(
|
||||
(
|
||||
device_name: "FX607V",
|
||||
product_id: "",
|
||||
layout_name: "fa506i",
|
||||
@@ -332,6 +332,15 @@
|
||||
advanced_type: r#None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G615LR",
|
||||
product_id: "",
|
||||
layout_name: "g634j-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave],
|
||||
basic_zones: [Key1, Key2, Key3, Key4],
|
||||
advanced_type: r#None,
|
||||
power_zones: [Keyboard, Lightbar],
|
||||
),
|
||||
(
|
||||
device_name: "G634J",
|
||||
product_id: "",
|
||||
@@ -342,13 +351,13 @@
|
||||
power_zones: [Keyboard, Lightbar, Logo, RearGlow],
|
||||
),
|
||||
(
|
||||
device_name: "G635L",
|
||||
product_id: "",
|
||||
layout_name: "g635l-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
device_name: "G635L",
|
||||
product_id: "",
|
||||
layout_name: "g635l-per-key",
|
||||
basic_modes: [Static, Breathe, RainbowCycle, RainbowWave, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||
basic_zones: [],
|
||||
advanced_type: PerKey,
|
||||
power_zones: [Keyboard, Lightbar, Logo],
|
||||
),
|
||||
(
|
||||
device_name: "G712LI",
|
||||
@@ -989,4 +998,4 @@
|
||||
advanced_type: r#None,
|
||||
power_zones: [Ally],
|
||||
),
|
||||
])
|
||||
])
|
||||
@@ -29,7 +29,6 @@ rog_dbus = { path = "../rog-dbus" }
|
||||
rog_aura = { path = "../rog-aura" }
|
||||
rog_profiles = { path = "../rog-profiles" }
|
||||
rog_platform = { path = "../rog-platform" }
|
||||
rog_slash = { path = "../rog-slash" }
|
||||
supergfxctl = { git = "https://gitlab.com/asus-linux/supergfxctl.git", default-features = false }
|
||||
dmi_id = { path = "../dmi-id" }
|
||||
|
||||
@@ -40,7 +39,6 @@ env_logger.workspace = true
|
||||
tokio.workspace = true
|
||||
serde.workspace = true
|
||||
zbus.workspace = true
|
||||
ron.workspace = true
|
||||
dirs.workspace = true
|
||||
notify-rust.workspace = true
|
||||
concat-idents.workspace = true
|
||||
|
||||
@@ -11,21 +11,16 @@ use gumdrop::Options;
|
||||
use log::{debug, info, warn, LevelFilter};
|
||||
use rog_control_center::cli_options::CliStart;
|
||||
use rog_control_center::config::Config;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
thread_local! {
|
||||
pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default();
|
||||
pub static TRAY_TOOLTIP: std::cell::RefCell<Option<TrayTooltip>> = Default::default();
|
||||
}
|
||||
use rog_control_center::error::Result;
|
||||
use rog_control_center::notify::start_notifications;
|
||||
use rog_control_center::slint::ComponentHandle;
|
||||
use rog_control_center::tray::{init_tray, TrayEvent, TrayStats};
|
||||
use rog_control_center::tray::init_tray;
|
||||
use rog_control_center::ui::setup_window;
|
||||
use rog_control_center::zbus_proxies::{
|
||||
AppState, ROGCCZbus, ROGCCZbusProxyBlocking, ZBUS_IFACE, ZBUS_PATH,
|
||||
};
|
||||
use rog_control_center::{print_versions, MainWindow, TrayTooltip};
|
||||
use rog_control_center::{print_versions, MainWindow};
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
@@ -153,6 +148,12 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
};
|
||||
|
||||
let is_tuf = {
|
||||
let b = board_name.to_lowercase();
|
||||
let p = prod_family.to_lowercase();
|
||||
b.contains("tuf") || p.contains("tuf")
|
||||
};
|
||||
|
||||
#[cfg(feature = "rog_ally")]
|
||||
if is_rog_ally {
|
||||
config.notifications.enabled = false;
|
||||
@@ -170,33 +171,17 @@ async fn main() -> Result<()> {
|
||||
|
||||
start_notifications(config.clone(), &rt)?;
|
||||
|
||||
let (tray_tx, mut tray_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
// Channel for broadcasting system stats to the tray tooltip
|
||||
let (stats_tx, stats_rx) = tokio::sync::watch::channel(TrayStats::default());
|
||||
|
||||
if enable_tray_icon {
|
||||
init_tray(supported_properties, config.clone(), tray_tx, stats_rx);
|
||||
init_tray(supported_properties, config.clone());
|
||||
}
|
||||
|
||||
thread_local! { pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default()};
|
||||
// i_slint_backend_selector::with_platform(|_| Ok(())).unwrap();
|
||||
|
||||
if !startup_in_background {
|
||||
if let Ok(mut app_state) = app_state.lock() {
|
||||
*app_state = AppState::MainWindowShouldOpen;
|
||||
}
|
||||
} else {
|
||||
// Even in background, we need the UI handle for status polling and tray sync
|
||||
let config_copy = config.clone();
|
||||
let stats_tx_copy = stats_tx.clone();
|
||||
slint::invoke_from_event_loop(move || {
|
||||
UI.with(|ui_cell| {
|
||||
let mut ui = ui_cell.borrow_mut();
|
||||
if ui.is_none() {
|
||||
let newui = setup_window(config_copy, stats_tx_copy.clone());
|
||||
ui.replace(newui);
|
||||
}
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
if std::env::var("RUST_TRANSLATIONS").is_ok() {
|
||||
@@ -208,21 +193,18 @@ async fn main() -> Result<()> {
|
||||
slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/"));
|
||||
}
|
||||
|
||||
// Prefetch supported Aura modes once at startup and move into the
|
||||
// spawned UI thread so the UI uses a stable, immutable list.
|
||||
let prefetched_supported: std::sync::Arc<Option<Vec<i32>>> = std::sync::Arc::new(
|
||||
rog_control_center::ui::setup_aura::prefetch_supported_basic_modes().await,
|
||||
);
|
||||
|
||||
thread::spawn(move || {
|
||||
let mut state = AppState::StartingUp;
|
||||
loop {
|
||||
// Handle tray events
|
||||
while let Ok(event) = tray_rx.try_recv() {
|
||||
match event {
|
||||
TrayEvent::ToggleTooltip(_, _) => {
|
||||
// Native tooltip handled by ksni, no custom window needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_rog_ally {
|
||||
let config_copy_2 = config.clone();
|
||||
let newui = setup_window(config.clone(), stats_tx.clone());
|
||||
let newui = setup_window(config.clone(), prefetched_supported.clone(), is_tuf);
|
||||
newui.window().on_close_requested(move || {
|
||||
exit(0);
|
||||
});
|
||||
@@ -263,7 +245,9 @@ async fn main() -> Result<()> {
|
||||
|
||||
let config_copy = config.clone();
|
||||
let app_state_copy = app_state.clone();
|
||||
let stats_tx_loop = stats_tx.clone();
|
||||
// Avoid moving the original `prefetched_supported` into the
|
||||
// closure — clone an Arc for the closure to capture.
|
||||
let pref_for_invoke = prefetched_supported.clone();
|
||||
slint::invoke_from_event_loop(move || {
|
||||
UI.with(|ui| {
|
||||
let app_state_copy = app_state_copy.clone();
|
||||
@@ -278,7 +262,7 @@ async fn main() -> Result<()> {
|
||||
});
|
||||
} else {
|
||||
let config_copy_2 = config_copy.clone();
|
||||
let newui = setup_window(config_copy, stats_tx_loop.clone());
|
||||
let newui = setup_window(config_copy, pref_for_invoke.clone(), is_tuf);
|
||||
newui.window().on_close_requested(move || {
|
||||
if let Ok(mut app_state) = app_state_copy.lock() {
|
||||
*app_state = AppState::MainWindowClosed;
|
||||
|
||||
@@ -11,8 +11,6 @@ use std::time::Duration;
|
||||
|
||||
use log::{debug, error, info, warn};
|
||||
use notify_rust::{Hint, Notification, Timeout};
|
||||
use rog_dbus::zbus_platform::PlatformProxy;
|
||||
use rog_platform::platform::PlatformProfile;
|
||||
use rog_platform::power::AsusPower;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use supergfxctl::pci_device::GfxPower;
|
||||
@@ -30,7 +28,6 @@ pub struct EnabledNotifications {
|
||||
pub enabled: bool,
|
||||
pub receive_notify_gfx: bool,
|
||||
pub receive_notify_gfx_status: bool,
|
||||
pub receive_notify_platform_profile: bool,
|
||||
}
|
||||
|
||||
impl Default for EnabledNotifications {
|
||||
@@ -39,7 +36,6 @@ impl Default for EnabledNotifications {
|
||||
enabled: true,
|
||||
receive_notify_gfx: true,
|
||||
receive_notify_gfx_status: true,
|
||||
receive_notify_platform_profile: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,57 +86,6 @@ fn start_dpu_status_mon(config: Arc<Mutex<Config>>) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Start monitoring for platform profile changes (triggered by Fn+F5 or software)
|
||||
/// and display an OSD notification when the profile changes.
|
||||
fn start_platform_profile_mon(config: Arc<Mutex<Config>>, rt: &Runtime) {
|
||||
let enabled_notifications_copy = config.clone();
|
||||
rt.spawn(async move {
|
||||
let conn = match zbus::Connection::system().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
error!("zbus signal: platform_profile_mon: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let proxy = match PlatformProxy::builder(&conn).build().await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
error!("zbus signal: platform_profile_mon proxy: {e}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Get initial profile to avoid notification on startup
|
||||
let mut last_profile = proxy.platform_profile().await.ok();
|
||||
|
||||
info!("Started platform profile change monitor");
|
||||
use futures_util::StreamExt;
|
||||
let mut stream = proxy.receive_platform_profile_changed().await;
|
||||
while let Some(e) = stream.next().await {
|
||||
if let Ok(config) = enabled_notifications_copy.lock() {
|
||||
if !config.notifications.enabled
|
||||
|| !config.notifications.receive_notify_platform_profile
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Ok(new_profile) = e.get().await {
|
||||
// Only show notification if profile actually changed
|
||||
if last_profile != Some(new_profile) {
|
||||
debug!("Platform profile changed to: {:?}", new_profile);
|
||||
if let Err(e) = do_platform_profile_notif("Power Profile:", &new_profile)
|
||||
.show()
|
||||
.map(|n| n.on_close(|_| ()))
|
||||
{
|
||||
warn!("Failed to show platform profile notification: {e}");
|
||||
}
|
||||
last_profile = Some(new_profile);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn start_notifications(
|
||||
config: Arc<Mutex<Config>>,
|
||||
rt: &Runtime,
|
||||
@@ -199,9 +144,6 @@ pub fn start_notifications(
|
||||
info!("Attempting to start plain dgpu status monitor");
|
||||
start_dpu_status_mon(config.clone());
|
||||
|
||||
info!("Starting platform profile change monitor");
|
||||
start_platform_profile_mon(config.clone(), rt);
|
||||
|
||||
// GPU MUX Mode notif
|
||||
// TODO: need to get armoury attrs and iter to find
|
||||
// let enabled_notifications_copy = config.clone();
|
||||
@@ -267,28 +209,3 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Notification {
|
||||
notif.icon(icon);
|
||||
notif
|
||||
}
|
||||
|
||||
/// Create a notification for platform profile (power mode) changes.
|
||||
/// Uses profile-specific icons and user-friendly names.
|
||||
fn do_platform_profile_notif(message: &str, profile: &PlatformProfile) -> Notification {
|
||||
let profile_name = match profile {
|
||||
PlatformProfile::Balanced => "Balanced",
|
||||
PlatformProfile::Performance => "Performance",
|
||||
PlatformProfile::Quiet => "Quiet",
|
||||
PlatformProfile::LowPower => "Low Power",
|
||||
PlatformProfile::Custom => "Custom",
|
||||
};
|
||||
let mut notif = base_notification(message, &profile_name.to_owned());
|
||||
|
||||
// Use appropriate icons for each profile
|
||||
// These icons should be available in the system or ROG icon pack
|
||||
let icon = match profile {
|
||||
PlatformProfile::Balanced => "asus_notif_blue", // Blue for balanced
|
||||
PlatformProfile::Performance => "asus_notif_red", // Red for performance
|
||||
PlatformProfile::Quiet => "asus_notif_green", // Green for quiet/power saving
|
||||
PlatformProfile::LowPower => "asus_notif_green", // Green for low power
|
||||
PlatformProfile::Custom => "asus_notif_white", // White for custom
|
||||
};
|
||||
notif.icon(icon);
|
||||
notif
|
||||
}
|
||||
|
||||
@@ -59,29 +59,6 @@ struct AsusTray {
|
||||
current_title: String,
|
||||
current_icon: Icon,
|
||||
proxy: ROGCCZbusProxyBlocking<'static>,
|
||||
tray_channel: Option<tokio::sync::mpsc::UnboundedSender<TrayEvent>>,
|
||||
// System stats for native tooltip
|
||||
cpu_temp: String,
|
||||
gpu_temp: String,
|
||||
cpu_fan: String,
|
||||
gpu_fan: String,
|
||||
power_w: String,
|
||||
power_profile: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum TrayEvent {
|
||||
ToggleTooltip(i32, i32),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct TrayStats {
|
||||
pub cpu_temp: String,
|
||||
pub gpu_temp: String,
|
||||
pub cpu_fan: String,
|
||||
pub gpu_fan: String,
|
||||
pub power_w: String,
|
||||
pub power_profile: String,
|
||||
}
|
||||
|
||||
impl ksni::Tray for AsusTray {
|
||||
@@ -101,26 +78,6 @@ impl ksni::Tray for AsusTray {
|
||||
ksni::Status::Active
|
||||
}
|
||||
|
||||
fn activate(&mut self, x: i32, y: i32) {
|
||||
if let Some(tx) = &self.tray_channel {
|
||||
let _ = tx.send(TrayEvent::ToggleTooltip(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
fn tool_tip(&self) -> ksni::ToolTip {
|
||||
ksni::ToolTip {
|
||||
title: "ROG Control Center".into(),
|
||||
description: format!(
|
||||
"<b>Profile:</b> {}\n<b>CPU:</b> {}°C | <b>GPU:</b> {}°C\n<b>Fans:</b> {} / {} RPM\n<b>Power:</b> {} W",
|
||||
self.power_profile,
|
||||
self.cpu_temp, self.gpu_temp,
|
||||
self.cpu_fan, self.gpu_fan,
|
||||
self.power_w
|
||||
),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn menu(&self) -> Vec<ksni::MenuItem<Self>> {
|
||||
use ksni::menu::*;
|
||||
vec![
|
||||
@@ -198,12 +155,7 @@ fn find_dgpu() -> Option<Device> {
|
||||
}
|
||||
|
||||
/// The tray is controlled somewhat by `Arc<Mutex<SystemState>>`
|
||||
pub fn init_tray(
|
||||
_supported_properties: Vec<Properties>,
|
||||
config: Arc<Mutex<Config>>,
|
||||
tray_channel: tokio::sync::mpsc::UnboundedSender<TrayEvent>,
|
||||
mut stats_rx: tokio::sync::watch::Receiver<TrayStats>,
|
||||
) {
|
||||
pub fn init_tray(_supported_properties: Vec<Properties>, config: Arc<Mutex<Config>>) {
|
||||
tokio::spawn(async move {
|
||||
let user_con = zbus::blocking::Connection::session().unwrap();
|
||||
let proxy = ROGCCZbusProxyBlocking::new(&user_con).unwrap();
|
||||
@@ -214,14 +166,6 @@ pub fn init_tray(
|
||||
current_title: TRAY_LABEL.to_string(),
|
||||
current_icon: rog_red.clone(),
|
||||
proxy,
|
||||
tray_channel: Some(tray_channel),
|
||||
// Initialize stats fields
|
||||
cpu_temp: "--".into(),
|
||||
gpu_temp: "--".into(),
|
||||
cpu_fan: "--".into(),
|
||||
gpu_fan: "--".into(),
|
||||
power_w: "--".into(),
|
||||
power_profile: "Unknown".into(),
|
||||
};
|
||||
|
||||
// TODO: return an error to the UI
|
||||
@@ -281,45 +225,28 @@ pub fn init_tray(
|
||||
info!("Started ROGTray");
|
||||
let mut last_power = GfxPower::Unknown;
|
||||
let dev = find_dgpu();
|
||||
|
||||
// Loop with select! to handle both periodic checks and stats updates
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = stats_rx.changed() => {
|
||||
let stats = stats_rx.borrow().clone();
|
||||
tray.update(move |t| {
|
||||
t.cpu_temp = stats.cpu_temp;
|
||||
t.gpu_temp = stats.gpu_temp;
|
||||
t.cpu_fan = stats.cpu_fan;
|
||||
t.gpu_fan = stats.gpu_fan;
|
||||
t.power_w = stats.power_w;
|
||||
t.power_profile = stats.power_profile;
|
||||
}).await;
|
||||
tokio::time::sleep(Duration::from_millis(1000)).await;
|
||||
if let Ok(lock) = config.try_lock() {
|
||||
if !lock.enable_tray_icon {
|
||||
return;
|
||||
}
|
||||
_ = tokio::time::sleep(Duration::from_millis(1000)) => {
|
||||
if let Ok(lock) = config.try_lock() {
|
||||
if !lock.enable_tray_icon {
|
||||
return;
|
||||
}
|
||||
if has_supergfx {
|
||||
if let Ok(mode) = gfx_proxy.mode().await {
|
||||
if let Ok(power) = gfx_proxy.power().await {
|
||||
if last_power != power {
|
||||
set_tray_icon_and_tip(mode, power, &mut tray, has_supergfx).await;
|
||||
last_power = power;
|
||||
}
|
||||
}
|
||||
// Handle GPU icon updates
|
||||
if has_supergfx {
|
||||
if let Ok(mode) = gfx_proxy.mode().await {
|
||||
if let Ok(power) = gfx_proxy.power().await {
|
||||
if last_power != power {
|
||||
set_tray_icon_and_tip(mode, power, &mut tray, has_supergfx).await;
|
||||
last_power = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(dev) = dev.as_ref() {
|
||||
if let Ok(power) = dev.get_runtime_status() {
|
||||
if last_power != power {
|
||||
set_tray_icon_and_tip(GfxMode::Hybrid, power, &mut tray, has_supergfx)
|
||||
.await;
|
||||
last_power = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(dev) = dev.as_ref() {
|
||||
if let Ok(power) = dev.get_runtime_status() {
|
||||
if last_power != power {
|
||||
set_tray_icon_and_tip(GfxMode::Hybrid, power, &mut tray, has_supergfx)
|
||||
.await;
|
||||
last_power = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,200 +0,0 @@
|
||||
//! Software-based keyboard animation for keyboards that only support Static mode.
|
||||
//! Provides Rainbow and Color Cycle animations via timer-based color updates.
|
||||
|
||||
use log::{info, warn};
|
||||
use slint::Weak;
|
||||
use std::process::Command;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::MainWindow;
|
||||
|
||||
/// Animation mode enum matching the UI
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||
pub enum AnimationMode {
|
||||
#[default]
|
||||
None,
|
||||
Rainbow,
|
||||
ColorCycle,
|
||||
}
|
||||
|
||||
impl From<i32> for AnimationMode {
|
||||
fn from(v: i32) -> Self {
|
||||
match v {
|
||||
1 => AnimationMode::Rainbow,
|
||||
2 => AnimationMode::ColorCycle,
|
||||
_ => AnimationMode::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Shared state for the animator
|
||||
pub struct AnimatorState {
|
||||
/// Current animation mode
|
||||
pub mode: AtomicU32,
|
||||
/// Animation speed in milliseconds (update interval)
|
||||
pub speed_ms: AtomicU32,
|
||||
/// Stop signal
|
||||
pub stop: AtomicBool,
|
||||
/// Current hue for rainbow mode (0-360)
|
||||
hue: AtomicU32,
|
||||
}
|
||||
|
||||
impl Default for AnimatorState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
mode: AtomicU32::new(0),
|
||||
speed_ms: AtomicU32::new(200),
|
||||
stop: AtomicBool::new(false),
|
||||
hue: AtomicU32::new(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert HSV to RGB (H: 0-360, S: 0-100, V: 0-100)
|
||||
fn hsv_to_rgb(h: u32, s: u32, v: u32) -> (u8, u8, u8) {
|
||||
let s = s as f32 / 100.0;
|
||||
let v = v as f32 / 100.0;
|
||||
let c = v * s;
|
||||
let h_prime = (h as f32 / 60.0) % 6.0;
|
||||
let x = c * (1.0 - ((h_prime % 2.0) - 1.0).abs());
|
||||
let m = v - c;
|
||||
|
||||
let (r, g, b) = match h_prime as u32 {
|
||||
0 => (c, x, 0.0),
|
||||
1 => (x, c, 0.0),
|
||||
2 => (0.0, c, x),
|
||||
3 => (0.0, x, c),
|
||||
4 => (x, 0.0, c),
|
||||
_ => (c, 0.0, x),
|
||||
};
|
||||
|
||||
(
|
||||
((r + m) * 255.0) as u8,
|
||||
((g + m) * 255.0) as u8,
|
||||
((b + m) * 255.0) as u8,
|
||||
)
|
||||
}
|
||||
|
||||
/// Format RGB as hex color string for asusctl
|
||||
fn rgb_to_hex(r: u8, g: u8, b: u8) -> String {
|
||||
format!("{:02x}{:02x}{:02x}", r, g, b)
|
||||
}
|
||||
|
||||
// Simple LCG for random numbers to avoid pulling in rand crate
|
||||
fn next_random(seed: &mut u64) -> u32 {
|
||||
*seed = seed.wrapping_mul(6364136223846793005).wrapping_add(1);
|
||||
(*seed >> 32) as u32
|
||||
}
|
||||
|
||||
/// Start the animation loop (runs in tokio task)
|
||||
pub fn start_animator(state: Arc<AnimatorState>, _ui_weak: Weak<MainWindow>) {
|
||||
info!("Starting keyboard animator");
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Local state for Color Cycle (RGB)
|
||||
let mut current_r: f32 = 255.0;
|
||||
let mut current_g: f32 = 0.0;
|
||||
let mut current_b: f32 = 0.0;
|
||||
let mut target_r: f32 = 0.0;
|
||||
let mut target_g: f32 = 255.0;
|
||||
let mut target_b: f32 = 0.0;
|
||||
let mut seed = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.map(|d| d.as_nanos() as u64)
|
||||
.unwrap_or(12345);
|
||||
|
||||
loop {
|
||||
// Check for stop signal
|
||||
if state.stop.load(Ordering::Relaxed) {
|
||||
info!("Animator stopping");
|
||||
break;
|
||||
}
|
||||
|
||||
let mode = AnimationMode::from(state.mode.load(Ordering::Relaxed) as i32);
|
||||
// Cap speed at 150ms for stability
|
||||
let raw_speed = state.speed_ms.load(Ordering::Relaxed);
|
||||
let effective_speed = raw_speed.max(150) as u64;
|
||||
|
||||
if mode == AnimationMode::None {
|
||||
// No animation, sleep longer
|
||||
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate next color
|
||||
let hex_color = match mode {
|
||||
AnimationMode::Rainbow => {
|
||||
// Hue step 1 for smooth, granular transitions
|
||||
let hue = state.hue.fetch_add(1, Ordering::Relaxed) % 360;
|
||||
let (r, g, b) = hsv_to_rgb(hue, 100, 100);
|
||||
rgb_to_hex(r, g, b)
|
||||
}
|
||||
AnimationMode::ColorCycle => {
|
||||
// RGB Linear Interpolation (Fading) - NOT Rainbow
|
||||
|
||||
// 1. Check distance to target
|
||||
let dist_sq = (target_r - current_r).powi(2)
|
||||
+ (target_g - current_g).powi(2)
|
||||
+ (target_b - current_b).powi(2);
|
||||
|
||||
// If close, pick new random target color
|
||||
if dist_sq < 100.0 {
|
||||
let next_h = next_random(&mut seed) % 360;
|
||||
let (r, g, b) = hsv_to_rgb(next_h, 100, 100);
|
||||
target_r = r as f32;
|
||||
target_g = g as f32;
|
||||
target_b = b as f32;
|
||||
}
|
||||
|
||||
// 2. Lerp towards target (5% per frame for smooth ease-out)
|
||||
let factor = 0.05;
|
||||
current_r += (target_r - current_r) * factor;
|
||||
current_g += (target_g - current_g) * factor;
|
||||
current_b += (target_b - current_b) * factor;
|
||||
|
||||
rgb_to_hex(current_r as u8, current_g as u8, current_b as u8)
|
||||
}
|
||||
AnimationMode::None => continue,
|
||||
};
|
||||
|
||||
// Send color update via asusctl command (blocking, AWAITED to prevent races)
|
||||
let hex = hex_color.clone();
|
||||
let _ = tokio::task::spawn_blocking(move || {
|
||||
let result = Command::new("asusctl")
|
||||
.args([
|
||||
"aura", "static", "-c", &hex,
|
||||
])
|
||||
.output();
|
||||
|
||||
if let Err(e) = result {
|
||||
warn!("Failed to set aura color: {}", e);
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
// Sleep for the animation speed interval
|
||||
tokio::time::sleep(Duration::from_millis(effective_speed)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// Stop the animator
|
||||
pub fn stop_animator(state: &Arc<AnimatorState>) {
|
||||
state.stop.store(true, Ordering::Relaxed);
|
||||
state.mode.store(0, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Set animation mode
|
||||
pub fn set_animation_mode(state: &Arc<AnimatorState>, mode: AnimationMode) {
|
||||
state.mode.store(mode as u32, Ordering::Relaxed);
|
||||
// Reset stop flag in case we're restarting
|
||||
state.stop.store(false, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Set animation speed
|
||||
pub fn set_animation_speed(state: &Arc<AnimatorState>, speed_ms: u32) {
|
||||
let clamped = speed_ms.clamp(50, 2000);
|
||||
state.speed_ms.store(clamped, Ordering::Relaxed);
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
pub mod aura_animator;
|
||||
pub mod setup_anime;
|
||||
pub mod setup_aura;
|
||||
pub mod setup_fan_curve_custom;
|
||||
pub mod setup_fans;
|
||||
pub mod setup_screenpad;
|
||||
pub mod setup_slash;
|
||||
pub mod setup_status;
|
||||
pub mod setup_supergfx;
|
||||
pub mod setup_gpu;
|
||||
pub mod setup_system;
|
||||
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
static TOAST_SEQ: AtomicU64 = AtomicU64::new(0);
|
||||
|
||||
use config_traits::StdConfig;
|
||||
use log::warn;
|
||||
@@ -17,14 +16,9 @@ use rog_dbus::list_iface_blocking;
|
||||
use slint::{ComponentHandle, SharedString, Weak};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::tray::TrayStats;
|
||||
use crate::ui::setup_anime::setup_anime_page;
|
||||
use crate::ui::setup_aura::setup_aura_page;
|
||||
use crate::ui::setup_fans::setup_fan_curve_page;
|
||||
use crate::ui::setup_screenpad::setup_screenpad;
|
||||
use crate::ui::setup_slash::setup_slash;
|
||||
use crate::ui::setup_status::setup_status;
|
||||
use crate::ui::setup_supergfx::setup_supergfx;
|
||||
use crate::ui::setup_system::{setup_system_page, setup_system_page_callbacks};
|
||||
use crate::{AppSettingsPageData, MainWindow};
|
||||
|
||||
@@ -81,21 +75,52 @@ pub fn show_toast(
|
||||
handle: Weak<MainWindow>,
|
||||
result: zbus::Result<()>,
|
||||
) {
|
||||
// bump sequence so that any previously spawned timers won't clear newer toasts
|
||||
let seq = TOAST_SEQ.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
match result {
|
||||
Ok(_) => {
|
||||
slint::invoke_from_event_loop(move || handle.unwrap().invoke_show_toast(success)).ok()
|
||||
let delayed_handle = handle.clone();
|
||||
let delayed_text = success.clone();
|
||||
slint::invoke_from_event_loop(move || handle.unwrap().invoke_show_toast(success)).ok();
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
if TOAST_SEQ.load(Ordering::SeqCst) == seq {
|
||||
slint::invoke_from_event_loop(move || {
|
||||
delayed_handle
|
||||
.unwrap()
|
||||
.invoke_clear_toast_if_matches(delayed_text)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
let delayed_handle = handle.clone();
|
||||
let delayed_text = fail.clone();
|
||||
slint::invoke_from_event_loop(move || {
|
||||
log::warn!("{fail}: {e}");
|
||||
handle.unwrap().invoke_show_toast(fail)
|
||||
})
|
||||
.ok();
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
if TOAST_SEQ.load(Ordering::SeqCst) == seq {
|
||||
slint::invoke_from_event_loop(move || {
|
||||
delayed_handle
|
||||
.unwrap()
|
||||
.invoke_clear_toast_if_matches(delayed_text)
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
}
|
||||
Err(e) => slint::invoke_from_event_loop(move || {
|
||||
log::warn!("{fail}: {e}");
|
||||
handle.unwrap().invoke_show_toast(fail)
|
||||
})
|
||||
.ok(),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn setup_window(
|
||||
config: Arc<Mutex<Config>>,
|
||||
stats_tx: tokio::sync::watch::Sender<TrayStats>,
|
||||
prefetched_supported: std::sync::Arc<Option<Vec<i32>>>,
|
||||
is_tuf: bool,
|
||||
) -> MainWindow {
|
||||
slint::set_xdg_app_id("rog-control-center")
|
||||
.map_err(|e| warn!("Couldn't set application ID: {e:?}"))
|
||||
@@ -103,6 +128,8 @@ pub fn setup_window(
|
||||
let ui = MainWindow::new()
|
||||
.map_err(|e| warn!("Couldn't create main window: {e:?}"))
|
||||
.unwrap();
|
||||
// propagate TUF flag to the UI so the sidebar can swap logo branding
|
||||
ui.set_is_tuf(is_tuf);
|
||||
ui.window()
|
||||
.show()
|
||||
.map_err(|e| warn!("Couldn't show main window: {e:?}"))
|
||||
@@ -115,27 +142,10 @@ pub fn setup_window(
|
||||
available.contains(&"xyz.ljones.Platform".to_string()),
|
||||
available.contains(&"xyz.ljones.Aura".to_string()),
|
||||
available.contains(&"xyz.ljones.Anime".to_string()),
|
||||
available.contains(&"xyz.ljones.Slash".to_string()),
|
||||
// Supergfx check
|
||||
{
|
||||
if let Ok(conn) = zbus::blocking::Connection::system() {
|
||||
zbus::blocking::fdo::DBusProxy::new(&conn)
|
||||
.ok()
|
||||
.and_then(|p| {
|
||||
p.name_has_owner("org.supergfxctl.Daemon".try_into().ok()?)
|
||||
.ok()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
},
|
||||
// Screenpad check (Backlight interface)
|
||||
available.contains(&"xyz.ljones.Backlight".to_string()),
|
||||
available.contains(&"xyz.ljones.FanCurves".to_string()),
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true, // GPU Configuration
|
||||
true, // App Settings
|
||||
true, // About
|
||||
]
|
||||
.into(),
|
||||
);
|
||||
@@ -144,61 +154,23 @@ pub fn setup_window(
|
||||
slint::quit_event_loop().unwrap();
|
||||
});
|
||||
|
||||
// Auto-hide toast logic
|
||||
let toast_gen = Arc::new(Mutex::new(0u64));
|
||||
let ui_weak = ui.as_weak();
|
||||
ui.on_start_toast_timer(move || {
|
||||
let toast_gen_clone = toast_gen.clone();
|
||||
let ui_weak_clone = ui_weak.clone();
|
||||
let my_gen = {
|
||||
if let Ok(mut g) = toast_gen.lock() {
|
||||
*g += 1;
|
||||
*g
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
if my_gen > 0 {
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(4)).await;
|
||||
if let Ok(g) = toast_gen_clone.lock() {
|
||||
if *g == my_gen {
|
||||
let _ =
|
||||
ui_weak_clone.upgrade_in_event_loop(move |ui| ui.invoke_hide_toast());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
setup_app_settings_page(&ui, config.clone());
|
||||
if available.contains(&"xyz.ljones.Platform".to_string()) {
|
||||
setup_system_page(&ui, config.clone());
|
||||
setup_system_page_callbacks(&ui, config.clone());
|
||||
}
|
||||
if available.contains(&"xyz.ljones.Aura".to_string()) {
|
||||
setup_aura_page(&ui, config.clone());
|
||||
setup_aura_page(&ui, config.clone(), prefetched_supported.as_ref().clone());
|
||||
}
|
||||
if available.contains(&"xyz.ljones.Anime".to_string()) {
|
||||
setup_anime_page(&ui, config.clone());
|
||||
}
|
||||
if available.contains(&"xyz.ljones.Slash".to_string()) {
|
||||
setup_slash(&ui, config.clone());
|
||||
}
|
||||
|
||||
// Always try to setup supergfx if detected above, but for simplicity here we assume if sidebar has it (re-check or just run)
|
||||
// We didn't capture the boolean above. Let's just run it, it handles its own availability check internally via async proxy creation.
|
||||
setup_supergfx(&ui, config.clone());
|
||||
|
||||
if available.contains(&"xyz.ljones.Backlight".to_string()) {
|
||||
setup_screenpad(&ui, config.clone());
|
||||
}
|
||||
|
||||
if available.contains(&"xyz.ljones.FanCurves".to_string()) {
|
||||
setup_fan_curve_page(&ui, config.clone());
|
||||
}
|
||||
|
||||
setup_status(&ui, config, stats_tx);
|
||||
// Populate GPU page choices and callbacks
|
||||
setup_gpu::setup_gpu_page(&ui);
|
||||
|
||||
ui
|
||||
}
|
||||
@@ -226,49 +198,18 @@ pub fn setup_app_settings_page(ui: &MainWindow, config: Arc<Mutex<Config>>) {
|
||||
lock.write();
|
||||
}
|
||||
});
|
||||
|
||||
// Master notifications toggle
|
||||
let config_copy = config.clone();
|
||||
global.on_set_notifications_enabled(move |enable| {
|
||||
global.on_set_enable_dgpu_notifications(move |enable| {
|
||||
if let Ok(mut lock) = config_copy.try_lock() {
|
||||
lock.notifications.enabled = enable;
|
||||
lock.write();
|
||||
}
|
||||
});
|
||||
|
||||
// Granular notification toggles
|
||||
let config_copy = config.clone();
|
||||
global.on_set_notify_gfx_switch(move |enable| {
|
||||
if let Ok(mut lock) = config_copy.try_lock() {
|
||||
lock.notifications.receive_notify_gfx = enable;
|
||||
lock.write();
|
||||
}
|
||||
});
|
||||
|
||||
let config_copy = config.clone();
|
||||
global.on_set_notify_gfx_status(move |enable| {
|
||||
if let Ok(mut lock) = config_copy.try_lock() {
|
||||
lock.notifications.receive_notify_gfx_status = enable;
|
||||
lock.write();
|
||||
}
|
||||
});
|
||||
|
||||
let config_copy = config.clone();
|
||||
global.on_set_notify_platform_profile(move |enable| {
|
||||
if let Ok(mut lock) = config_copy.try_lock() {
|
||||
lock.notifications.receive_notify_platform_profile = enable;
|
||||
lock.write();
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize UI values from config
|
||||
if let Ok(lock) = config.try_lock() {
|
||||
global.set_run_in_background(lock.run_in_background);
|
||||
global.set_startup_in_background(lock.startup_in_background);
|
||||
global.set_enable_tray_icon(lock.enable_tray_icon);
|
||||
global.set_notifications_enabled(lock.notifications.enabled);
|
||||
global.set_notify_gfx_switch(lock.notifications.receive_notify_gfx);
|
||||
global.set_notify_gfx_status(lock.notifications.receive_notify_gfx_status);
|
||||
global.set_notify_platform_profile(lock.notifications.receive_notify_platform_profile);
|
||||
global.set_enable_dgpu_notifications(lock.notifications.enabled);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@ use rog_dbus::zbus_aura::AuraProxy;
|
||||
use slint::{ComponentHandle, Model, RgbaColor, SharedString};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::ui::aura_animator::{
|
||||
set_animation_mode, set_animation_speed, start_animator, AnimationMode, AnimatorState,
|
||||
};
|
||||
use crate::ui::show_toast;
|
||||
use crate::{
|
||||
set_ui_callbacks, set_ui_props_async, AuraPageData, MainWindow, PowerZones as SlintPowerZones,
|
||||
@@ -37,63 +34,103 @@ fn decode_hex(s: &str) -> RgbaColor<u8> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the first available Aura interface
|
||||
// TODO: return all
|
||||
async fn find_aura_iface() -> Result<AuraProxy<'static>, Box<dyn std::error::Error>> {
|
||||
let conn = zbus::Connection::system().await?;
|
||||
let f = zbus::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").await?;
|
||||
let interfaces = f.get_managed_objects().await?;
|
||||
let mut aura_paths = Vec::new();
|
||||
for v in interfaces.iter() {
|
||||
for k in v.1.keys() {
|
||||
if k.as_str() == "xyz.ljones.Aura" {
|
||||
println!("Found aura device at {}, {}", v.0, k);
|
||||
aura_paths.push(v.0.clone());
|
||||
}
|
||||
}
|
||||
let mgr = zbus::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").await?;
|
||||
let objs = mgr.get_managed_objects().await?;
|
||||
let mut paths: Vec<zbus::zvariant::OwnedObjectPath> = objs
|
||||
.iter()
|
||||
.filter(|(_, ifaces)| ifaces.keys().any(|k| k.as_str() == "xyz.ljones.Aura"))
|
||||
.map(|(p, _)| p.clone())
|
||||
.collect();
|
||||
if paths.len() > 1 {
|
||||
log::debug!("Multiple aura devices: {paths:?}");
|
||||
}
|
||||
if aura_paths.len() > 1 {
|
||||
println!("Multiple aura devices found: {aura_paths:?}");
|
||||
println!("TODO: enable selection");
|
||||
}
|
||||
if let Some(path) = aura_paths.first() {
|
||||
return Ok(AuraProxy::builder(&conn)
|
||||
.path(path.clone())?
|
||||
.destination("xyz.ljones.Asusd")?
|
||||
.build()
|
||||
.await?);
|
||||
}
|
||||
|
||||
Err("No Aura interface".into())
|
||||
let path = paths.pop().ok_or("No Aura interface")?;
|
||||
AuraProxy::builder(&conn)
|
||||
.path(path)?
|
||||
.destination("xyz.ljones.Asusd")?
|
||||
.build()
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
ui.global::<AuraPageData>().on_cb_hex_from_colour(|c| {
|
||||
pub async fn prefetch_supported_basic_modes() -> Option<Vec<i32>> {
|
||||
let proxy = find_aura_iface().await.ok()?;
|
||||
let modes = proxy.supported_basic_modes().await.ok()?;
|
||||
Some(modes.iter().map(|n| (*n).into()).collect())
|
||||
}
|
||||
|
||||
pub fn setup_aura_page(
|
||||
ui: &MainWindow,
|
||||
_states: Arc<Mutex<Config>>,
|
||||
prefetched_supported: Option<Vec<i32>>,
|
||||
) {
|
||||
let g = ui.global::<AuraPageData>();
|
||||
g.on_cb_hex_from_colour(|c| {
|
||||
format!("#{:02X}{:02X}{:02X}", c.red(), c.green(), c.blue()).into()
|
||||
});
|
||||
|
||||
ui.global::<AuraPageData>()
|
||||
.on_cb_hex_to_colour(|s| decode_hex(s.as_str()).into());
|
||||
g.on_cb_hex_to_colour(|s| decode_hex(s.as_str()).into());
|
||||
|
||||
let handle = ui.as_weak();
|
||||
tokio::spawn(async move {
|
||||
let Ok(aura) = find_aura_iface().await else {
|
||||
info!("This device appears to have no aura interfaces");
|
||||
info!("No aura interfaces");
|
||||
return Ok::<(), zbus::Error>(());
|
||||
};
|
||||
|
||||
set_ui_props_async!(handle, aura, AuraPageData, brightness);
|
||||
set_ui_props_async!(handle, aura, AuraPageData, led_mode);
|
||||
set_ui_props_async!(handle, aura, AuraPageData, led_mode_data);
|
||||
set_ui_props_async!(handle, aura, AuraPageData, led_power);
|
||||
set_ui_props_async!(handle, aura, AuraPageData, device_type);
|
||||
|
||||
let modes_vec: Vec<i32> = match prefetched_supported {
|
||||
Some(p) => p,
|
||||
None => aura
|
||||
.supported_basic_modes()
|
||||
.await
|
||||
.ok()
|
||||
.map(|m| m.iter().map(|n| (*n).into()).collect())
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
|
||||
// Restore saved mode, colours, zone, speed, direction from asusd (persisted to disk).
|
||||
// Use effect.mode as single source — avoid led_mode() which can fail (try_lock).
|
||||
let restore = aura.led_mode_data().await.ok();
|
||||
let raw_mode: Option<i32> = restore.as_ref().map(|d| d.mode.into());
|
||||
let d_slint = restore.map(|d| d.into());
|
||||
handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
let names = h.global::<AuraPageData>().get_mode_names();
|
||||
let mut raws = Vec::new();
|
||||
let mut mode_names = Vec::new();
|
||||
for (i, name) in names.iter().enumerate() {
|
||||
let raw = i as i32;
|
||||
if modes_vec.contains(&raw) && i != 9 {
|
||||
raws.push(raw);
|
||||
mode_names.push(name.clone());
|
||||
}
|
||||
}
|
||||
h.global::<AuraPageData>()
|
||||
.set_supported_basic_modes(raws.as_slice().into());
|
||||
h.global::<AuraPageData>()
|
||||
.set_available_mode_names(mode_names.as_slice().into());
|
||||
if let Some(d) = d_slint {
|
||||
h.global::<AuraPageData>().invoke_update_led_mode_data(d);
|
||||
if let Some(cm) = raw_mode {
|
||||
let idx = raws.iter().position(|&r| r == cm).unwrap_or(0) as i32;
|
||||
h.global::<AuraPageData>().set_current_available_mode(idx);
|
||||
}
|
||||
h.invoke_external_colour_change();
|
||||
}
|
||||
})
|
||||
.map_err(|e| error!("{e}"))
|
||||
.ok();
|
||||
|
||||
if let Ok(mut pow3r) = aura.supported_power_zones().await {
|
||||
let dev_type = aura
|
||||
let dev = aura
|
||||
.device_type()
|
||||
.await
|
||||
.unwrap_or(AuraDeviceType::LaptopKeyboard2021);
|
||||
log::debug!("Available LED power modes {pow3r:?}");
|
||||
handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
let names: Vec<SharedString> = handle
|
||||
@@ -101,171 +138,103 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc<Mutex<Config>>) {
|
||||
.get_power_zone_names()
|
||||
.iter()
|
||||
.collect();
|
||||
|
||||
if dev_type.is_old_laptop() {
|
||||
// Need to add the specific KeyboardAndLightbar
|
||||
if dev.is_old_laptop() {
|
||||
if pow3r.contains(&PowerZones::Keyboard)
|
||||
&& pow3r.contains(&PowerZones::Lightbar)
|
||||
{
|
||||
pow3r.push(PowerZones::KeyboardAndLightbar);
|
||||
}
|
||||
let names: Vec<SharedString> =
|
||||
pow3r.iter().map(|n| names[(*n) as usize].clone()).collect();
|
||||
let n: Vec<SharedString> =
|
||||
pow3r.iter().map(|z| names[(*z) as usize].clone()).collect();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.set_power_zone_names_old(names.as_slice().into());
|
||||
.set_power_zone_names_old(n.as_slice().into());
|
||||
} else {
|
||||
let power: Vec<SlintPowerZones> =
|
||||
pow3r.iter().map(|p| (*p).into()).collect();
|
||||
|
||||
let p: Vec<SlintPowerZones> = pow3r.iter().map(|z| (*z).into()).collect();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.set_supported_power_zones(power.as_slice().into());
|
||||
.set_supported_power_zones(p.as_slice().into());
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
// Create animator state (shared across callbacks)
|
||||
let animator_state = Arc::new(AnimatorState::default());
|
||||
|
||||
if let Ok(modes) = aura.supported_basic_modes().await {
|
||||
log::debug!("Available LED modes {modes:?}");
|
||||
|
||||
// Check if only Static mode is available (enable software animation)
|
||||
let static_only = modes.len() == 1 && modes.iter().any(|m| *m == 0.into());
|
||||
|
||||
let handle_for_anim = handle.clone();
|
||||
let animator_state_clone = animator_state.clone();
|
||||
handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
let m: Vec<i32> = modes.iter().map(|n| (*n).into()).collect();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.set_supported_basic_modes(m.as_slice().into());
|
||||
// Get the translated names
|
||||
let names = handle.global::<AuraPageData>().get_mode_names();
|
||||
|
||||
let res: Vec<SharedString> = names
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(n, _)| modes.contains(&(*n as i32).into()) && *n != 9)
|
||||
.map(|(_, i)| i)
|
||||
.collect();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.set_available_mode_names(res.as_slice().into());
|
||||
|
||||
// Enable software animation if only Static mode is available
|
||||
if static_only {
|
||||
info!("Only Static mode available - enabling software animation controls");
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.set_soft_animation_available(true);
|
||||
|
||||
// Start the animator thread
|
||||
start_animator(animator_state_clone.clone(), handle_for_anim.clone());
|
||||
|
||||
// Connect mode callback
|
||||
let state_for_mode = animator_state_clone.clone();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.on_cb_soft_animation_mode(move |mode| {
|
||||
set_animation_mode(&state_for_mode, AnimationMode::from(mode));
|
||||
});
|
||||
|
||||
// Connect speed callback
|
||||
let state_for_speed = animator_state_clone.clone();
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.on_cb_soft_animation_speed(move |speed| {
|
||||
set_animation_speed(&state_for_speed, speed as u32);
|
||||
});
|
||||
}
|
||||
})
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok();
|
||||
}
|
||||
|
||||
let proxy_copy = aura.clone();
|
||||
let proxy = aura.clone();
|
||||
let weak = handle.clone();
|
||||
handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
set_ui_callbacks!(handle,
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
set_ui_callbacks!(h,
|
||||
AuraPageData(.into()),
|
||||
proxy_copy.brightness(.into()),
|
||||
"Keyboard LED brightness successfully set to {}",
|
||||
"Setting keyboard LED brightness failed"
|
||||
proxy.brightness(.into()),
|
||||
"Brightness set to {}",
|
||||
"Brightness failed"
|
||||
);
|
||||
|
||||
set_ui_callbacks!(handle,
|
||||
AuraPageData(.into()),
|
||||
proxy_copy.led_mode(.into()),
|
||||
"Keyboard LED mode successfully set to {}",
|
||||
"Setting keyboard LEDmode failed"
|
||||
);
|
||||
|
||||
set_ui_callbacks!(handle,
|
||||
AuraPageData(.into()),
|
||||
proxy_copy.led_mode_data(.into()),
|
||||
"Keyboard LED mode set to {:?}",
|
||||
"Setting keyboard LED mode failed"
|
||||
);
|
||||
|
||||
// set_ui_callbacks!(handle,
|
||||
// AuraPageData(.clone().into()),
|
||||
// proxy_copy.led_power(.into()),
|
||||
// "Keyboard LED power successfully set to {:?}",
|
||||
// "Setting keyboard power failed"
|
||||
// );
|
||||
|
||||
handle.invoke_external_colour_change();
|
||||
})
|
||||
.ok();
|
||||
|
||||
let handle_copy = handle.clone();
|
||||
let proxy_copy = aura.clone();
|
||||
handle
|
||||
.upgrade_in_event_loop(|handle| {
|
||||
handle
|
||||
.global::<AuraPageData>()
|
||||
.on_cb_led_power(move |power| {
|
||||
let handle_copy = handle_copy.clone();
|
||||
let proxy_copy = aura.clone();
|
||||
let power: LaptopAuraPower = power.into();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
"Aura power settings changed".into(),
|
||||
"Failed to set Aura power settings".into(),
|
||||
handle_copy,
|
||||
proxy_copy.set_led_power(power).await,
|
||||
);
|
||||
});
|
||||
let p = proxy.clone();
|
||||
let w = weak.clone();
|
||||
h.global::<AuraPageData>().on_apply_led_mode_data(move || {
|
||||
let Some(ui) = w.upgrade() else { return };
|
||||
let slint_effect = ui.global::<AuraPageData>().get_led_mode_data();
|
||||
let raw: rog_aura::AuraEffect = slint_effect.into();
|
||||
let pp = p.clone();
|
||||
let t = w.clone();
|
||||
tokio::spawn(async move {
|
||||
let r = pp.set_led_mode_data(raw).await;
|
||||
show_toast("LED mode applied".into(), "LED mode failed".into(), t, r);
|
||||
});
|
||||
});
|
||||
h.invoke_external_colour_change();
|
||||
})
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok();
|
||||
|
||||
// Need to update the UI if the mode changes
|
||||
let handle_copy = handle.clone();
|
||||
// spawn required since the while let never exits
|
||||
let weak_power = handle.clone();
|
||||
let proxy_power = aura.clone();
|
||||
handle
|
||||
.upgrade_in_event_loop(|h| {
|
||||
h.global::<AuraPageData>().on_cb_led_power(move |power| {
|
||||
let w = weak_power.clone();
|
||||
let p = proxy_power.clone();
|
||||
let pw: LaptopAuraPower = power.into();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
"Aura power updated".into(),
|
||||
"Aura power failed".into(),
|
||||
w,
|
||||
p.set_led_power(pw).await,
|
||||
);
|
||||
});
|
||||
});
|
||||
})
|
||||
.map_err(|e| error!("{e}"))
|
||||
.ok();
|
||||
|
||||
let stream_handle = handle.clone();
|
||||
let aura_stream = aura.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut x = proxy_copy.receive_led_mode_data_changed().await;
|
||||
use futures_util::StreamExt;
|
||||
while let Some(e) = x.next().await {
|
||||
let mut stream = aura_stream.receive_led_mode_data_changed().await;
|
||||
while let Some(e) = stream.next().await {
|
||||
if let Ok(out) = e.get().await {
|
||||
handle_copy
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
handle
|
||||
let raw: i32 = out.mode.into();
|
||||
let data = out.into();
|
||||
stream_handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
h.global::<AuraPageData>().invoke_update_led_mode_data(data);
|
||||
let supported: Vec<i32> = h
|
||||
.global::<AuraPageData>()
|
||||
.invoke_update_led_mode_data(out.into());
|
||||
handle.invoke_external_colour_change();
|
||||
.get_supported_basic_modes()
|
||||
.iter()
|
||||
.collect();
|
||||
let idx = supported.iter().position(|&x| x == raw).unwrap_or(0) as i32;
|
||||
h.global::<AuraPageData>().set_current_available_mode(idx);
|
||||
h.invoke_external_colour_change();
|
||||
})
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.map_err(|e| error!("{e}"))
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
});
|
||||
debug!("Aura setup tasks complete");
|
||||
debug!("Aura setup done");
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,241 +0,0 @@
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use log::{error, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{FanType, MainWindow, Node};
|
||||
|
||||
const ASUS_CUSTOM_FAN_NAME: &str = "asus_custom_fan_curve";
|
||||
const CONFIG_FILE_NAME: &str = "custom_fans.ron";
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CustomCurvePoint {
|
||||
pub temp: u8,
|
||||
pub pwm: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct CustomFanConfig {
|
||||
pub cpu_curve: Vec<CustomCurvePoint>,
|
||||
pub gpu_curve: Vec<CustomCurvePoint>,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SysfsPaths {
|
||||
root: PathBuf,
|
||||
}
|
||||
|
||||
impl SysfsPaths {
|
||||
fn new() -> Option<Self> {
|
||||
let hwmon = Path::new("/sys/class/hwmon");
|
||||
if let Ok(entries) = fs::read_dir(hwmon) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
let name_path = path.join("name");
|
||||
if let Ok(name) = fs::read_to_string(&name_path) {
|
||||
if name.trim() == ASUS_CUSTOM_FAN_NAME {
|
||||
info!("Found ASUS Custom Fan Control at {:?}", path);
|
||||
return Some(Self { root: path });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn enable_path(&self, index: u8) -> PathBuf {
|
||||
self.root.join(format!("pwm{}_enable", index))
|
||||
}
|
||||
|
||||
fn point_pwm_path(&self, fan_idx: u8, point_idx: u8) -> PathBuf {
|
||||
self.root
|
||||
.join(format!("pwm{}_auto_point{}_pwm", fan_idx, point_idx))
|
||||
}
|
||||
|
||||
fn point_temp_path(&self, fan_idx: u8, point_idx: u8) -> PathBuf {
|
||||
self.root
|
||||
.join(format!("pwm{}_auto_point{}_temp", fan_idx, point_idx))
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to write with logging
|
||||
fn write_sysfs(path: &Path, value: &str) -> std::io::Result<()> {
|
||||
// debug!("Writing {} to {:?}", value, path);
|
||||
fs::write(path, value)
|
||||
}
|
||||
|
||||
fn _read_sysfs_u8(path: &Path) -> std::io::Result<u8> {
|
||||
let s = fs::read_to_string(path)?;
|
||||
s.trim()
|
||||
.parse::<u8>()
|
||||
.map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
|
||||
}
|
||||
|
||||
pub fn is_custom_fan_supported() -> bool {
|
||||
SysfsPaths::new().is_some()
|
||||
}
|
||||
|
||||
// Logic to apply a full curve to a specific fan (1=CPU, 2=GPU usually)
|
||||
// Implements the "Gradual Descent" algorithm
|
||||
fn apply_curve_to_fan(
|
||||
paths: &SysfsPaths,
|
||||
fan_idx: u8,
|
||||
points: &[CustomCurvePoint],
|
||||
) -> std::io::Result<()> {
|
||||
// Sort target points by temp (Hardware Requirement)
|
||||
let mut sorted_target = points.to_vec();
|
||||
sorted_target.sort_by_key(|p| p.temp);
|
||||
|
||||
// Ensure we have 8 points (fill with last if needed, or sensible default)
|
||||
while sorted_target.len() < 8 {
|
||||
if let Some(last) = sorted_target.last() {
|
||||
sorted_target.push(last.clone());
|
||||
} else {
|
||||
sorted_target.push(CustomCurvePoint {
|
||||
temp: 100,
|
||||
pwm: 255,
|
||||
});
|
||||
}
|
||||
}
|
||||
sorted_target.truncate(8);
|
||||
|
||||
// Validate Temp Order (Synchronous Check)
|
||||
for (i, p) in sorted_target.iter().enumerate() {
|
||||
if i > 0 {
|
||||
let prev_temp = sorted_target[i - 1].temp;
|
||||
if p.temp < prev_temp {
|
||||
error!("Invalid temp order");
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidInput,
|
||||
"Temp disorder",
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn completely detached thread for ALL I/O
|
||||
let paths_clone = paths.clone();
|
||||
let sorted_target = sorted_target.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let paths = paths_clone;
|
||||
|
||||
// 1. Enable custom mode
|
||||
if let Err(e) = write_sysfs(&paths.enable_path(fan_idx), "1") {
|
||||
error!("Failed to enable custom fan mode: {}", e);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Write Temps
|
||||
for (i, p) in sorted_target.iter().enumerate() {
|
||||
let point_idx = (i + 1) as u8;
|
||||
if let Err(e) = write_sysfs(
|
||||
&paths.point_temp_path(fan_idx, point_idx),
|
||||
&p.temp.to_string(),
|
||||
) {
|
||||
error!("Failed to write temp point {}: {}", point_idx, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Write PWMs directly (hardware handles gradual transition)
|
||||
for (i, target_p) in sorted_target.iter().enumerate() {
|
||||
let point_idx = (i + 1) as u8;
|
||||
if let Err(e) = write_sysfs(
|
||||
&paths.point_pwm_path(fan_idx, point_idx),
|
||||
&target_p.pwm.to_string(),
|
||||
) {
|
||||
error!("Failed to write PWM point {}: {}", point_idx, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Ensure enable is set
|
||||
let _ = write_sysfs(&paths.enable_path(fan_idx), "1");
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_fan_auto(paths: &SysfsPaths, fan_idx: u8) -> std::io::Result<()> {
|
||||
// 2 = Auto (usually)
|
||||
write_sysfs(&paths.enable_path(fan_idx), "2")
|
||||
}
|
||||
|
||||
fn load_config() -> CustomFanConfig {
|
||||
if let Some(config_dir) = dirs::config_dir() {
|
||||
let path = config_dir.join("rog").join(CONFIG_FILE_NAME);
|
||||
if let Ok(content) = fs::read_to_string(path) {
|
||||
if let Ok(cfg) = ron::from_str(&content) {
|
||||
return cfg;
|
||||
}
|
||||
}
|
||||
}
|
||||
CustomFanConfig::default()
|
||||
}
|
||||
|
||||
fn save_config(config: &CustomFanConfig) {
|
||||
if let Some(config_dir) = dirs::config_dir() {
|
||||
let rog_dir = config_dir.join("rog");
|
||||
let _ = fs::create_dir_all(&rog_dir);
|
||||
let path = rog_dir.join(CONFIG_FILE_NAME);
|
||||
if let Ok(s) = ron::ser::to_string_pretty(config, ron::ser::PrettyConfig::default()) {
|
||||
let _ = fs::write(path, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Public entry point called from setup_fans.rs or similar
|
||||
// Returns immediately - all work is done in a detached thread
|
||||
pub fn apply_custom_fan_curve(
|
||||
_handle_weak: slint::Weak<MainWindow>,
|
||||
fan_type: FanType,
|
||||
enabled: bool,
|
||||
nodes: Vec<Node>,
|
||||
) {
|
||||
// Fan Index: 1=CPU, 2=GPU usually.
|
||||
let fan_idx = match fan_type {
|
||||
FanType::CPU => 1,
|
||||
FanType::GPU => 2,
|
||||
_ => return, // Ignore others
|
||||
};
|
||||
|
||||
// Convert nodes to points (fast, CPU-only)
|
||||
let points: Vec<CustomCurvePoint> = nodes
|
||||
.iter()
|
||||
.map(|n| CustomCurvePoint {
|
||||
temp: n.x as u8,
|
||||
pwm: n.y as u8,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Spawn a completely detached thread for ALL I/O
|
||||
std::thread::spawn(move || {
|
||||
// Get paths (blocking FS operation)
|
||||
let Some(paths) = SysfsPaths::new() else {
|
||||
error!("No custom fan support found");
|
||||
return;
|
||||
};
|
||||
|
||||
// Save config
|
||||
let mut cfg = load_config();
|
||||
if enabled {
|
||||
match fan_type {
|
||||
FanType::CPU => cfg.cpu_curve = points.clone(),
|
||||
FanType::GPU => cfg.gpu_curve = points.clone(),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
cfg.enabled = enabled;
|
||||
save_config(&cfg);
|
||||
|
||||
// Apply curve or set auto
|
||||
if enabled {
|
||||
if let Err(e) = apply_curve_to_fan(&paths, fan_idx, &points) {
|
||||
error!("Failed to apply fan curve: {}", e);
|
||||
}
|
||||
} else if let Err(e) = set_fan_auto(&paths, fan_idx) {
|
||||
error!("Failed to set fan auto: {}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
use crate::ui::show_toast;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::error;
|
||||
use rog_dbus::zbus_fan_curves::FanCurvesProxy;
|
||||
@@ -10,25 +8,7 @@ use rog_profiles::fan_curve_set::CurveData;
|
||||
use slint::{ComponentHandle, Model, Weak};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::{FanPageData, FanType, MainWindow, Node, Profile};
|
||||
|
||||
// Isolated Rust-side cache for fan curves (not affected by Slint reactivity)
|
||||
type FanCacheKey = (i32, i32); // (Profile as i32, FanType as i32)
|
||||
static FAN_CACHE: OnceLock<Mutex<HashMap<FanCacheKey, Vec<Node>>>> = OnceLock::new();
|
||||
|
||||
fn fan_cache() -> &'static Mutex<HashMap<FanCacheKey, Vec<Node>>> {
|
||||
FAN_CACHE.get_or_init(|| Mutex::new(HashMap::new()))
|
||||
}
|
||||
|
||||
fn cache_fan_curve(profile: Profile, fan_type: FanType, nodes: Vec<Node>) {
|
||||
let key = (profile as i32, fan_type as i32);
|
||||
fan_cache().lock().unwrap().insert(key, nodes);
|
||||
}
|
||||
|
||||
fn get_cached_fan_curve(profile: Profile, fan_type: FanType) -> Option<Vec<Node>> {
|
||||
let key = (profile as i32, fan_type as i32);
|
||||
fan_cache().lock().unwrap().get(&key).cloned()
|
||||
}
|
||||
use crate::{FanPageData, FanType, MainWindow, Node};
|
||||
|
||||
pub fn update_fan_data(
|
||||
handle: Weak<MainWindow>,
|
||||
@@ -39,7 +19,7 @@ pub fn update_fan_data(
|
||||
handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
let global = handle.global::<FanPageData>();
|
||||
let _collect = |temp: &[u8], pwm: &[u8]| -> slint::ModelRc<Node> {
|
||||
let collect = |temp: &[u8], pwm: &[u8]| -> slint::ModelRc<Node> {
|
||||
let tmp: Vec<Node> = temp
|
||||
.iter()
|
||||
.zip(pwm.iter())
|
||||
@@ -53,100 +33,61 @@ pub fn update_fan_data(
|
||||
|
||||
for fan in bal {
|
||||
global.set_balanced_available(true);
|
||||
let nodes_vec: Vec<Node> = fan
|
||||
.temp
|
||||
.iter()
|
||||
.zip(fan.pwm.iter())
|
||||
.map(|(x, y)| Node {
|
||||
x: *x as f32,
|
||||
y: *y as f32,
|
||||
})
|
||||
.collect();
|
||||
let nodes: slint::ModelRc<Node> = nodes_vec.as_slice().into();
|
||||
match fan.fan {
|
||||
rog_profiles::FanCurvePU::CPU => {
|
||||
global.set_cpu_fan_available(true);
|
||||
global.set_balanced_cpu_enabled(fan.enabled);
|
||||
global.set_balanced_cpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Balanced, FanType::CPU, nodes_vec);
|
||||
global.set_balanced_cpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::GPU => {
|
||||
global.set_gpu_fan_available(true);
|
||||
global.set_balanced_gpu_enabled(fan.enabled);
|
||||
global.set_balanced_gpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Balanced, FanType::GPU, nodes_vec);
|
||||
global.set_balanced_gpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::MID => {
|
||||
global.set_mid_fan_available(true);
|
||||
global.set_balanced_mid_enabled(fan.enabled);
|
||||
global.set_balanced_mid(nodes.clone());
|
||||
cache_fan_curve(Profile::Balanced, FanType::Middle, nodes_vec);
|
||||
global.set_balanced_mid(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
}
|
||||
}
|
||||
for fan in perf {
|
||||
global.set_performance_available(true);
|
||||
let nodes_vec: Vec<Node> = fan
|
||||
.temp
|
||||
.iter()
|
||||
.zip(fan.pwm.iter())
|
||||
.map(|(x, y)| Node {
|
||||
x: *x as f32,
|
||||
y: *y as f32,
|
||||
})
|
||||
.collect();
|
||||
let nodes: slint::ModelRc<Node> = nodes_vec.as_slice().into();
|
||||
match fan.fan {
|
||||
rog_profiles::FanCurvePU::CPU => {
|
||||
global.set_cpu_fan_available(true);
|
||||
global.set_performance_cpu_enabled(fan.enabled);
|
||||
global.set_performance_cpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Performance, FanType::CPU, nodes_vec);
|
||||
global.set_performance_cpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::GPU => {
|
||||
global.set_gpu_fan_available(true);
|
||||
global.set_performance_gpu_enabled(fan.enabled);
|
||||
global.set_performance_gpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Performance, FanType::GPU, nodes_vec);
|
||||
global.set_performance_gpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::MID => {
|
||||
global.set_mid_fan_available(true);
|
||||
global.set_performance_mid_enabled(fan.enabled);
|
||||
global.set_performance_mid(nodes.clone());
|
||||
cache_fan_curve(Profile::Performance, FanType::Middle, nodes_vec);
|
||||
global.set_performance_mid(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
}
|
||||
}
|
||||
for fan in quiet {
|
||||
global.set_quiet_available(true);
|
||||
let nodes_vec: Vec<Node> = fan
|
||||
.temp
|
||||
.iter()
|
||||
.zip(fan.pwm.iter())
|
||||
.map(|(x, y)| Node {
|
||||
x: *x as f32,
|
||||
y: *y as f32,
|
||||
})
|
||||
.collect();
|
||||
let nodes: slint::ModelRc<Node> = nodes_vec.as_slice().into();
|
||||
match fan.fan {
|
||||
rog_profiles::FanCurvePU::CPU => {
|
||||
global.set_cpu_fan_available(true);
|
||||
global.set_quiet_cpu_enabled(fan.enabled);
|
||||
global.set_quiet_cpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Quiet, FanType::CPU, nodes_vec);
|
||||
global.set_quiet_cpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::GPU => {
|
||||
global.set_gpu_fan_available(true);
|
||||
global.set_quiet_gpu_enabled(fan.enabled);
|
||||
global.set_quiet_gpu(nodes.clone());
|
||||
cache_fan_curve(Profile::Quiet, FanType::GPU, nodes_vec);
|
||||
global.set_quiet_gpu(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
rog_profiles::FanCurvePU::MID => {
|
||||
global.set_mid_fan_available(true);
|
||||
global.set_quiet_mid_enabled(fan.enabled);
|
||||
global.set_quiet_mid(nodes.clone());
|
||||
cache_fan_curve(Profile::Quiet, FanType::Middle, nodes_vec);
|
||||
global.set_quiet_mid(collect(&fan.temp, &fan.pwm))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,7 +171,6 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let choices_for_ui = platform_profile_choices.clone();
|
||||
let handle_next1 = handle_copy.clone();
|
||||
if let Err(e) = handle_copy.upgrade_in_event_loop(move |handle| {
|
||||
let handle_weak_for_fans = handle.as_weak();
|
||||
let global = handle.global::<FanPageData>();
|
||||
let fans1 = fans.clone();
|
||||
let choices = choices_for_ui.clone();
|
||||
@@ -272,103 +212,17 @@ pub fn setup_fan_curve_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
update_fan_data(handle_next, balanced, perf, quiet);
|
||||
});
|
||||
});
|
||||
|
||||
let handle_weak_for_cancel = handle_weak_for_fans.clone();
|
||||
global.on_set_fan_data(move |fan, profile, enabled, data| {
|
||||
if crate::ui::setup_fan_curve_custom::is_custom_fan_supported() {
|
||||
let handle_weak = handle_weak_for_fans.clone();
|
||||
let data: Vec<Node> = data.iter().collect();
|
||||
|
||||
use log::info;
|
||||
info!("MainThread: Request to apply custom curve for {:?}", fan);
|
||||
|
||||
// Explicitly spawn a thread to handle this, preventing ANY main thread blocking
|
||||
std::thread::spawn(move || {
|
||||
info!("WorkerThread: applying curve for {:?}", fan);
|
||||
crate::ui::setup_fan_curve_custom::apply_custom_fan_curve(
|
||||
handle_weak.clone(),
|
||||
fan,
|
||||
enabled,
|
||||
data,
|
||||
);
|
||||
info!("WorkerThread: returned from apply (async), clearing busy flag for {:?}", fan);
|
||||
|
||||
// Clear busy flag
|
||||
let _ = handle_weak.upgrade_in_event_loop(move |h| {
|
||||
let g = h.global::<FanPageData>();
|
||||
match fan {
|
||||
FanType::CPU => g.set_is_busy_cpu(false),
|
||||
FanType::GPU => g.set_is_busy_gpu(false),
|
||||
FanType::Middle => g.set_is_busy_mid(false),
|
||||
}
|
||||
info!("MainThread: cleared busy flag for {:?}", fan);
|
||||
});
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let fans = fans.clone();
|
||||
let handle_weak = handle_weak_for_fans.clone();
|
||||
let nodes_vec: Vec<Node> = data.iter().collect();
|
||||
let _data_copy = nodes_vec.clone();
|
||||
let cache_copy = nodes_vec.clone(); // Clone for cache update
|
||||
let fan_data = fan_data_for(fan, enabled, nodes_vec);
|
||||
let data: Vec<Node> = data.iter().collect();
|
||||
let data = fan_data_for(fan, enabled, data);
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
"Fan curve applied".into(),
|
||||
"Failed to apply fan curve".into(),
|
||||
handle_weak.clone(),
|
||||
fans.set_fan_curve(profile.into(), fan_data).await,
|
||||
);
|
||||
let _ = handle_weak.upgrade_in_event_loop(move |h| {
|
||||
let g = h.global::<FanPageData>();
|
||||
// Update Rust-side cache (isolated from Slint properties)
|
||||
cache_fan_curve(profile, fan, cache_copy);
|
||||
|
||||
match fan {
|
||||
FanType::CPU => g.set_is_busy_cpu(false),
|
||||
FanType::GPU => g.set_is_busy_gpu(false),
|
||||
FanType::Middle => g.set_is_busy_mid(false),
|
||||
}
|
||||
});
|
||||
fans.set_fan_curve(profile.into(), data)
|
||||
.await
|
||||
.map_err(|e| error!("{e:}"))
|
||||
.ok()
|
||||
});
|
||||
});
|
||||
global.on_cancel(move |fan_type, profile| {
|
||||
let handle_weak = handle_weak_for_cancel.clone();
|
||||
let _ = handle_weak.upgrade_in_event_loop(move |h: MainWindow| {
|
||||
let global = h.global::<FanPageData>();
|
||||
|
||||
// Retrieve from isolated Rust cache
|
||||
let nodes_opt = get_cached_fan_curve(profile, fan_type);
|
||||
|
||||
if let Some(nodes_vec) = nodes_opt {
|
||||
use log::info;
|
||||
info!("Canceling {:?} {:?} - restoring {} nodes from isolated cache", fan_type, profile, nodes_vec.len());
|
||||
|
||||
let new_model: slint::ModelRc<Node> = nodes_vec.as_slice().into();
|
||||
|
||||
match (profile, fan_type) {
|
||||
(crate::Profile::Balanced, FanType::CPU) => global.set_balanced_cpu(new_model),
|
||||
(crate::Profile::Balanced, FanType::GPU) => global.set_balanced_gpu(new_model),
|
||||
(crate::Profile::Balanced, FanType::Middle) => global.set_balanced_mid(new_model),
|
||||
(crate::Profile::Performance, FanType::CPU) => global.set_performance_cpu(new_model),
|
||||
(crate::Profile::Performance, FanType::GPU) => global.set_performance_gpu(new_model),
|
||||
(crate::Profile::Performance, FanType::Middle) => global.set_performance_mid(new_model),
|
||||
(crate::Profile::Quiet, FanType::CPU) => global.set_quiet_cpu(new_model),
|
||||
(crate::Profile::Quiet, FanType::GPU) => global.set_quiet_gpu(new_model),
|
||||
(crate::Profile::Quiet, FanType::Middle) => global.set_quiet_mid(new_model),
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
log::warn!("Cancel failed: No cached data for {:?} {:?}", fan_type, profile);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Initialize warning
|
||||
if crate::ui::setup_fan_curve_custom::is_custom_fan_supported() {
|
||||
global.set_show_custom_warning(true);
|
||||
}
|
||||
}) {
|
||||
error!("setup_fan_curve_page: upgrade_in_event_loop: {e:?}");
|
||||
}
|
||||
|
||||
182
rog-control-center/src/ui/setup_gpu.rs
Normal file
182
rog-control-center/src/ui/setup_gpu.rs
Normal file
@@ -0,0 +1,182 @@
|
||||
use log::error;
|
||||
use rog_platform::asus_armoury::{AttrValue, FirmwareAttributes};
|
||||
use slint::{ComponentHandle, ModelRc, SharedString};
|
||||
|
||||
use crate::{GPUPageData, MainWindow};
|
||||
|
||||
// Populate GPU page choices and wire the `cb_set_gpu_mode` callback
|
||||
pub fn setup_gpu_page(ui: &MainWindow) {
|
||||
let handle = ui.as_weak();
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Read available attributes
|
||||
let attrs = FirmwareAttributes::new();
|
||||
let gpu_mux_available = attrs
|
||||
.gpu_mux_mode()
|
||||
.map(|a| a.base_path_exists())
|
||||
.unwrap_or(false);
|
||||
|
||||
// Prepare choice strings
|
||||
let mut choices: Vec<SharedString> = Vec::new();
|
||||
choices.push(SharedString::from("Integrated"));
|
||||
if gpu_mux_available {
|
||||
choices.push(SharedString::from("Ultimate"));
|
||||
}
|
||||
choices.push(SharedString::from("Hybrid"));
|
||||
|
||||
// Read current attribute values to initialise UI state
|
||||
let current_dgpu = attrs
|
||||
.dgpu_disable()
|
||||
.and_then(|a| a.current_value().ok())
|
||||
.unwrap_or(AttrValue::Integer(0));
|
||||
let current_mux = attrs
|
||||
.gpu_mux_mode()
|
||||
.and_then(|a| a.current_value().ok())
|
||||
.unwrap_or(AttrValue::Integer(1));
|
||||
|
||||
// Convert to UI-able values
|
||||
let dgpu_disabled = matches!(current_dgpu, AttrValue::Integer(v) if v == 1);
|
||||
// Determine initial index for gpu_mux_mode property
|
||||
let initial_index: i32 = if gpu_mux_available {
|
||||
// If mux attr says 0 -> Ultimate, else try dgpu to refine
|
||||
match current_mux {
|
||||
AttrValue::Integer(0) => 1, // Ultimate
|
||||
_ => {
|
||||
match current_dgpu {
|
||||
AttrValue::Integer(1) => 0, // Integrated
|
||||
_ => 2, // Hybrid/Optimus fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Only Integrated / Hybrid
|
||||
match current_dgpu {
|
||||
AttrValue::Integer(1) => 0,
|
||||
_ => 1,
|
||||
}
|
||||
};
|
||||
|
||||
let handle_copy = handle.clone();
|
||||
if let Err(e) = handle.upgrade_in_event_loop(move |handle| {
|
||||
let global = handle.global::<GPUPageData>();
|
||||
|
||||
// set choices model
|
||||
let model: ModelRc<SharedString> = choices.as_slice().into();
|
||||
global.set_gpu_modes_choises(model);
|
||||
global.set_gpu_mux_available(gpu_mux_available);
|
||||
|
||||
// set initial state
|
||||
global.set_dgpu_disabled(if dgpu_disabled { 1 } else { 0 });
|
||||
global.set_gpu_mux_mode(initial_index);
|
||||
|
||||
// register callback
|
||||
let handle_cb = handle_copy.clone();
|
||||
global.on_cb_set_gpu_mode(move |index: i32| {
|
||||
// show a blue toast informing user a reboot is required (auto-clears)
|
||||
let toast_handle = handle_cb.clone();
|
||||
crate::ui::show_toast(
|
||||
SharedString::from(
|
||||
"GPU mode change scheduled — reboot required for changes to apply.",
|
||||
),
|
||||
SharedString::from("Failed to set GPU mode"),
|
||||
toast_handle.clone(),
|
||||
Ok(()),
|
||||
);
|
||||
|
||||
let handle_next = handle_cb.clone();
|
||||
tokio::spawn(async move {
|
||||
let attrs = FirmwareAttributes::new();
|
||||
let mux_avail = attrs
|
||||
.gpu_mux_mode()
|
||||
.map(|a| a.base_path_exists())
|
||||
.unwrap_or(false);
|
||||
|
||||
// helper to set attribute ignoring errors
|
||||
if mux_avail {
|
||||
match index {
|
||||
0 => {
|
||||
// Integrated
|
||||
if let Some(attr) = attrs.dgpu_disable() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(1));
|
||||
}
|
||||
if let Some(attr) = attrs.gpu_mux_mode() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(1));
|
||||
}
|
||||
}
|
||||
1 => {
|
||||
// Ultimate
|
||||
if let Some(attr) = attrs.dgpu_disable() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(0));
|
||||
}
|
||||
if let Some(attr) = attrs.gpu_mux_mode() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(0));
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
// Dynamic
|
||||
if let Some(attr) = attrs.dgpu_disable() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(0));
|
||||
}
|
||||
if let Some(attr) = attrs.gpu_mux_mode() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(1));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match index {
|
||||
0 => {
|
||||
if let Some(attr) = attrs.dgpu_disable() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(1));
|
||||
}
|
||||
}
|
||||
1 => {
|
||||
if let Some(attr) = attrs.dgpu_disable() {
|
||||
let _ = attr.set_current_value(&AttrValue::Integer(0));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
|
||||
// After attempting write(s), refresh UI from attributes
|
||||
let attrs2 = FirmwareAttributes::new();
|
||||
let cur_dgpu = attrs2
|
||||
.dgpu_disable()
|
||||
.and_then(|a| a.current_value().ok())
|
||||
.unwrap_or(AttrValue::Integer(0));
|
||||
let cur_mux = attrs2
|
||||
.gpu_mux_mode()
|
||||
.and_then(|a| a.current_value().ok())
|
||||
.unwrap_or(AttrValue::Integer(1));
|
||||
|
||||
let dgpu_disabled = matches!(cur_dgpu, AttrValue::Integer(v) if v == 1);
|
||||
let new_index: i32 = if mux_avail {
|
||||
match cur_mux {
|
||||
AttrValue::Integer(0) => 1,
|
||||
_ => match cur_dgpu {
|
||||
AttrValue::Integer(1) => 0,
|
||||
_ => 2,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
match cur_dgpu {
|
||||
AttrValue::Integer(1) => 0,
|
||||
_ => 1,
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = handle_next.upgrade_in_event_loop(move |h| {
|
||||
let g = h.global::<GPUPageData>();
|
||||
g.set_dgpu_disabled(if dgpu_disabled { 1 } else { 0 });
|
||||
g.set_gpu_mux_mode(new_index);
|
||||
}) {
|
||||
error!("setup_gpu callback: upgrade_in_event_loop: {e:?}");
|
||||
}
|
||||
});
|
||||
});
|
||||
}) {
|
||||
error!("setup_gpu_page: upgrade_in_event_loop: {e:?}");
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
use log::{debug, error};
|
||||
use rog_dbus::zbus_backlight::BacklightProxy;
|
||||
use slint::ComponentHandle;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::ui::show_toast;
|
||||
use crate::{MainWindow, ScreenpadPageData};
|
||||
|
||||
pub fn setup_screenpad(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let handle = ui.as_weak();
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Create the connections/proxies here
|
||||
let conn = match zbus::Connection::system().await {
|
||||
Ok(conn) => conn,
|
||||
Err(e) => {
|
||||
error!("Failed to connect to system bus for Screenpad: {e:}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let backlight = match BacklightProxy::builder(&conn).build().await {
|
||||
Ok(backlight) => backlight,
|
||||
Err(e) => {
|
||||
error!("Failed to create backlight proxy for Screenpad: {e:}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize state
|
||||
debug!("Initializing Screenpad page data");
|
||||
|
||||
// Use helper to set initial properties
|
||||
if let Ok(val) = backlight.screenpad_brightness().await {
|
||||
handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
h.global::<ScreenpadPageData>().set_brightness(val);
|
||||
// Assume power is on if brightness > 0
|
||||
h.global::<ScreenpadPageData>().set_power(val > 0);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
if let Ok(gamma_str) = backlight.screenpad_gamma().await {
|
||||
if let Ok(gamma) = gamma_str.parse::<f32>() {
|
||||
handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
h.global::<ScreenpadPageData>().set_gamma(gamma);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(sync) = backlight.screenpad_sync_with_primary().await {
|
||||
handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
h.global::<ScreenpadPageData>().set_sync_with_primary(sync);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
// Set up callbacks
|
||||
let handle_copy = handle.clone();
|
||||
let backlight_copy = backlight.clone();
|
||||
handle
|
||||
.upgrade_in_event_loop(move |h| {
|
||||
let global = h.global::<ScreenpadPageData>();
|
||||
|
||||
// Brightness Callback
|
||||
let hl = handle_copy.clone();
|
||||
let bl = backlight_copy.clone();
|
||||
global.on_cb_brightness(move |val| {
|
||||
let bl = bl.clone();
|
||||
let hl = hl.clone();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
format!("Screenpad brightness set to {}", val).into(),
|
||||
"Failed to set Screenpad brightness".into(),
|
||||
hl,
|
||||
bl.set_screenpad_brightness(val).await,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Gamma Callback
|
||||
let hl = handle_copy.clone();
|
||||
let bl = backlight_copy.clone();
|
||||
global.on_cb_gamma(move |val| {
|
||||
let bl = bl.clone();
|
||||
let hl = hl.clone();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
format!("Screenpad gamma set to {:.2}", val).into(),
|
||||
"Failed to set Screenpad gamma".into(),
|
||||
hl,
|
||||
bl.set_screenpad_gamma(&val.to_string()).await,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Sync Callback
|
||||
let hl = handle_copy.clone();
|
||||
let bl = backlight_copy.clone();
|
||||
global.on_cb_sync_with_primary(move |val| {
|
||||
let bl = bl.clone();
|
||||
let hl = hl.clone();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
format!(
|
||||
"Screenpad sync {}",
|
||||
if val { "enabled" } else { "disabled" }
|
||||
)
|
||||
.into(),
|
||||
"Failed to toggle Screenpad sync".into(),
|
||||
hl,
|
||||
bl.set_screenpad_sync_with_primary(val).await,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Power Callback (Toggle brightness to 0/last or 100)
|
||||
let hl = handle_copy.clone();
|
||||
let bl = backlight_copy.clone();
|
||||
global.on_cb_power(move |val| {
|
||||
let bl = bl.clone();
|
||||
let hl = hl.clone();
|
||||
tokio::spawn(async move {
|
||||
let target = if val { 100 } else { 0 };
|
||||
let _ = bl.set_screenpad_brightness(target).await;
|
||||
hl.upgrade_in_event_loop(move |h| {
|
||||
h.global::<ScreenpadPageData>().set_brightness(target);
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
|
||||
// Optional: Value watches for external changes
|
||||
// (Similar to setup_system.rs if needed)
|
||||
});
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
use crate::config::Config;
|
||||
use crate::set_ui_callbacks;
|
||||
use crate::ui::show_toast;
|
||||
use crate::{MainWindow, SlashPageData};
|
||||
use rog_dbus::{find_iface_async, zbus_slash::SlashProxy};
|
||||
use rog_slash::SlashMode;
|
||||
use slint::{ComponentHandle, Model};
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub fn setup_slash(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let ui_weak = ui.as_weak();
|
||||
|
||||
tokio::spawn(async move {
|
||||
// Find the Slash interface proxy
|
||||
let proxies = match find_iface_async::<SlashProxy>("xyz.ljones.Slash").await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to find Slash interface: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let proxy = match proxies.first() {
|
||||
Some(p) => p.clone(),
|
||||
None => return,
|
||||
};
|
||||
|
||||
// UI Callbacks (MUST be done on UI thread to access global state)
|
||||
{
|
||||
let proxy_copy = proxy.clone();
|
||||
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
let proxy = proxy_copy.clone();
|
||||
let ui_handle = ui;
|
||||
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.enabled(), "Slash enabled {}", "Failed to enable slash");
|
||||
|
||||
// Fix: Cast f32 (UI) to u8 (DBus)
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(as f32), proxy.brightness(as u8), "Slash brightness set to {}", "Failed to set slash brightness");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(as f32), proxy.interval(as u8), "Slash interval set to {}", "Failed to set slash interval");
|
||||
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_battery_warning(), "Battery warning set to {}", "Failed to set battery warning");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_on_battery(), "Show on battery set to {}", "Failed to set show on battery");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_on_boot(), "Show on boot set to {}", "Failed to set show on boot");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_on_shutdown(), "Show on shutdown set to {}", "Failed to set show on shutdown");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_on_sleep(), "Show on sleep set to {}", "Failed to set show on sleep");
|
||||
set_ui_callbacks!(ui_handle, SlashPageData(), proxy.show_on_lid_closed(), "Show on lid closed set to {}", "Failed to set show on lid closed");
|
||||
});
|
||||
}
|
||||
|
||||
// Custom Mode Logic - Callback setup
|
||||
{
|
||||
let proxy_copy = proxy.clone();
|
||||
let ui_weak_copy = ui_weak.clone();
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
let data = ui.global::<SlashPageData>();
|
||||
|
||||
data.on_cb_mode_index(move |idx| {
|
||||
let proxy_copy = proxy_copy.clone();
|
||||
let handle_weak = ui_weak_copy.clone();
|
||||
|
||||
let mode_str_opt = if let Some(h) = handle_weak.upgrade() {
|
||||
let d = h.global::<SlashPageData>();
|
||||
if idx >= 0 && (idx as usize) < d.get_modes().row_count() {
|
||||
Some(d.get_modes().row_data(idx as usize).unwrap_or_default())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(mode_str) = mode_str_opt {
|
||||
if let Ok(mode) = SlashMode::from_str(&mode_str) {
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
format!("Slash mode set to {}", mode).into(),
|
||||
"Failed to set slash mode".into(),
|
||||
handle_weak,
|
||||
proxy_copy.set_mode(mode).await,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// D-Bus Signal -> UI
|
||||
let proxy_copy = proxy.clone();
|
||||
let handle_copy = ui_weak.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut changes = proxy_copy.receive_mode_changed().await;
|
||||
use futures_util::StreamExt;
|
||||
while let Some(change) = changes.next().await {
|
||||
if let Ok(mode) = change.get().await {
|
||||
let mode_str = mode.to_string();
|
||||
let handle_copy = handle_copy.clone();
|
||||
let _ = slint::invoke_from_event_loop(move || {
|
||||
if let Some(h) = handle_copy.upgrade() {
|
||||
let d = h.global::<SlashPageData>();
|
||||
let model = d.get_modes();
|
||||
for (i, m) in model.iter().enumerate() {
|
||||
if m == mode_str {
|
||||
d.set_mode_index(i as i32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if let Ok(m) = proxy.mode().await {
|
||||
let mode_str = m.to_string();
|
||||
let _ = slint::invoke_from_event_loop(move || {
|
||||
if let Some(h) = ui_weak.upgrade() {
|
||||
let d = h.global::<SlashPageData>();
|
||||
let model = d.get_modes();
|
||||
for (i, m) in model.iter().enumerate() {
|
||||
if m == mode_str {
|
||||
d.set_mode_index(i as i32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
use crate::config::Config;
|
||||
use crate::tray::TrayStats;
|
||||
use crate::{MainWindow, SystemStatus};
|
||||
use rog_dbus::zbus_platform::PlatformProxy;
|
||||
use slint::ComponentHandle;
|
||||
use std::collections::VecDeque;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use tokio::fs;
|
||||
use tokio::time::Duration;
|
||||
use zbus::Connection;
|
||||
|
||||
pub fn setup_status(
|
||||
ui: &MainWindow,
|
||||
_config: Arc<Mutex<Config>>,
|
||||
stats_tx: tokio::sync::watch::Sender<TrayStats>,
|
||||
) {
|
||||
let ui_weak = ui.as_weak();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut power_history: VecDeque<i32> = VecDeque::with_capacity(150); // 300s window at 2s poll
|
||||
// DBus connection for profile
|
||||
let conn = Connection::system().await.ok();
|
||||
let platform = if let Some(c) = &conn {
|
||||
PlatformProxy::new(c).await.ok()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
loop {
|
||||
let (cpu_temp, gpu_temp, cpu_fan, gpu_fan) = read_hwmon().await;
|
||||
let power_microwatts = read_power().await;
|
||||
|
||||
// Rolling average logic
|
||||
if power_history.len() >= 150 {
|
||||
power_history.pop_front();
|
||||
}
|
||||
power_history.push_back(power_microwatts);
|
||||
|
||||
let sum: i64 = power_history.iter().map(|&x| x as i64).sum();
|
||||
let avg_microwatts = if !power_history.is_empty() {
|
||||
sum / power_history.len() as i64
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
// Convert to Watts
|
||||
let power_w = power_microwatts as f64 / 1_000_000.0;
|
||||
let avg_w = avg_microwatts as f64 / 1_000_000.0;
|
||||
|
||||
// Fetch profile
|
||||
let mut profile_str = "Unknown".to_string();
|
||||
if let Some(p) = &platform {
|
||||
if let Ok(prof) = p.platform_profile().await {
|
||||
profile_str = format!("{:?}", prof);
|
||||
}
|
||||
}
|
||||
let ui_weak_loop = ui_weak.clone(); // Clone ui_weak for this iteration
|
||||
|
||||
// Send to Tray
|
||||
let _ = stats_tx.send(TrayStats {
|
||||
cpu_temp: format!("{}", cpu_temp),
|
||||
gpu_temp: format!("{}", gpu_temp),
|
||||
cpu_fan: format!("{}", cpu_fan),
|
||||
gpu_fan: format!("{}", gpu_fan),
|
||||
power_w: format!("{:.1}", power_w),
|
||||
power_profile: profile_str,
|
||||
});
|
||||
|
||||
let _ = slint::invoke_from_event_loop(move || {
|
||||
if let Some(ui) = ui_weak_loop.upgrade() {
|
||||
let global = ui.global::<SystemStatus>();
|
||||
global.set_cpu_temp(cpu_temp);
|
||||
global.set_gpu_temp(gpu_temp);
|
||||
global.set_cpu_fan(cpu_fan);
|
||||
global.set_gpu_fan(gpu_fan);
|
||||
|
||||
global.set_power_w(slint::SharedString::from(format!("{:.1}", power_w)));
|
||||
global.set_power_avg_w(slint::SharedString::from(format!("{:.1}", avg_w)));
|
||||
}
|
||||
});
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async fn read_hwmon() -> (i32, i32, i32, i32) {
|
||||
let mut cpu_temp = 0;
|
||||
let mut gpu_temp = 0;
|
||||
let mut cpu_fan = 0;
|
||||
let mut gpu_fan = 0;
|
||||
|
||||
let mut entries = match fs::read_dir("/sys/class/hwmon").await {
|
||||
Ok(e) => e,
|
||||
Err(_) => return (0, 0, 0, 0),
|
||||
};
|
||||
|
||||
while let Ok(Some(entry)) = entries.next_entry().await {
|
||||
let path = entry.path();
|
||||
let name_path = path.join("name");
|
||||
|
||||
if let Ok(name_str) = fs::read_to_string(&name_path).await {
|
||||
let name = name_str.trim();
|
||||
|
||||
if name == "k10temp" || name == "coretemp" || name == "zenpower" {
|
||||
// Try temp1_input (TCtl/Package)
|
||||
if let Ok(temp) = read_val(&path.join("temp1_input")).await {
|
||||
cpu_temp = temp / 1000;
|
||||
}
|
||||
} else if name == "amdgpu" || name == "nvidia" {
|
||||
if let Ok(temp) = read_val(&path.join("temp1_input")).await {
|
||||
gpu_temp = temp / 1000;
|
||||
}
|
||||
} else if name == "asus" || name == "asus_custom_fan_curve" {
|
||||
if let Ok(fan) = read_val(&path.join("fan1_input")).await {
|
||||
cpu_fan = fan;
|
||||
}
|
||||
if let Ok(fan) = read_val(&path.join("fan2_input")).await {
|
||||
gpu_fan = fan;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(cpu_temp, gpu_temp, cpu_fan, gpu_fan)
|
||||
}
|
||||
|
||||
async fn read_val(path: &PathBuf) -> Result<i32, ()> {
|
||||
let s = fs::read_to_string(path).await.map_err(|_| ())?;
|
||||
s.trim().parse::<i32>().map_err(|_| ())
|
||||
}
|
||||
|
||||
async fn read_power() -> i32 {
|
||||
let mut p = 0;
|
||||
// Try BAT0 then BAT1
|
||||
if let Ok(v) = read_val(&PathBuf::from("/sys/class/power_supply/BAT0/power_now")).await {
|
||||
p = v.abs();
|
||||
} else if let Ok(v) = read_val(&PathBuf::from("/sys/class/power_supply/BAT1/power_now")).await {
|
||||
p = v.abs();
|
||||
}
|
||||
|
||||
// Check status
|
||||
if let Ok(s) = fs::read_to_string("/sys/class/power_supply/BAT0/status").await {
|
||||
if s.trim() == "Discharging" {
|
||||
return -p;
|
||||
}
|
||||
}
|
||||
p
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
use crate::config::Config;
|
||||
use crate::ui::show_toast;
|
||||
use crate::{MainWindow, SupergfxPageData};
|
||||
use slint::{ComponentHandle, Model, SharedString, VecModel};
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use zbus::proxy;
|
||||
|
||||
#[proxy(
|
||||
interface = "org.supergfxctl.Daemon",
|
||||
default_service = "org.supergfxctl.Daemon",
|
||||
default_path = "/org/supergfxctl/Gfx"
|
||||
)]
|
||||
trait Supergfx {
|
||||
fn supported(&self) -> zbus::Result<Vec<String>>;
|
||||
fn mode(&self) -> zbus::Result<String>;
|
||||
fn set_mode(&self, mode: &str) -> zbus::Result<()>;
|
||||
fn vendor(&self) -> zbus::Result<String>;
|
||||
}
|
||||
|
||||
pub fn setup_supergfx(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
let ui_weak = ui.as_weak();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let conn = match zbus::Connection::system().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to connect to system bus: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let proxy = match SupergfxProxy::new(&conn).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to create Supergfx proxy: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Register Callbacks on UI Thread
|
||||
{
|
||||
let proxy_copy = proxy.clone();
|
||||
let ui_weak_copy = ui_weak.clone();
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
let handle_copy = ui_weak_copy.clone();
|
||||
ui.global::<SupergfxPageData>()
|
||||
.on_set_mode(move |mode_str| {
|
||||
let proxy = proxy_copy.clone();
|
||||
let handle = handle_copy.clone();
|
||||
tokio::spawn(async move {
|
||||
show_toast(
|
||||
format!("Switching to {}. Logout required.", mode_str).into(),
|
||||
"Failed to set mode".into(),
|
||||
handle,
|
||||
proxy.set_mode(&mode_str).await,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Fetch Initial State
|
||||
// Vendor
|
||||
if let Ok(vendor) = proxy.vendor().await {
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
ui.global::<SupergfxPageData>().set_vendor(vendor.into())
|
||||
});
|
||||
}
|
||||
|
||||
// Supported Modes
|
||||
if let Ok(supported) = proxy.supported().await {
|
||||
let modes: Vec<SharedString> = supported
|
||||
.iter()
|
||||
.map(|s| SharedString::from(s.as_str()))
|
||||
.collect();
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
let mode_model = Rc::new(VecModel::from(modes));
|
||||
ui.global::<SupergfxPageData>()
|
||||
.set_supported_modes(mode_model.into())
|
||||
});
|
||||
}
|
||||
|
||||
// Current Mode
|
||||
if let Ok(mode) = proxy.mode().await {
|
||||
let _ = ui_weak.upgrade_in_event_loop(move |ui| {
|
||||
let g = ui.global::<SupergfxPageData>();
|
||||
g.set_current_mode(mode.clone().into());
|
||||
// Update selection index
|
||||
let model = g.get_supported_modes();
|
||||
for (i, m) in model.iter().enumerate() {
|
||||
if m == mode.as_str() {
|
||||
g.set_selected_index(i as i32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// No signal monitoring implemented as supergfxctl state changes usually require user action/logout
|
||||
});
|
||||
}
|
||||
@@ -40,13 +40,10 @@ pub fn setup_system_page(ui: &MainWindow, _config: Arc<Mutex<Config>>) {
|
||||
ui.global::<SystemPageData>().set_platform_profile(-1);
|
||||
ui.global::<SystemPageData>().set_panel_overdrive(-1);
|
||||
ui.global::<SystemPageData>().set_boot_sound(-1);
|
||||
ui.global::<SystemPageData>().set_kbd_leds_awake(-1);
|
||||
ui.global::<SystemPageData>().set_kbd_leds_sleep(-1);
|
||||
ui.global::<SystemPageData>().set_kbd_leds_boot(-1);
|
||||
ui.global::<SystemPageData>().set_kbd_leds_shutdown(-1);
|
||||
ui.global::<SystemPageData>().set_screen_auto_brightness(-1);
|
||||
ui.global::<SystemPageData>().set_mcu_powersave(-1);
|
||||
ui.global::<SystemPageData>().set_mini_led_mode(-1);
|
||||
ui.global::<SystemPageData>().set_screenpad_brightness(-1);
|
||||
ui.global::<SystemPageData>().set_ppt_pl1_spl(MINMAX);
|
||||
ui.global::<SystemPageData>().set_ppt_pl2_sppt(MINMAX);
|
||||
ui.global::<SystemPageData>().set_ppt_pl3_fppt(MINMAX);
|
||||
@@ -295,7 +292,7 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
|
||||
log::error!("Failed to create platform proxy: {}", e);
|
||||
})
|
||||
.unwrap();
|
||||
let _backlight = BacklightProxy::builder(&conn)
|
||||
let backlight = BacklightProxy::builder(&conn)
|
||||
.build()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
@@ -396,7 +393,23 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
|
||||
|
||||
set_ui_props_async!(handle, platform, SystemPageData, enable_ppt_group);
|
||||
|
||||
set_ui_props_async!(handle, platform, SystemPageData, enable_ppt_group);
|
||||
set_ui_props_async!(handle, backlight, SystemPageData, screenpad_brightness);
|
||||
if let Ok(value) = backlight.screenpad_gamma().await {
|
||||
handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
handle
|
||||
.global::<SystemPageData>()
|
||||
.set_screenpad_gamma(value.parse().unwrap_or(1.0));
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
set_ui_props_async!(
|
||||
handle,
|
||||
backlight,
|
||||
SystemPageData,
|
||||
screenpad_sync_with_primary
|
||||
);
|
||||
|
||||
let platform_copy = platform.clone();
|
||||
handle
|
||||
@@ -519,11 +532,25 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
|
||||
"Setting Throttle policy on AC failed"
|
||||
);
|
||||
|
||||
set_ui_callbacks!(handle,
|
||||
SystemPageData(as i32),
|
||||
backlight.screenpad_brightness(as i32),
|
||||
"Screenpad successfully set to {}",
|
||||
"Setting screenpad brightness failed"
|
||||
);
|
||||
|
||||
set_ui_callbacks!(handle,
|
||||
SystemPageData(as bool),
|
||||
platform_copy.change_platform_profile_on_battery(.into()),
|
||||
"Throttle policy on battery enabled: {}",
|
||||
"Setting Throttle policy on AC failed"
|
||||
backlight.screenpad_sync_with_primary(as bool),
|
||||
"Screenpad successfully set to {}",
|
||||
"Setting screenpad brightness failed"
|
||||
);
|
||||
|
||||
set_ui_callbacks!(handle,
|
||||
SystemPageData(.parse().unwrap_or(1.0)),
|
||||
backlight.screenpad_gamma(.to_string().as_str()),
|
||||
"Screenpad successfully set to {}",
|
||||
"Setting screenpad brightness failed"
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
@@ -642,26 +669,6 @@ pub fn setup_system_page_callbacks(ui: &MainWindow, _states: Arc<Mutex<Config>>)
|
||||
setup_callback!(boot_sound, handle, attr, i32);
|
||||
setup_external!(boot_sound, i32, handle, attr, value)
|
||||
}
|
||||
FirmwareAttribute::KbdLedsAwake => {
|
||||
init_property!(kbd_leds_awake, handle, value, i32);
|
||||
setup_callback!(kbd_leds_awake, handle, attr, i32);
|
||||
setup_external!(kbd_leds_awake, i32, handle, attr, value)
|
||||
}
|
||||
FirmwareAttribute::KbdLedsSleep => {
|
||||
init_property!(kbd_leds_sleep, handle, value, i32);
|
||||
setup_callback!(kbd_leds_sleep, handle, attr, i32);
|
||||
setup_external!(kbd_leds_sleep, i32, handle, attr, value)
|
||||
}
|
||||
FirmwareAttribute::KbdLedsBoot => {
|
||||
init_property!(kbd_leds_boot, handle, value, i32);
|
||||
setup_callback!(kbd_leds_boot, handle, attr, i32);
|
||||
setup_external!(kbd_leds_boot, i32, handle, attr, value)
|
||||
}
|
||||
FirmwareAttribute::KbdLedsShutdown => {
|
||||
init_property!(kbd_leds_shutdown, handle, value, i32);
|
||||
setup_callback!(kbd_leds_shutdown, handle, attr, i32);
|
||||
setup_external!(kbd_leds_shutdown, i32, handle, attr, value)
|
||||
}
|
||||
FirmwareAttribute::ScreenAutoBrightness => {
|
||||
init_property!(screen_auto_brightness, handle, value, i32);
|
||||
setup_callback!(screen_auto_brightness, handle, attr, i32);
|
||||
|
||||
Binary file not shown.
810
rog-control-center/translations/uk_UA/rog-control-center.po
Normal file
810
rog-control-center/translations/uk_UA/rog-control-center.po
Normal file
@@ -0,0 +1,810 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: rog-control-center\n"
|
||||
"POT-Creation-Date: 2026-01-16 22:25+0000\n"
|
||||
"PO-Revision-Date: 2024-07-28 12:00+0300\n"
|
||||
"Last-Translator: Mykola Shevchenko\n"
|
||||
"Language-Team: Ukrainian\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: uk_UA\n"
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:55
|
||||
msgctxt "MainWindow"
|
||||
msgid "ROG"
|
||||
msgstr "ROG"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:57
|
||||
msgctxt "Menu1"
|
||||
msgid "System Control"
|
||||
msgstr "Системні"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:58
|
||||
msgctxt "Menu2"
|
||||
msgid "Keyboard Aura"
|
||||
msgstr "Aura клавіатури"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:59
|
||||
msgctxt "Menu3"
|
||||
msgid "AniMe Matrix"
|
||||
msgstr "AniMe матриця"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:60
|
||||
msgctxt "Menu4"
|
||||
msgid "Fan Curves"
|
||||
msgstr "Криві вентиляторів"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:61
|
||||
msgctxt "Menu5"
|
||||
msgid "App Settings"
|
||||
msgstr "Налаштування"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:62
|
||||
msgctxt "Menu6"
|
||||
msgid "About"
|
||||
msgstr "Про додаток"
|
||||
|
||||
#: rog-control-center/ui/main_window.slint:74
|
||||
msgctxt "MainWindow"
|
||||
msgid "Quit App"
|
||||
msgstr "Вийти"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:6
|
||||
msgctxt "Anime Brightness"
|
||||
msgid "Off"
|
||||
msgstr "Вимкнено"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:7
|
||||
msgctxt "Anime Brightness"
|
||||
msgid "Low"
|
||||
msgstr "Низька"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:8
|
||||
msgctxt "Anime Brightness"
|
||||
msgid "Med"
|
||||
msgstr "Середня"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:9
|
||||
msgctxt "Anime Brightness"
|
||||
msgid "High"
|
||||
msgstr "Висока"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:23
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Glitch Construction"
|
||||
msgstr "Збій конструкції"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:23
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Static Emergence"
|
||||
msgstr "Статична поява"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:25
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Binary Banner Scroll"
|
||||
msgstr "Прокрутка бінарного банера"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:25
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Rog Logo Glitch"
|
||||
msgstr "Збій логотипу Rog"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:27
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Banner Swipe"
|
||||
msgstr "Прогортання банера"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:27
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Starfield"
|
||||
msgstr "Зоряне поле"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:29
|
||||
msgctxt "AnimePageData"
|
||||
msgid "Glitch Out"
|
||||
msgstr "Збій"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:29
|
||||
msgctxt "AnimePageData"
|
||||
msgid "See Ya"
|
||||
msgstr "Бувай"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:50
|
||||
msgctxt "Anime Brightness"
|
||||
msgid "Brightness"
|
||||
msgstr "Яскравість"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:66
|
||||
msgctxt "PageAnime"
|
||||
msgid "Enable display"
|
||||
msgstr "Увімкнути показ"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:74 rog-control-center/ui/pages/anime.slint:97
|
||||
msgctxt "PageAnime"
|
||||
msgid "Advanced"
|
||||
msgstr "Розширені"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:89
|
||||
msgctxt "PageAnime"
|
||||
msgid "Use built-in animations"
|
||||
msgstr "Використовувати вбудовані анімації"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:146
|
||||
msgctxt "PageAnime"
|
||||
msgid "Set which builtin animations are played"
|
||||
msgstr "Встановити, які вбудовані анімації відтворювати"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:150
|
||||
msgctxt "Anime built-in selection"
|
||||
msgid "Boot Animation"
|
||||
msgstr "Анімація завантаження"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:160
|
||||
msgctxt "Anime built-in selection"
|
||||
msgid "Running Animation"
|
||||
msgstr "Анімація роботи"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:170
|
||||
msgctxt "Anime built-in selection"
|
||||
msgid "Sleep Animation"
|
||||
msgstr "Анімація сну"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:180
|
||||
msgctxt "Anime built-in selection"
|
||||
msgid "Shutdown Animation"
|
||||
msgstr "Анімація вимкнення"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:220
|
||||
msgctxt "PageAnime"
|
||||
msgid "Advanced Display Settings"
|
||||
msgstr "Розширені налаштування показу"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:225
|
||||
msgctxt "PageAnime"
|
||||
msgid "Off when lid closed"
|
||||
msgstr "Вимикати при закритій кришці"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:234
|
||||
msgctxt "PageAnime"
|
||||
msgid "Off when suspended"
|
||||
msgstr "Вимикати в режимі сну"
|
||||
|
||||
#: rog-control-center/ui/pages/anime.slint:243
|
||||
msgctxt "PageAnime"
|
||||
msgid "Off when on battery"
|
||||
msgstr "Вимикати при роботі від батареї"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:20
|
||||
msgctxt "SystemPageData"
|
||||
msgid "Balanced"
|
||||
msgstr "Збалансований"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:20 rog-control-center/ui/pages/system.slint:27
|
||||
msgctxt "SystemPageData"
|
||||
msgid "Performance"
|
||||
msgstr "Продуктивний"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:20
|
||||
msgctxt "SystemPageData"
|
||||
msgid "Quiet"
|
||||
msgstr "Тихий"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:20
|
||||
msgctxt "SystemPageData"
|
||||
msgid "LowPower"
|
||||
msgstr "Низьке споживання"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:26
|
||||
msgctxt "SystemPageData"
|
||||
msgid "Default"
|
||||
msgstr "За замовчуванням"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:28
|
||||
msgctxt "SystemPageData"
|
||||
msgid "BalancePerformance"
|
||||
msgstr "Баланс-Продуктивність"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:29
|
||||
msgctxt "SystemPageData"
|
||||
msgid "BalancePower"
|
||||
msgstr "Баланс-Енергозбереження"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:30
|
||||
msgctxt "SystemPageData"
|
||||
msgid "Power"
|
||||
msgstr "Енергозбереження"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:159
|
||||
msgctxt "PageSystem"
|
||||
msgid "Power settings"
|
||||
msgstr "Налаштування живлення"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:164
|
||||
msgctxt "PageSystem"
|
||||
msgid "Charge limit"
|
||||
msgstr "Ліміт заряду"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:179
|
||||
msgctxt "PageSystem"
|
||||
msgid "Platform Profile"
|
||||
msgstr "Профіль платформи"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:189
|
||||
msgctxt "PageSystem"
|
||||
msgid "Advanced"
|
||||
msgstr "Розширені"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:209
|
||||
msgctxt "PageSystem"
|
||||
msgid "Screenpad brightness"
|
||||
msgstr "Яскравість екранної панелі"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:233
|
||||
msgctxt "PageSystem"
|
||||
msgid "Sync with primary"
|
||||
msgstr "Синхронізувати з основним"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:253
|
||||
msgctxt "PageSystem"
|
||||
msgid "Armoury settings"
|
||||
msgstr "Налаштування Armoury"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:253
|
||||
msgctxt "PageSystem"
|
||||
msgid "Keyboard Power Management"
|
||||
msgstr "Керування живленням клавіатури"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:263
|
||||
msgctxt "no_asus_armoury_driver_1"
|
||||
msgid "The asus-armoury driver is not loaded"
|
||||
msgstr "Драйвер asus-armoury не завантажено"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:269
|
||||
msgctxt "no_asus_armoury_driver_2"
|
||||
msgid "For advanced features you will require a kernel with this driver added."
|
||||
msgstr "Для розширених функцій вам знадобиться ядро з доданим цим драйвером."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:280
|
||||
msgctxt "PageSystem"
|
||||
msgid "Panel Overdrive"
|
||||
msgstr "Розгін матриці"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:288
|
||||
msgctxt "PageSystem"
|
||||
msgid "MiniLED Mode"
|
||||
msgstr "Режим MiniLED"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:296
|
||||
msgctxt "PageSystem"
|
||||
msgid "POST boot sound"
|
||||
msgstr "Звук при завантаженні"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:312
|
||||
msgctxt "ppt_warning"
|
||||
msgid "The following settings are not applied until the toggle is enabled."
|
||||
msgstr "Наступні налаштування не застосовуються, доки перемикач не буде увімкнено."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:317 rog-control-center/ui/pages/system.slint:324
|
||||
msgctxt "ppt_group_enabled"
|
||||
msgid "Enable Tuning"
|
||||
msgstr "Увімкнути налаштування"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:334 rog-control-center/ui/pages/system.slint:335
|
||||
msgctxt "ppt_pl1_spl"
|
||||
msgid "CPU Sustained Power Limit"
|
||||
msgstr "Тривалий ліміт потужності CPU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:336
|
||||
msgctxt "ppt_pl1_spl_help"
|
||||
msgid ""
|
||||
"Long-term CPU power limit that affects sustained workload performance. "
|
||||
"Higher values may increase heat and power consumption."
|
||||
msgstr ""
|
||||
"Довготривалий ліміт потужності CPU, що впливає на продуктивність при тривалих навантаженнях."
|
||||
"Вищі значення можуть збільшити нагрівання та споживання енергії."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:352 rog-control-center/ui/pages/system.slint:353
|
||||
msgctxt "ppt_pl2_sppt"
|
||||
msgid "CPU Turbo Power Limit"
|
||||
msgstr "Турбо ліміт потужності CPU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:354
|
||||
msgctxt "ppt_pl2_sppt_help"
|
||||
msgid ""
|
||||
"Short-term CPU power limit for boost periods. Controls maximum power during "
|
||||
"brief high-performance bursts."
|
||||
msgstr ""
|
||||
"Короткочасний ліміт потужності CPU для періодів прискорення. Контролює максимальну"
|
||||
"потужність під час коротких сплесків високої продуктивності."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:370 rog-control-center/ui/pages/system.slint:371
|
||||
msgctxt "ppt_pl3_fppt"
|
||||
msgid "CPU Fast Burst Power Limit"
|
||||
msgstr "Швидкий ліміт потужності CPU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:372
|
||||
msgctxt "ppt_pl3_fppt_help"
|
||||
msgid ""
|
||||
"Ultra-short duration power limit for instantaneous CPU bursts. Affects "
|
||||
"responsiveness during sudden workload spikes."
|
||||
msgstr ""
|
||||
"Надкороткий ліміт потужності для миттєвих сплесків CPU."
|
||||
"Впливає на чутливість під час раптових піків навантаження."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:387 rog-control-center/ui/pages/system.slint:388
|
||||
msgctxt "ppt_fppt"
|
||||
msgid "Fast Package Power Limit"
|
||||
msgstr "Швидкий ліміт потужності пакета"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:389
|
||||
msgctxt "ppt_fppt_help"
|
||||
msgid ""
|
||||
"Ultra-short duration power limit for system package. Controls maximum power "
|
||||
"during millisecond-scale load spikes."
|
||||
msgstr ""
|
||||
"Надкороткий ліміт потужності для системного пакета. Контролює максимальну"
|
||||
"потужність під час пікових навантажень мілісекундного масштабу."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:405 rog-control-center/ui/pages/system.slint:406
|
||||
msgctxt "ppt_apu_sppt"
|
||||
msgid "APU Sustained Power Limit"
|
||||
msgstr "Тривалий ліміт потужності APU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:407
|
||||
msgctxt "ppt_apu_sppt_help"
|
||||
msgid ""
|
||||
"Long-term power limit for integrated graphics and CPU combined. Affects "
|
||||
"sustained performance of APU-based workloads."
|
||||
msgstr ""
|
||||
"Довготривалий ліміт потужності для інтегрованої графіки та CPU разом."
|
||||
"Впливає на тривалу продуктивність навантажень на базі APU."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:423 rog-control-center/ui/pages/system.slint:424
|
||||
msgctxt "ppt_platform_sppt"
|
||||
msgid "Platform Sustained Power Limit"
|
||||
msgstr "Тривалий ліміт потужності платформи"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:425
|
||||
msgctxt "ppt_platform_sppt_help"
|
||||
msgid ""
|
||||
"Overall system power limit for sustained operations. Controls total platform "
|
||||
"power consumption over extended periods."
|
||||
msgstr ""
|
||||
"Загальний ліміт потужності системи для тривалих операцій. Контролює загальне"
|
||||
"споживання енергії платформою протягом тривалих періодів."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:441 rog-control-center/ui/pages/system.slint:442
|
||||
msgctxt "nv_dynamic_boost"
|
||||
msgid "GPU Power Boost"
|
||||
msgstr "Прискорення потужності GPU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:443
|
||||
msgctxt "nv_dynamic_boost_help"
|
||||
msgid ""
|
||||
"Additional power allocation for GPU dynamic boost. Higher values increase "
|
||||
"GPU performance but generate more heat."
|
||||
msgstr ""
|
||||
"Додаткове виділення потужності для динамічного прискорення GPU. Вищі значення"
|
||||
"збільшують продуктивність GPU, але генерують більше тепла."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:459 rog-control-center/ui/pages/system.slint:460
|
||||
msgctxt "nv_temp_target"
|
||||
msgid "GPU Temperature Limit"
|
||||
msgstr "Ліміт температури GPU"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:461
|
||||
msgctxt "nv_temp_target_help"
|
||||
msgid ""
|
||||
"Maximum GPU temperature threshold in Celsius. GPU will throttle to maintain "
|
||||
"temperature below this limit."
|
||||
msgstr ""
|
||||
"Максимальний поріг температури GPU у градусах Цельсія. GPU буде знижувати"
|
||||
"частоту для підтримки температури нижче цього ліміту."
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:513
|
||||
msgctxt "PageSystem"
|
||||
msgid "Energy Performance Preference linked to Throttle Policy"
|
||||
msgstr "Перевага енергоефективності пов'язана з Політикою Тротлінгу"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:517
|
||||
msgctxt "PageSystem"
|
||||
msgid "Change EPP based on Throttle Policy"
|
||||
msgstr "Змінювати EPP на основі Політики Тротлінгу"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:525
|
||||
msgctxt "PageSystem"
|
||||
msgid "EPP for Balanced Policy"
|
||||
msgstr "EPP для Збалансованої Політики"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:535
|
||||
msgctxt "PageSystem"
|
||||
msgid "EPP for Performance Policy"
|
||||
msgstr "EPP для Політики Продуктивності"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:545
|
||||
msgctxt "PageSystem"
|
||||
msgid "EPP for Quiet Policy"
|
||||
msgstr "EPP для Тихої Політики"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:563
|
||||
msgctxt "PageSystem"
|
||||
msgid "Throttle Policy for power state"
|
||||
msgstr "Політика Тротлінгу для стану живлення"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:569
|
||||
msgctxt "PageSystem"
|
||||
msgid "Throttle Policy on Battery"
|
||||
msgstr "Політика Тротлінгу при живленні від батареї"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:579 rog-control-center/ui/pages/system.slint:600
|
||||
msgctxt "PageSystem"
|
||||
msgid "Enabled"
|
||||
msgstr "Увімкнено"
|
||||
|
||||
#: rog-control-center/ui/pages/system.slint:590
|
||||
msgctxt "PageSystem"
|
||||
msgid "Throttle Policy on AC"
|
||||
msgstr "Політика Тротлінгу при живленні від мережі"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:28
|
||||
msgctxt "PageAura"
|
||||
msgid "Brightness"
|
||||
msgstr "Яскравість"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:39
|
||||
msgctxt "PageAura"
|
||||
msgid "Aura mode"
|
||||
msgstr "Режим Aura"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:59
|
||||
msgctxt "PageAura"
|
||||
msgid "Colour 1"
|
||||
msgstr "Колір 1"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:85
|
||||
msgctxt "PageAura"
|
||||
msgid "Colour 2"
|
||||
msgstr "Колір 2"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:119
|
||||
msgctxt "PageAura"
|
||||
msgid "Zone"
|
||||
msgstr "Зона"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:142
|
||||
msgctxt "PageAura"
|
||||
msgid "Direction"
|
||||
msgstr "Напрямок"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:164
|
||||
msgctxt "PageAura"
|
||||
msgid "Speed"
|
||||
msgstr "Швидкість"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:185
|
||||
msgctxt "PageAura"
|
||||
msgid "Power Settings"
|
||||
msgstr "Налаштування живлення"
|
||||
|
||||
#: rog-control-center/ui/pages/aura.slint:270
|
||||
msgctxt "PageAura"
|
||||
msgid "Power Zones"
|
||||
msgstr "Зони живлення"
|
||||
|
||||
#: rog-control-center/ui/pages/app_settings.slint:26
|
||||
msgctxt "PageAppSettings"
|
||||
msgid "Run in background after closing"
|
||||
msgstr "Працювати у фоні після закриття"
|
||||
|
||||
#: rog-control-center/ui/pages/app_settings.slint:34
|
||||
msgctxt "PageAppSettings"
|
||||
msgid "Start app in background (UI closed)"
|
||||
msgstr "Запускати у фоні (без інтерфейсу)"
|
||||
|
||||
#: rog-control-center/ui/pages/app_settings.slint:42
|
||||
msgctxt "PageAppSettings"
|
||||
msgid "Enable system tray icon"
|
||||
msgstr "Увімкнути іконку в треї"
|
||||
|
||||
#: rog-control-center/ui/pages/app_settings.slint:50
|
||||
msgctxt "PageAppSettings"
|
||||
msgid "Enable dGPU notifications"
|
||||
msgstr "Увімкнути сповіщення про dGPU"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:26
|
||||
msgctxt "FanTab"
|
||||
msgid "This fan is not avilable on this machine"
|
||||
msgstr "Цей вентилятор недоступний на цьому пристрої"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:34
|
||||
msgctxt "FanTab"
|
||||
msgid "Enabled"
|
||||
msgstr "Увімкнено"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:43
|
||||
msgctxt "FanTab"
|
||||
msgid "Apply"
|
||||
msgstr "Застосувати"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:51
|
||||
msgctxt "FanTab"
|
||||
msgid "Cancel"
|
||||
msgstr "Скасувати"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:59
|
||||
msgctxt "FanTab"
|
||||
msgid "Factory Default (all fans)"
|
||||
msgstr "Заводські налаштування (всі вентилятори)"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:72
|
||||
msgctxt "PageFans"
|
||||
msgid "Balanced"
|
||||
msgstr "Збалансований"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:75 rog-control-center/ui/pages/fans.slint:134 rog-control-center/ui/pages/fans.slint:193
|
||||
msgctxt "PageFans"
|
||||
msgid "CPU"
|
||||
msgstr "CPU"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:93 rog-control-center/ui/pages/fans.slint:152 rog-control-center/ui/pages/fans.slint:211
|
||||
msgctxt "PageFans"
|
||||
msgid "Mid"
|
||||
msgstr "Середній"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:111 rog-control-center/ui/pages/fans.slint:170 rog-control-center/ui/pages/fans.slint:229
|
||||
msgctxt "PageFans"
|
||||
msgid "GPU"
|
||||
msgstr "GPU"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:131
|
||||
msgctxt "PageFans"
|
||||
msgid "Performance"
|
||||
msgstr "Продуктивний"
|
||||
|
||||
#: rog-control-center/ui/pages/fans.slint:190
|
||||
msgctxt "PageFans"
|
||||
msgid "Quiet"
|
||||
msgstr "Тихий"
|
||||
|
||||
#: rog-control-center/ui/widgets/common.slint:126
|
||||
msgctxt "confirm_reset"
|
||||
msgid "Are you sure you want to reset this?"
|
||||
msgstr "Ви впевнені, що хочете скинути це?"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:33
|
||||
msgctxt "AuraPowerGroup"
|
||||
msgid "Boot"
|
||||
msgstr "Запуск"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:43
|
||||
msgctxt "AuraPowerGroup"
|
||||
msgid "Awake"
|
||||
msgstr "Робота"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:53
|
||||
msgctxt "AuraPowerGroup"
|
||||
msgid "Sleep"
|
||||
msgstr "Сон"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:63
|
||||
msgctxt "AuraPowerGroup"
|
||||
msgid "Shutdown"
|
||||
msgstr "Вимкнення"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:102
|
||||
msgctxt "AuraPowerGroupOld"
|
||||
msgid "Zone Selection"
|
||||
msgstr "Вибір зони"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:114
|
||||
msgctxt "AuraPowerGroupOld"
|
||||
msgid "Boot"
|
||||
msgstr "Завантаження"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:124
|
||||
msgctxt "AuraPowerGroupOld"
|
||||
msgid "Awake"
|
||||
msgstr "Робота"
|
||||
|
||||
#: rog-control-center/ui/widgets/aura_power.slint:134
|
||||
msgctxt "AuraPowerGroupOld"
|
||||
msgid "Sleep"
|
||||
msgstr "Сон"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:52
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Logo"
|
||||
msgstr "Логотип"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:53 rog-control-center/ui/types/aura_types.slint:63
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Keyboard"
|
||||
msgstr "Клавіатура"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:54 rog-control-center/ui/types/aura_types.slint:64
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Lightbar"
|
||||
msgstr "Світлова панель"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:55
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Lid"
|
||||
msgstr "Кришка"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:56
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Rear Glow"
|
||||
msgstr "Заднє світіння"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:57 rog-control-center/ui/types/aura_types.slint:65
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Keyboard and Lightbar"
|
||||
msgstr "Клавіатура та світлова панель"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:58
|
||||
msgctxt "Aura power zone"
|
||||
msgid "Ally"
|
||||
msgstr "Ally"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:68
|
||||
msgctxt "Aura brightness"
|
||||
msgid "Off"
|
||||
msgstr "Вимкнено"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:69
|
||||
msgctxt "Aura brightness"
|
||||
msgid "Low"
|
||||
msgstr "Низька"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:70
|
||||
msgctxt "Aura brightness"
|
||||
msgid "Med"
|
||||
msgstr "Середня"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:71
|
||||
msgctxt "Aura brightness"
|
||||
msgid "High"
|
||||
msgstr "Висока"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:76 rog-control-center/ui/types/aura_types.slint:91
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Static"
|
||||
msgstr "Статичний"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:77 rog-control-center/ui/types/aura_types.slint:92
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Breathe"
|
||||
msgstr "Дихання"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:78 rog-control-center/ui/types/aura_types.slint:93
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Strobe"
|
||||
msgstr "Стробоскоп"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:79
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Rainbow"
|
||||
msgstr "Веселка"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:80
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Star"
|
||||
msgstr "Зірка"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:81
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Rain"
|
||||
msgstr "Дощ"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:82
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Highlight"
|
||||
msgstr "Підсвічування"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:83
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Laser"
|
||||
msgstr "Лазер"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:84
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Ripple"
|
||||
msgstr "Хвиля"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:85
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Nothing"
|
||||
msgstr "Нічого"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:86
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Pulse"
|
||||
msgstr "Пульс"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:87
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Comet"
|
||||
msgstr "Комета"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:88
|
||||
msgctxt "Basic aura mode"
|
||||
msgid "Flash"
|
||||
msgstr "Спалах"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:100
|
||||
msgctxt "Aura zone"
|
||||
msgid "None"
|
||||
msgstr "Немає"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:101
|
||||
msgctxt "Aura zone"
|
||||
msgid "Key1"
|
||||
msgstr "Клавіша 1"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:102
|
||||
msgctxt "Aura zone"
|
||||
msgid "Key2"
|
||||
msgstr "Клавіша 2"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:103
|
||||
msgctxt "Aura zone"
|
||||
msgid "Key3"
|
||||
msgstr "Клавіша 3"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:104
|
||||
msgctxt "Aura zone"
|
||||
msgid "Key4"
|
||||
msgstr "Клавіша 4"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:105
|
||||
msgctxt "Aura zone"
|
||||
msgid "Logo"
|
||||
msgstr "Логотип"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:106
|
||||
msgctxt "Aura zone"
|
||||
msgid "Lightbar Left"
|
||||
msgstr "Світлова панель зліва"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:107
|
||||
msgctxt "Aura zone"
|
||||
msgid "Lightbar Right"
|
||||
msgstr "Світлова панель справа"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:111
|
||||
msgctxt "Aura direction"
|
||||
msgid "Right"
|
||||
msgstr "Вправо"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:112
|
||||
msgctxt "Aura direction"
|
||||
msgid "Left"
|
||||
msgstr "Вліво"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:113
|
||||
msgctxt "Aura direction"
|
||||
msgid "Up"
|
||||
msgstr "Вгору"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:114
|
||||
msgctxt "Aura direction"
|
||||
msgid "Down"
|
||||
msgstr "Вниз"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:118
|
||||
msgctxt "Aura speed"
|
||||
msgid "Low"
|
||||
msgstr "Низька"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:119
|
||||
msgctxt "Aura speed"
|
||||
msgid "Medium"
|
||||
msgstr "Середня"
|
||||
|
||||
#: rog-control-center/ui/types/aura_types.slint:120
|
||||
msgctxt "Aura speed"
|
||||
msgid "High"
|
||||
msgstr "Висока"
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import { Button, VerticalBox } from "std-widgets.slint";
|
||||
import { Palette, Button, VerticalBox } from "std-widgets.slint";
|
||||
import { AppSize } from "globals.slint";
|
||||
import { PageSystem, SystemPageData, AttrMinMax } from "pages/system.slint";
|
||||
import { SideBar } from "widgets/sidebar.slint";
|
||||
import { PageAbout } from "pages/about.slint";
|
||||
import { PageFans } from "pages/fans.slint";
|
||||
import { PageSlash, SlashPageData } from "pages/slash.slint";
|
||||
import { PageSupergfx, SupergfxPageData } from "pages/supergfx.slint";
|
||||
import { PageScreenpad, ScreenpadPageData } from "pages/screenpad.slint";
|
||||
import { PageAnime, AnimePageData } from "pages/anime.slint";
|
||||
import { RogItem } from "widgets/common.slint";
|
||||
import { PageAura } from "pages/aura.slint";
|
||||
import { PageGPU, GPUPageData } from "pages/gpu.slint";
|
||||
import { Node } from "widgets/graph.slint";
|
||||
export { Node }
|
||||
import { FanPageData, FanType, Profile } from "types/fan_types.slint";
|
||||
@@ -17,18 +15,8 @@ export { FanPageData, FanType, Profile }
|
||||
import { AuraPageData, AuraDevType, LaptopAuraPower, AuraPowerState, PowerZones, AuraEffect } from "types/aura_types.slint";
|
||||
export { AuraPageData, AuraDevType, LaptopAuraPower, AuraPowerState, PowerZones, AuraEffect }
|
||||
import { PageAppSettings, AppSettingsPageData } from "pages/app_settings.slint";
|
||||
import { StatusBar, SystemStatus } from "widgets/status_bar.slint";
|
||||
import { TrayTooltip } from "windows/tray_tooltip.slint";
|
||||
export { TrayTooltip }
|
||||
|
||||
import { RogPalette } from "themes/rog_theme.slint";
|
||||
|
||||
export { AppSize, AttrMinMax, SystemPageData, AnimePageData, AppSettingsPageData, SystemStatus, SlashPageData, SupergfxPageData, ScreenpadPageData }
|
||||
|
||||
export global SomeError {
|
||||
in property <string> error_message: "";
|
||||
in property <string> error_help: "";
|
||||
}
|
||||
export { AppSize, AttrMinMax, SystemPageData, AnimePageData, AppSettingsPageData, GPUPageData }
|
||||
|
||||
export component MainWindow inherits Window {
|
||||
title: "ROG Control";
|
||||
@@ -37,133 +25,146 @@ export component MainWindow inherits Window {
|
||||
default-font-size: 14px;
|
||||
default-font-weight: 400;
|
||||
icon: @image-url("../data/rog-control-center.png");
|
||||
in property <[bool]> sidebar_items_avilable: [true, true, true, true, true, true, true, true, true];
|
||||
in property <[bool]> sidebar_items_avilable: [
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
true, // GPU Configuration
|
||||
true, // App Settings
|
||||
true, // About
|
||||
];
|
||||
private property <bool> show_notif;
|
||||
// TODO: change if TUF on the logo in the menu on the main page
|
||||
in property <bool> is_tuf: false;
|
||||
private property <bool> fade_cover;
|
||||
private property <bool> toast: false;
|
||||
private property <string> toast_text: "I show when something is waiting";
|
||||
|
||||
callback show_toast(string);
|
||||
callback start_toast_timer();
|
||||
callback hide_toast();
|
||||
|
||||
hide_toast() => {
|
||||
toast = false;
|
||||
}
|
||||
|
||||
show_toast(text) => {
|
||||
toast = text != "";
|
||||
toast_text = text;
|
||||
if (toast) {
|
||||
start_toast_timer();
|
||||
}
|
||||
callback clear_toast_if_matches(string);
|
||||
clear_toast_if_matches(text) => {
|
||||
if (toast && toast_text == text) {
|
||||
toast = false;
|
||||
toast_text = "";
|
||||
}
|
||||
}
|
||||
|
||||
callback exit-app();
|
||||
callback show_notification(bool);
|
||||
|
||||
show_notification(yes) => {
|
||||
show_notif = yes;
|
||||
fade_cover = yes;
|
||||
}
|
||||
|
||||
callback external_colour_change();
|
||||
external_colour_change() => {
|
||||
aura.external_colour_change();
|
||||
aura.external_colour_change();
|
||||
}
|
||||
|
||||
min-height: AppSize.height;
|
||||
min-width: AppSize.width;
|
||||
background: RogPalette.background;
|
||||
background: Palette.alternate-background;
|
||||
|
||||
VerticalLayout {
|
||||
HorizontalLayout {
|
||||
HorizontalLayout {
|
||||
padding: 0px;
|
||||
VerticalLayout {
|
||||
padding: 0px;
|
||||
|
||||
// Left Column: Sidebar + Quit Button
|
||||
VerticalLayout {
|
||||
side-bar := SideBar {
|
||||
title: @tr("ROG");
|
||||
model: [
|
||||
@tr("Menu1" => "System Control"),
|
||||
@tr("Menu2" => "Keyboard Aura"),
|
||||
@tr("Menu3" => "AniMe Matrix"),
|
||||
@tr("Menu7" => "Slash Lighting"),
|
||||
@tr("Menu8" => "Graphics Control"),
|
||||
@tr("Menu9" => "Screenpad Control"),
|
||||
@tr("Menu4" => "Fan Curves"),
|
||||
@tr("Menu5" => "App Settings"),
|
||||
@tr("Menu6" => "About"),
|
||||
];
|
||||
available: root.sidebar_items_avilable;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
max-height: 40px;
|
||||
width: side-bar.width;
|
||||
background: RogPalette.control-background;
|
||||
Text {
|
||||
vertical-alignment: center;
|
||||
horizontal-alignment: center;
|
||||
text: @tr("Quit App");
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
TouchArea {
|
||||
clicked => {
|
||||
root.exit-app();
|
||||
}
|
||||
}
|
||||
}
|
||||
side-bar := SideBar {
|
||||
model: [
|
||||
@tr("Menu1" => "System Control"),
|
||||
@tr("Menu2" => "Keyboard Aura"),
|
||||
@tr("Menu3" => "AniMe Matrix"),
|
||||
@tr("Menu4" => "Fan Curves"),
|
||||
@tr("Menu5" => "GPU Configuration"),
|
||||
@tr("Menu6" => "App Settings"),
|
||||
@tr("Menu7" => "About"),
|
||||
];
|
||||
available: root.sidebar_items_avilable;
|
||||
is_tuf: root.is_tuf;
|
||||
}
|
||||
|
||||
// Right Column: Content Pages
|
||||
Rectangle {
|
||||
background: RogPalette.background;
|
||||
if(side-bar.current-item == 0): page := PageSystem {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
}
|
||||
|
||||
aura := PageAura {
|
||||
width: root.width - side-bar.width;
|
||||
visible: side-bar.current-item == 1;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 2): PageAnime {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 3): PageSlash {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 4): PageSupergfx {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 5): PageScreenpad {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
fans := PageFans {
|
||||
width: root.width - side-bar.width;
|
||||
visible: side-bar.current-item == 6;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 7): PageAppSettings {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 8): PageAbout {
|
||||
width: root.width - side-bar.width;
|
||||
Button {
|
||||
height: 40px;
|
||||
width: side-bar.width;
|
||||
text: @tr("Quit App");
|
||||
clicked() => {
|
||||
root.exit-app();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Palette.background;
|
||||
if(side-bar.current-item == 0): page := PageSystem {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
}
|
||||
|
||||
/*if(side-bar.current-item == 1):*/ aura := PageAura {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 1;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 2): PageAnime {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 2;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 3): fans := PageFans {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 3;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 4): PageGPU {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 4;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 5): PageAppSettings {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 5;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 6): PageAbout {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
visible: side-bar.current-item == 6;
|
||||
}
|
||||
|
||||
if toast: Rectangle {
|
||||
x: 0px;
|
||||
y: root.height - self.height;
|
||||
width: root.width - side-bar.width;
|
||||
height: 40px;
|
||||
opacity: 1.0;
|
||||
background: Palette.selection-background;
|
||||
clip: true;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
clicked => {
|
||||
toast = false;
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: Palette.control-background;
|
||||
Text {
|
||||
color: Palette.control-foreground;
|
||||
text: root.toast_text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bottom: Status Bar
|
||||
StatusBar {}
|
||||
}
|
||||
|
||||
if fade_cover: Rectangle {
|
||||
@@ -171,7 +172,7 @@ export component MainWindow inherits Window {
|
||||
y: 0px;
|
||||
width: root.width;
|
||||
height: root.height;
|
||||
background: Colors.rgba(0,0,0,0.7);
|
||||
background: Colors.rgba(25,33,23,20);
|
||||
opacity: 0.7;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
@@ -186,52 +187,6 @@ export component MainWindow inherits Window {
|
||||
}
|
||||
}
|
||||
|
||||
// Modern floating toast/snackbar notification
|
||||
// Shows at the bottom center, non-intrusive
|
||||
Rectangle {
|
||||
visible: self.opacity > 0;
|
||||
opacity: root.toast ? 1 : 0;
|
||||
animate opacity { duration: 300ms; }
|
||||
|
||||
x: (root.width - 400px) / 2; // Center horizontally
|
||||
y: root.height - 80px; // Bottom padding
|
||||
width: 400px;
|
||||
height: 48px;
|
||||
border-radius: RogPalette.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.accent;
|
||||
background: RogPalette.control-background;
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: Colors.black;
|
||||
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
clicked => {
|
||||
toast = false;
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
alignment: space-between;
|
||||
|
||||
Text {
|
||||
vertical-alignment: center;
|
||||
color: RogPalette.text-primary;
|
||||
text: root.toast_text;
|
||||
overflow: elide;
|
||||
}
|
||||
|
||||
Text {
|
||||
vertical-alignment: center;
|
||||
text: "Dismiss";
|
||||
color: RogPalette.text-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: or use Dialogue
|
||||
if show_notif: Rectangle {
|
||||
@@ -248,20 +203,13 @@ export component MainWindow inherits Window {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add properties to display
|
||||
Rectangle {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
|
||||
VerticalLayout {
|
||||
alignment: center;
|
||||
Text {
|
||||
horizontal-alignment: center;
|
||||
text: "Click here to exit";
|
||||
color: RogPalette.text-primary;
|
||||
font-size: 16px;
|
||||
}
|
||||
background: Palette.background;
|
||||
Text {
|
||||
text: "Click here to exit";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,45 +219,31 @@ export component MainWindow inherits Window {
|
||||
y: 0px;
|
||||
width: root.width;
|
||||
height: root.height;
|
||||
|
||||
background: RogPalette.background;
|
||||
border-color: RogPalette.accent;
|
||||
border-width: 2px;
|
||||
border-radius: 8px;
|
||||
background: Palette.background;
|
||||
border-color: Palette.border;
|
||||
border-width: 3px;
|
||||
border-radius: 10px;
|
||||
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 15px;
|
||||
alignment: center;
|
||||
|
||||
Text {
|
||||
text: "Error";
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: RogPalette.accent;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
min-height: 60px;
|
||||
|
||||
RogItem {
|
||||
min-height: 50px;
|
||||
max-height: 100px;
|
||||
Text {
|
||||
text <=> SomeError.error_message;
|
||||
font-size: 16px;
|
||||
color: RogPalette.text-primary;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text <=> SomeError.error_help;
|
||||
color: RogPalette.text-secondary;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export global SomeError {
|
||||
in property <string> error_message: "";
|
||||
in property <string> error_help: "";
|
||||
}
|
||||
|
||||
@@ -1,126 +1,75 @@
|
||||
import { VerticalBox, HorizontalBox, ScrollView } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export component PageAbout inherits Rectangle {
|
||||
background: RogPalette.background;
|
||||
import {
|
||||
AboutSlint,
|
||||
VerticalBox,
|
||||
HorizontalBox,
|
||||
ScrollView,
|
||||
} from "std-widgets.slint";
|
||||
|
||||
export component PageAbout inherits VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
ScrollView {
|
||||
VerticalBox {
|
||||
padding: 30px;
|
||||
spacing: 20px;
|
||||
alignment: center;
|
||||
|
||||
// Title
|
||||
Text {
|
||||
horizontal-alignment: center;
|
||||
text: "ROG Control Center";
|
||||
font-size: 28px;
|
||||
font-weight: 800;
|
||||
color: RogPalette.accent;
|
||||
}
|
||||
HorizontalBox {
|
||||
alignment: LayoutAlignment.center;
|
||||
VerticalBox {
|
||||
alignment: LayoutAlignment.center;
|
||||
|
||||
Text {
|
||||
horizontal-alignment: center;
|
||||
text: "A modern UI for asusctl built with Slint";
|
||||
font-size: 16px;
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
|
||||
// Version info
|
||||
Rectangle {
|
||||
height: 60px;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
|
||||
HorizontalBox {
|
||||
padding: 15px;
|
||||
alignment: center;
|
||||
Text {
|
||||
text: "Version 6.3.0";
|
||||
font-size: 14px;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
Text {
|
||||
text: " | ";
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
Text {
|
||||
text: "Requires kernel 6.10+";
|
||||
font-size: 14px;
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
Text {
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text: "ROG Control Center";
|
||||
font-size: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
// Features section
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 12px;
|
||||
|
||||
Text {
|
||||
text: "Features";
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: RogPalette.accent;
|
||||
}
|
||||
|
||||
// Completed features
|
||||
Text { text: "[x] ROG-themed dark UI"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] System status bar (CPU/GPU temps & fan speeds)"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Power profile management"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Aura RGB keyboard lighting"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] AniMe Matrix display"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Slash LED control"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Supergfx graphics switching"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Screenpad brightness & gamma"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Custom fan curves"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] Desktop notifications (KDE OSD)"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
Text { text: "[x] System tray integration"; color: RogPalette.text-primary; font-size: 13px; }
|
||||
|
||||
// Pending features
|
||||
Rectangle { height: 10px; }
|
||||
Text { text: "Planned:"; font-size: 14px; font-weight: 600; color: RogPalette.text-secondary; }
|
||||
Text { text: "[ ] ROG Ally specific settings"; color: RogPalette.text-secondary; font-size: 13px; }
|
||||
Text { text: "[ ] Advanced Aura zone editing"; color: RogPalette.text-secondary; font-size: 13px; }
|
||||
Text {
|
||||
wrap: TextWrap.word-wrap;
|
||||
text: "\nA powerful graphical interface for managing ASUS ROG, TUF, and ProArt laptops on Linux. It acts as the official GUI for the asusctl toolset, allowing for seamless hardware tuning without the command line.";
|
||||
}
|
||||
}
|
||||
|
||||
// Credits
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
Text {
|
||||
font-weight: 900;
|
||||
text: "Key Features:";
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 8px;
|
||||
Text {
|
||||
text: " • Performance: Switch power profiles and customize fan curves.\n • Aura Sync: Control keyboard backlighting and LED effects.\n • Battery Health: Set charge limits to extend battery longevity.\n • Display: Toggle Panel Overdrive and refresh rates.\n • AniMe Matrix: Control AniMe Matrix displays.";
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "Credits";
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: RogPalette.accent;
|
||||
}
|
||||
Text {
|
||||
font-weight: 900;
|
||||
text: "Requirements:";
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "asusctl & asusd by Luke Jones";
|
||||
font-size: 13px;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
Text {
|
||||
text: "UI built with Slint";
|
||||
font-size: 13px;
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
Text {
|
||||
text: " • This software requires kernel version 6.19.";
|
||||
}
|
||||
|
||||
Text {
|
||||
font-weight: 900;
|
||||
text: "Work in progress:";
|
||||
}
|
||||
|
||||
Text {
|
||||
text: " • Theme the widgets\n • Add a cpu/gpu temp/fan speed info bar\n • Include fan speeds, temps in a bottom bar\n • Slash control\n • Screenpad controls\n • ROG Ally specific settings";
|
||||
}
|
||||
|
||||
Text {
|
||||
font-weight: 900;
|
||||
text: "License:";
|
||||
}
|
||||
|
||||
Text {
|
||||
text: " This project is open-source software licensed under the Mozilla Public License 2.0 (MPL-2.0).";
|
||||
}
|
||||
|
||||
Text {
|
||||
font-weight: 900;
|
||||
text: "Links:";
|
||||
}
|
||||
|
||||
Text {
|
||||
text: " Source Code: https://gitlab.com/asus-linux/asusctl\n Website: https://asus-linux.org/";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { SystemDropdown, SystemToggle } from "../widgets/common.slint";
|
||||
import { Palette, GroupBox, VerticalBox, Button, HorizontalBox } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export global AnimePageData {
|
||||
in-out property <[string]> brightness_names: [
|
||||
@@ -37,12 +36,8 @@ export component PageAnime inherits Rectangle {
|
||||
property <bool> show_display_advanced: false;
|
||||
property <bool> show_builtin_advanced: false;
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
//padding only has effect on layout elements
|
||||
//padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
VerticalLayout {
|
||||
|
||||
VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
HorizontalLayout {
|
||||
@@ -110,7 +105,7 @@ export component PageAnime inherits Rectangle {
|
||||
if root.show_fade_cover: Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: RogPalette.background;
|
||||
background: Palette.background;
|
||||
opacity: 0.8;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
@@ -133,8 +128,9 @@ export component PageAnime inherits Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
background: Palette.background;
|
||||
VerticalLayout {
|
||||
padding: 50px;
|
||||
padding: 4px;
|
||||
spacing: 10px;
|
||||
GroupBox {
|
||||
height: 10px;
|
||||
@@ -142,8 +138,8 @@ export component PageAnime inherits Rectangle {
|
||||
spacing: 10px;
|
||||
alignment: LayoutAlignment.start;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.text-primary;
|
||||
font-size: 16px;
|
||||
color: Palette.control-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text: @tr("Set which builtin animations are played");
|
||||
}
|
||||
@@ -194,8 +190,8 @@ export component PageAnime inherits Rectangle {
|
||||
Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "X";
|
||||
height: 40px;
|
||||
text: "✕";
|
||||
height: 36px;
|
||||
clicked => {
|
||||
root.show_builtin_advanced = false;
|
||||
root.show_fade_cover = false;
|
||||
@@ -207,8 +203,9 @@ export component PageAnime inherits Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
background: Palette.background;
|
||||
VerticalLayout {
|
||||
padding: 50px;
|
||||
padding: 4px;
|
||||
spacing: 10px;
|
||||
GroupBox {
|
||||
height: 100px;
|
||||
@@ -216,8 +213,8 @@ export component PageAnime inherits Rectangle {
|
||||
spacing: 10px;
|
||||
alignment: LayoutAlignment.start;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.text-primary;
|
||||
font-size: 16px;
|
||||
color: Palette.control-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text: @tr("Advanced Display Settings");
|
||||
}
|
||||
@@ -255,8 +252,8 @@ export component PageAnime inherits Rectangle {
|
||||
Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "X";
|
||||
height: 40px;
|
||||
text: "✕";
|
||||
height: 36px;
|
||||
clicked => {
|
||||
root.show_display_advanced = false;
|
||||
root.show_fade_cover = false;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { VerticalBox, ScrollView, HorizontalBox, Button } from "std-widgets.slint";
|
||||
import { SystemToggle, RogItem } from "../widgets/common.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { Palette } from "std-widgets.slint";
|
||||
import { SystemToggle } from "../widgets/common.slint";
|
||||
|
||||
export global AppSettingsPageData {
|
||||
in-out property <bool> run_in_background;
|
||||
@@ -9,135 +8,53 @@ export global AppSettingsPageData {
|
||||
callback set_startup_in_background(bool);
|
||||
in-out property <bool> enable_tray_icon;
|
||||
callback set_enable_tray_icon(bool);
|
||||
|
||||
// Master notification toggle
|
||||
in-out property <bool> notifications_enabled;
|
||||
callback set_notifications_enabled(bool);
|
||||
|
||||
// Granular notification toggles
|
||||
in-out property <bool> notify_gfx_switch;
|
||||
callback set_notify_gfx_switch(bool);
|
||||
in-out property <bool> notify_gfx_status;
|
||||
callback set_notify_gfx_status(bool);
|
||||
in-out property <bool> notify_platform_profile;
|
||||
callback set_notify_platform_profile(bool);
|
||||
in-out property <bool> enable_dgpu_notifications;
|
||||
callback set_enable_dgpu_notifications(bool);
|
||||
}
|
||||
|
||||
export component PageAppSettings inherits Rectangle {
|
||||
background: RogPalette.background;
|
||||
|
||||
ScrollView {
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 20px;
|
||||
alignment: start;
|
||||
export component PageAppSettings inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
|
||||
// General Section
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
padding: 0px;
|
||||
|
||||
Rectangle {
|
||||
height: 30px;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 4px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
|
||||
Text {
|
||||
x: 10px;
|
||||
vertical-alignment: center;
|
||||
text: "General Settings";
|
||||
color: RogPalette.accent;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Run in background after closing");
|
||||
checked <=> AppSettingsPageData.run_in_background;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_run_in_background(AppSettingsPageData.run_in_background)
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Start app in background (UI closed)");
|
||||
checked <=> AppSettingsPageData.startup_in_background;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_startup_in_background(AppSettingsPageData.startup_in_background)
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Enable system tray icon");
|
||||
checked <=> AppSettingsPageData.enable_tray_icon;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_enable_tray_icon(AppSettingsPageData.enable_tray_icon)
|
||||
}
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
SystemToggle {
|
||||
text: @tr("Run in background after closing");
|
||||
checked <=> AppSettingsPageData.run_in_background;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_run_in_background(AppSettingsPageData.run_in_background)
|
||||
}
|
||||
}
|
||||
|
||||
// Notifications Section
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
padding: 0px;
|
||||
SystemToggle {
|
||||
text: @tr("Start app in background (UI closed)");
|
||||
checked <=> AppSettingsPageData.startup_in_background;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_startup_in_background(AppSettingsPageData.startup_in_background)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 30px;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 4px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
SystemToggle {
|
||||
text: @tr("Enable system tray icon");
|
||||
checked <=> AppSettingsPageData.enable_tray_icon;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_enable_tray_icon(AppSettingsPageData.enable_tray_icon)
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
x: 10px;
|
||||
vertical-alignment: center;
|
||||
text: "Notifications";
|
||||
color: RogPalette.accent;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Enable Notifications");
|
||||
checked <=> AppSettingsPageData.notifications_enabled;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_notifications_enabled(AppSettingsPageData.notifications_enabled)
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-toggles container
|
||||
VerticalBox {
|
||||
padding-left: 30px; // Indent
|
||||
spacing: 10px;
|
||||
visible: AppSettingsPageData.notifications_enabled;
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Notify on Graphics Switch");
|
||||
checked <=> AppSettingsPageData.notify_gfx_switch;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_notify_gfx_switch(AppSettingsPageData.notify_gfx_switch)
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Notify on GPU Status Change");
|
||||
checked <=> AppSettingsPageData.notify_gfx_status;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_notify_gfx_status(AppSettingsPageData.notify_gfx_status)
|
||||
}
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
text: @tr("Notify on Power Profile Change");
|
||||
checked <=> AppSettingsPageData.notify_platform_profile;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_notify_platform_profile(AppSettingsPageData.notify_platform_profile)
|
||||
}
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Enable dGPU notifications");
|
||||
checked <=> AppSettingsPageData.enable_dgpu_notifications;
|
||||
toggled => {
|
||||
AppSettingsPageData.set_enable_dgpu_notifications(AppSettingsPageData.enable_dgpu_notifications)
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Palette.accent-background;
|
||||
text: " WIP: some features like notifications are not complete";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { SystemDropdown, RogItem, SystemToggle, SystemToggleVert } from "../widgets/common.slint";
|
||||
import { Button, ComboBox, VerticalBox, GroupBox } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { Palette, Button, ComboBox, VerticalBox, GroupBox } from "std-widgets.slint";
|
||||
import { StyleMetrics, Slider, HorizontalBox, TextEdit, SpinBox, LineEdit, ScrollView } from "std-widgets.slint";
|
||||
import { ColourSlider } from "../widgets/colour_picker.slint";
|
||||
import { AuraPageData, AuraDevType, PowerZones, LaptopAuraPower, AuraEffect } from "../types/aura_types.slint";
|
||||
@@ -18,6 +17,7 @@ export component PageAura inherits Rectangle {
|
||||
c2.final_colour = AuraPageData.led_mode_data.colour2;
|
||||
c2.external_colour_change();
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
padding: 10px;
|
||||
@@ -42,10 +42,14 @@ export component PageAura inherits Rectangle {
|
||||
current_value: AuraPageData.available_mode_names[self.current-index];
|
||||
model <=> AuraPageData.available_mode_names;
|
||||
selected => {
|
||||
AuraPageData.led_mode_data.mode = AuraPageData.led_mode;
|
||||
AuraPageData.led_mode_data.mode = AuraPageData.current_available_mode;
|
||||
self.current_value = AuraPageData.available_mode_names[self.current-index];
|
||||
AuraPageData.cb_led_mode(AuraPageData.current_available_mode);
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.supported_basic_modes[self.current-index],
|
||||
zone: AuraPageData.led_mode_data.zone,
|
||||
colour1: AuraPageData.led_mode_data.colour1,
|
||||
colour2: AuraPageData.led_mode_data.colour2,
|
||||
speed: AuraPageData.led_mode_data.speed,
|
||||
direction: AuraPageData.led_mode_data.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,6 +58,7 @@ export component PageAura inherits Rectangle {
|
||||
min-height: 220px;
|
||||
max-height: 400px;
|
||||
HorizontalLayout {
|
||||
padding-top: 5px;
|
||||
spacing: 10px;
|
||||
VerticalBox {
|
||||
Text {
|
||||
@@ -61,47 +66,44 @@ export component PageAura inherits Rectangle {
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
c1 := ColourSlider {
|
||||
enabled: AuraPageData.led_mode == 0 || AuraPageData.led_mode == 1 || AuraPageData.led_mode == 4 || AuraPageData.led_mode == 6 || AuraPageData.led_mode == 7 || AuraPageData.led_mode == 8 || AuraPageData.led_mode == 10 || AuraPageData.led_mode == 11 || AuraPageData.led_mode == 12;
|
||||
enabled: AuraPageData.colour1_enabled;
|
||||
final_colour <=> AuraPageData.color1;
|
||||
colourbox <=> AuraPageData.colorbox1;
|
||||
set_hex_from_colour(c1) => {
|
||||
return AuraPageData.cb_hex_from_colour(c1);
|
||||
}
|
||||
hex_to_colour(s) => {
|
||||
return AuraPageData.cb_hex_to_colour(s);
|
||||
}
|
||||
set_hex_from_colour(c) => { return AuraPageData.cb_hex_from_colour(c); }
|
||||
hex_to_colour(s) => { return AuraPageData.cb_hex_to_colour(s); }
|
||||
released => {
|
||||
AuraPageData.led_mode_data.colour1 = AuraPageData.color1;
|
||||
AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data);
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.led_mode_data.mode,
|
||||
zone: AuraPageData.led_mode_data.zone,
|
||||
colour1: AuraPageData.color1,
|
||||
colour2: AuraPageData.led_mode_data.colour2,
|
||||
speed: AuraPageData.led_mode_data.speed,
|
||||
direction: AuraPageData.led_mode_data.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("Colour 2");
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
Text { text: @tr("Colour 2"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; }
|
||||
HorizontalBox {
|
||||
c2 := ColourSlider {
|
||||
enabled: AuraPageData.led_mode == 1 || AuraPageData.led_mode == 4;
|
||||
enabled: AuraPageData.colour2_enabled;
|
||||
final_colour <=> AuraPageData.color2;
|
||||
colourbox <=> AuraPageData.colorbox2;
|
||||
set_hex_from_colour(c1) => {
|
||||
return AuraPageData.cb_hex_from_colour(c1);
|
||||
}
|
||||
hex_to_colour(s) => {
|
||||
return AuraPageData.cb_hex_to_colour(s);
|
||||
}
|
||||
set_hex_from_colour(c) => { return AuraPageData.cb_hex_from_colour(c); }
|
||||
hex_to_colour(s) => { return AuraPageData.cb_hex_to_colour(s); }
|
||||
released => {
|
||||
AuraPageData.led_mode_data.colour2 = AuraPageData.color2;
|
||||
AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data);
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.led_mode_data.mode,
|
||||
zone: AuraPageData.led_mode_data.zone,
|
||||
colour1: AuraPageData.led_mode_data.colour1,
|
||||
colour2: AuraPageData.color2,
|
||||
speed: AuraPageData.led_mode_data.speed,
|
||||
direction: AuraPageData.led_mode_data.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,121 +116,64 @@ export component PageAura inherits Rectangle {
|
||||
min-height: 80px;
|
||||
max-height: 90px;
|
||||
RogItem {
|
||||
//padding only has effect on layout elements
|
||||
//padding: 0px;
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("Zone");
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
Text { text: @tr("Zone"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; }
|
||||
ComboBox {
|
||||
// enabled: AuraPageData.led_mode == ;
|
||||
enabled: false;
|
||||
enabled: false;
|
||||
current_index <=> AuraPageData.zone;
|
||||
current_value: AuraPageData.zone_names[self.current-index];
|
||||
model <=> AuraPageData.zone_names;
|
||||
selected => {
|
||||
AuraPageData.led_mode_data.zone = self.current-index;
|
||||
AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data);
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.led_mode_data.mode,
|
||||
zone: self.current-index,
|
||||
colour1: AuraPageData.led_mode_data.colour1,
|
||||
colour2: AuraPageData.led_mode_data.colour2,
|
||||
speed: AuraPageData.led_mode_data.speed,
|
||||
direction: AuraPageData.led_mode_data.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RogItem {
|
||||
//padding only has effect on layout elements
|
||||
//padding: 0px;
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("Direction");
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
Text { text: @tr("Direction"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; }
|
||||
ComboBox {
|
||||
enabled: AuraPageData.led_mode == 3;
|
||||
enabled: AuraPageData.direction_enabled;
|
||||
current_index <=> AuraPageData.direction;
|
||||
current_value: AuraPageData.direction_names[self.current-index];
|
||||
model <=> AuraPageData.direction_names;
|
||||
selected => {
|
||||
AuraPageData.led_mode_data.direction = self.current-index;
|
||||
AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data);
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.led_mode_data.mode,
|
||||
zone: AuraPageData.led_mode_data.zone,
|
||||
colour1: AuraPageData.led_mode_data.colour1,
|
||||
colour2: AuraPageData.led_mode_data.colour2,
|
||||
speed: AuraPageData.led_mode_data.speed,
|
||||
direction: self.current-index,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RogItem {
|
||||
//padding only has effect on layout elements
|
||||
//padding: 0px;
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("Speed");
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
Text { text: @tr("Speed"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; }
|
||||
ComboBox {
|
||||
enabled: AuraPageData.led_mode == 1 || AuraPageData.led_mode == 2 || AuraPageData.led_mode == 3 || AuraPageData.led_mode == 4 || AuraPageData.led_mode == 5 || AuraPageData.led_mode == 6 || AuraPageData.led_mode == 7 || AuraPageData.led_mode == 8;
|
||||
enabled: AuraPageData.speed_enabled;
|
||||
current_index <=> AuraPageData.speed;
|
||||
current_value: AuraPageData.speed_names[self.current-index];
|
||||
model <=> AuraPageData.speed_names;
|
||||
selected => {
|
||||
AuraPageData.led_mode_data.speed = self.current-index;
|
||||
AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Software Animation Controls (for Static-only keyboards)
|
||||
if AuraPageData.soft_animation_available: RogItem {
|
||||
min-height: 100px;
|
||||
VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 8px;
|
||||
|
||||
Text {
|
||||
text: @tr("Software Animation (Static-only keyboards)");
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: RogPalette.accent;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 20px;
|
||||
|
||||
VerticalLayout {
|
||||
Text {
|
||||
text: @tr("Animation Mode");
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
ComboBox {
|
||||
current_index <=> AuraPageData.soft_animation_mode;
|
||||
current_value: AuraPageData.soft_animation_modes[self.current-index];
|
||||
model <=> AuraPageData.soft_animation_modes;
|
||||
selected => {
|
||||
AuraPageData.cb_soft_animation_mode(AuraPageData.soft_animation_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
horizontal-stretch: 1;
|
||||
Text {
|
||||
text: @tr("Speed: ") + Math.round(AuraPageData.soft_animation_speed) + "ms";
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
Slider {
|
||||
minimum: 150;
|
||||
maximum: 1000;
|
||||
value <=> AuraPageData.soft_animation_speed;
|
||||
released => {
|
||||
AuraPageData.cb_soft_animation_speed(Math.round(AuraPageData.soft_animation_speed));
|
||||
}
|
||||
AuraPageData.apply_effect({
|
||||
mode: AuraPageData.led_mode_data.mode,
|
||||
zone: AuraPageData.led_mode_data.zone,
|
||||
colour1: AuraPageData.led_mode_data.colour1,
|
||||
colour2: AuraPageData.led_mode_data.colour2,
|
||||
speed: self.current-index,
|
||||
direction: AuraPageData.led_mode_data.direction,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,20 +192,17 @@ export component PageAura inherits Rectangle {
|
||||
}
|
||||
|
||||
if root.show_fade_cover: Rectangle {
|
||||
background: RogPalette.background;
|
||||
background: Palette.background;
|
||||
opacity: 0.8;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
clicked => {
|
||||
root.show_fade_cover = false;
|
||||
root.show_aura_power = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if root.show_aura_power && AuraPageData.device_type == AuraDevType.New: Rectangle {
|
||||
background: Palette.background;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
@@ -296,21 +238,54 @@ export component PageAura inherits Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "X";
|
||||
height: 40px;
|
||||
clicked => {
|
||||
root.show_aura_power = false;
|
||||
root.show_fade_cover = false;
|
||||
// TUF devices: show the same configurable power groups as `New`, since
|
||||
// `setup_aura` fills `AuraPageData.supported_power_zones` and `led_power`
|
||||
// appropriately for TUF devices. This ensures the Power Settings panel
|
||||
// reflects what the firmware reports for TUF models.
|
||||
if root.show_aura_power && AuraPageData.device_type == AuraDevType.Tuf: Rectangle {
|
||||
background: Palette.background;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
padding: 30px;
|
||||
padding-top: 10px;
|
||||
spacing: 10px;
|
||||
alignment: LayoutAlignment.start;
|
||||
|
||||
for state[idx] in AuraPageData.led_power.states: tuf_zone := AuraPowerGroup {
|
||||
group-title: AuraPageData.power_zone_names[state.zone_name_idx];
|
||||
boot_checked: state.boot;
|
||||
boot_toggled => {
|
||||
AuraPageData.led_power.states[idx].boot = tuf_zone.boot_checked;
|
||||
AuraPageData.cb_led_power(AuraPageData.led_power);
|
||||
}
|
||||
awake_checked: state.awake;
|
||||
awake_toggled => {
|
||||
AuraPageData.led_power.states[idx].awake = tuf_zone.awake_checked;
|
||||
AuraPageData.cb_led_power(AuraPageData.led_power);
|
||||
}
|
||||
sleep_checked: state.sleep;
|
||||
sleep_toggled => {
|
||||
AuraPageData.led_power.states[idx].sleep = tuf_zone.sleep_checked;
|
||||
AuraPageData.cb_led_power(AuraPageData.led_power);
|
||||
}
|
||||
shutdown_checked: state.shutdown;
|
||||
shutdown_toggled => {
|
||||
AuraPageData.led_power.states[idx].shutdown = tuf_zone.shutdown_checked;
|
||||
AuraPageData.cb_led_power(AuraPageData.led_power);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if root.show_aura_power && AuraPageData.device_type == AuraDevType.Old: Rectangle {
|
||||
background: Palette.background;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
@@ -322,10 +297,7 @@ export component PageAura inherits Rectangle {
|
||||
alignment: LayoutAlignment.start;
|
||||
|
||||
Text {
|
||||
text: "LED Power Zones (Legacy)";
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #ff0033;
|
||||
text: "TODO: In progress";
|
||||
}
|
||||
|
||||
for state[idx] in AuraPageData.led_power.states: old_zone := AuraPowerGroupOld {
|
||||
@@ -352,17 +324,17 @@ export component PageAura inherits Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "X";
|
||||
height: 40px;
|
||||
clicked => {
|
||||
root.show_aura_power = false;
|
||||
root.show_fade_cover = false;
|
||||
}
|
||||
}
|
||||
if root.show_aura_power: Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "✕";
|
||||
height: 36px;
|
||||
clicked => {
|
||||
root.show_aura_power = false;
|
||||
root.show_fade_cover = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import { Palette, TabWidget, Button, CheckBox, Slider } from "std-widgets.slint";
|
||||
import { Palette, TabWidget, Button, CheckBox } from "std-widgets.slint";
|
||||
import { Graph, Node } from "../widgets/graph.slint";
|
||||
import { SystemToggle } from "../widgets/common.slint";
|
||||
import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
|
||||
|
||||
component FanTab inherits Rectangle {
|
||||
in-out property <bool> enabled: false;
|
||||
@@ -19,104 +16,40 @@ component FanTab inherits Rectangle {
|
||||
in-out property <[Node]> nodes;
|
||||
|
||||
VerticalLayout {
|
||||
private property <bool> local_busy:
|
||||
(root.fan_type == FanType.CPU && FanPageData.is_busy_cpu) ||
|
||||
(root.fan_type == FanType.GPU && FanPageData.is_busy_gpu) ||
|
||||
(root.fan_type == FanType.Middle && FanPageData.is_busy_mid);
|
||||
|
||||
if FanPageData.show_custom_warning: Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 4px;
|
||||
height: 48px;
|
||||
HorizontalLayout {
|
||||
padding: 10px;
|
||||
Text {
|
||||
color: #ffd700; // Gold/Yellow
|
||||
text: @tr("Zero RPM Mode Enabled: Fans will take ~25s to spin down entirely.");
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
wrap: word-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
padding: 5px;
|
||||
HorizontalLayout {
|
||||
spacing: 10px;
|
||||
if root.tab_enabled: Graph {
|
||||
nodes <=> root.nodes;
|
||||
}
|
||||
if root.tab_enabled: VerticalLayout {
|
||||
width: 40px;
|
||||
alignment: center;
|
||||
spacing: 10px;
|
||||
|
||||
Button {
|
||||
text: "+";
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
clicked => {
|
||||
root.nodes = [
|
||||
{ x: root.nodes[0].x, y: min(255px, root.nodes[0].y + 13px) },
|
||||
{ x: root.nodes[1].x, y: min(255px, root.nodes[1].y + 13px) },
|
||||
{ x: root.nodes[2].x, y: min(255px, root.nodes[2].y + 13px) },
|
||||
{ x: root.nodes[3].x, y: min(255px, root.nodes[3].y + 13px) },
|
||||
{ x: root.nodes[4].x, y: min(255px, root.nodes[4].y + 13px) },
|
||||
{ x: root.nodes[5].x, y: min(255px, root.nodes[5].y + 13px) },
|
||||
{ x: root.nodes[6].x, y: min(255px, root.nodes[6].y + 13px) },
|
||||
{ x: root.nodes[7].x, y: min(255px, root.nodes[7].y + 13px) }
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: "All";
|
||||
font-size: 10px;
|
||||
horizontal-alignment: center;
|
||||
color: white;
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "-";
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
clicked => {
|
||||
root.nodes = [
|
||||
{ x: root.nodes[0].x, y: max(0px, root.nodes[0].y - 13px) },
|
||||
{ x: root.nodes[1].x, y: max(0px, root.nodes[1].y - 13px) },
|
||||
{ x: root.nodes[2].x, y: max(0px, root.nodes[2].y - 13px) },
|
||||
{ x: root.nodes[3].x, y: max(0px, root.nodes[3].y - 13px) },
|
||||
{ x: root.nodes[4].x, y: max(0px, root.nodes[4].y - 13px) },
|
||||
{ x: root.nodes[5].x, y: max(0px, root.nodes[5].y - 13px) },
|
||||
{ x: root.nodes[6].x, y: max(0px, root.nodes[6].y - 13px) },
|
||||
{ x: root.nodes[7].x, y: max(0px, root.nodes[7].y - 13px) }
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !root.tab_enabled: Rectangle {
|
||||
Text {
|
||||
font-size: 24px;
|
||||
font-size: 16px;
|
||||
text: @tr("This fan is not avilable on this machine");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Palette.border;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 20px;
|
||||
alignment: LayoutAlignment.end;
|
||||
spacing: 10px;
|
||||
padding: 10px;
|
||||
CheckBox {
|
||||
text: @tr("Enable Manual Control");
|
||||
text: @tr("Enabled");
|
||||
checked <=> root.enabled;
|
||||
enabled: root.tab_enabled && !local_busy;
|
||||
enabled <=> root.tab_enabled;
|
||||
toggled => {
|
||||
root.toggled();
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
text: local_busy ? @tr("Applying...") : @tr("Apply Curve");
|
||||
enabled: root.tab_enabled && root.enabled && !local_busy;
|
||||
text: @tr("Apply");
|
||||
enabled <=> root.tab_enabled;
|
||||
clicked => {
|
||||
root.apply();
|
||||
}
|
||||
@@ -124,7 +57,7 @@ component FanTab inherits Rectangle {
|
||||
|
||||
Button {
|
||||
text: @tr("Cancel");
|
||||
enabled: root.tab_enabled && !local_busy;
|
||||
enabled <=> root.tab_enabled;
|
||||
clicked => {
|
||||
root.cancel()
|
||||
}
|
||||
@@ -132,7 +65,7 @@ component FanTab inherits Rectangle {
|
||||
|
||||
Button {
|
||||
text: @tr("Factory Default (all fans)");
|
||||
enabled: root.tab_enabled && !local_busy;
|
||||
enabled <=> root.tab_enabled;
|
||||
clicked => {
|
||||
root.default();
|
||||
}
|
||||
@@ -161,9 +94,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Balanced);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.CPU, Profile.Balanced);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,9 +112,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Balanced);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.Middle, Profile.Balanced);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,9 +130,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Balanced);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.GPU, Profile.Balanced);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -229,9 +153,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Performance);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.CPU, Profile.Performance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,9 +171,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Performance);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.Middle, Profile.Performance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,9 +189,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Performance);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.GPU, Profile.Performance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,9 +212,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Quiet);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.CPU, Profile.Quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,9 +230,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Quiet);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.Middle, Profile.Quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,9 +248,6 @@ export component PageFans inherits VerticalLayout {
|
||||
default => {
|
||||
FanPageData.set_profile_default(Profile.Quiet);
|
||||
}
|
||||
cancel => {
|
||||
FanPageData.cancel(FanType.GPU, Profile.Quiet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
rog-control-center/ui/pages/gpu.slint
Normal file
64
rog-control-center/ui/pages/gpu.slint
Normal file
@@ -0,0 +1,64 @@
|
||||
import { Palette, TabWidget, Button, CheckBox, ScrollView } from "std-widgets.slint";
|
||||
import { Graph, Node } from "../widgets/graph.slint";
|
||||
import { SystemToggle, SystemDropdown } from "../widgets/common.slint";
|
||||
import { Profile, FanType, FanPageData } from "../types/fan_types.slint";
|
||||
|
||||
export global GPUPageData {
|
||||
// GPU mode and device state
|
||||
in-out property <int> gpu_mux_mode: 1; // 0 = Ultra/Discreet, 1 = Integrated/Optimus
|
||||
in-out property <int> dgpu_disabled: 0; // 1 == dGPU disabled
|
||||
in-out property <int> egpu_enabled: 0; // 1 == eGPU (XGMobile) enabled
|
||||
in-out property <[string]> gpu_modes_choises: [@tr("Integrated"), @tr("Hybrid")];
|
||||
in-out property <bool> gpu_mux_available: false;
|
||||
callback cb_set_gpu_mode(int);
|
||||
}
|
||||
|
||||
export component PageGPU inherits Rectangle {
|
||||
clip: true;
|
||||
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
padding: 12px;
|
||||
spacing: 8px;
|
||||
|
||||
Rectangle {
|
||||
background: Palette.alternate-background;
|
||||
border-color: Palette.border;
|
||||
border-width: 1px;
|
||||
border-radius: 2px;
|
||||
height: 36px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
color: Palette.control-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text: @tr("Internal/Discrete GPU");
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
padding-right: 10px;
|
||||
padding-left: 10px;
|
||||
alignment: LayoutAlignment.space-between;
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
text: @tr("Note: Changes take effect after a reboot. The dropdown always shows the current mode.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
SystemDropdown {
|
||||
text: @tr("GPU mode");
|
||||
model <=> GPUPageData.gpu_modes_choises;
|
||||
current_index <=> GPUPageData.gpu_mux_mode;
|
||||
current_value: GPUPageData.gpu_modes_choises[GPUPageData.gpu_mux_mode];
|
||||
selected => {
|
||||
GPUPageData.cb_set_gpu_mode(GPUPageData.gpu_mux_mode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
import { Button, VerticalBox, Slider, Switch } from "std-widgets.slint";
|
||||
import { ScreenpadPageData } from "../types/screenpad_types.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { RogItem, SystemSlider } from "../widgets/common.slint";
|
||||
|
||||
export { ScreenpadPageData }
|
||||
|
||||
export component PageScreenpad inherits Rectangle {
|
||||
background: RogPalette.background;
|
||||
|
||||
VerticalBox {
|
||||
alignment: LayoutAlignment.start;
|
||||
padding: 20px;
|
||||
spacing: 20px;
|
||||
|
||||
Text {
|
||||
text: @tr("Screenpad Controls");
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: RogPalette.accent;
|
||||
}
|
||||
|
||||
RogItem {
|
||||
HorizontalLayout {
|
||||
padding: 15px;
|
||||
spacing: 20px;
|
||||
alignment: LayoutAlignment.space-between;
|
||||
|
||||
Text {
|
||||
text: @tr("Enable Screenpad");
|
||||
font-size: 16px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
Switch {
|
||||
checked <=> ScreenpadPageData.power;
|
||||
toggled => {
|
||||
ScreenpadPageData.cb_power(self.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
spacing: 15px;
|
||||
|
||||
// Brightness Slider
|
||||
SystemSlider {
|
||||
enabled: ScreenpadPageData.power;
|
||||
text: @tr("Brightness");
|
||||
minimum: 0;
|
||||
maximum: 255;
|
||||
value: ScreenpadPageData.brightness;
|
||||
help_text: ScreenpadPageData.brightness == -1 ? @tr("Not available") : "";
|
||||
released => {
|
||||
ScreenpadPageData.cb_brightness(Math.round(self.value));
|
||||
}
|
||||
}
|
||||
|
||||
// Gamma Slider (New)
|
||||
SystemSlider {
|
||||
enabled: ScreenpadPageData.power;
|
||||
text: @tr("Gamma");
|
||||
minimum: 0.1;
|
||||
maximum: 2.5;
|
||||
value: ScreenpadPageData.gamma;
|
||||
help_text: @tr("Adjust color intensity");
|
||||
released => {
|
||||
ScreenpadPageData.cb_gamma(self.value);
|
||||
}
|
||||
}
|
||||
|
||||
RogItem {
|
||||
enabled: ScreenpadPageData.power;
|
||||
HorizontalLayout {
|
||||
padding: 15px;
|
||||
spacing: 20px;
|
||||
alignment: LayoutAlignment.space-between;
|
||||
|
||||
Text {
|
||||
text: @tr("Sync with Primary Display");
|
||||
font-size: 16px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
Switch {
|
||||
enabled: ScreenpadPageData.power;
|
||||
checked <=> ScreenpadPageData.sync_with_primary;
|
||||
toggled => {
|
||||
ScreenpadPageData.cb_sync_with_primary(self.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Spacer
|
||||
Rectangle {}
|
||||
}
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
import { SystemToggle, SystemSlider, SystemDropdown, RogItem } from "../widgets/common.slint";
|
||||
import { VerticalBox, ScrollView, GroupBox } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { SlashPageData } from "../types/slash_types.slint";
|
||||
|
||||
export { SlashPageData }
|
||||
|
||||
export component PageSlash inherits Rectangle {
|
||||
background: RogPalette.background;
|
||||
|
||||
ScrollView {
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 20px;
|
||||
alignment: start;
|
||||
|
||||
// Header
|
||||
Rectangle {
|
||||
height: 40px;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: RogPalette.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
|
||||
Text {
|
||||
text: @tr("Slash Lighting Control");
|
||||
color: RogPalette.accent;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
// Main Control
|
||||
RogItem {
|
||||
VerticalBox {
|
||||
SystemToggle {
|
||||
text: @tr("Enable Slash Lighting");
|
||||
checked <=> SlashPageData.enabled;
|
||||
toggled => { SlashPageData.cb_enabled(self.checked); }
|
||||
}
|
||||
|
||||
SystemDropdown {
|
||||
text: @tr("Lighting Mode");
|
||||
model <=> SlashPageData.modes;
|
||||
current_index <=> SlashPageData.mode_index;
|
||||
current_value: SlashPageData.modes[SlashPageData.mode_index];
|
||||
selected => {
|
||||
SlashPageData.cb_mode_index(self.current_index);
|
||||
}
|
||||
}
|
||||
|
||||
SystemSlider {
|
||||
title: @tr("Brightness");
|
||||
text: @tr("Brightness");
|
||||
value <=> SlashPageData.brightness;
|
||||
minimum: 0;
|
||||
maximum: 255;
|
||||
help_text: "";
|
||||
released(val) => { SlashPageData.cb_brightness(val); }
|
||||
}
|
||||
|
||||
SystemSlider {
|
||||
title: @tr("Interval / Speed");
|
||||
text: @tr("Interval / Speed");
|
||||
value <=> SlashPageData.interval;
|
||||
minimum: 0;
|
||||
maximum: 255;
|
||||
help_text: "";
|
||||
released(val) => { SlashPageData.cb_interval(val); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Behaviors
|
||||
GroupBox {
|
||||
title: @tr("Behavior Settings");
|
||||
VerticalBox {
|
||||
SystemToggle {
|
||||
text: @tr("Show Battery Warning");
|
||||
checked <=> SlashPageData.show_battery_warning;
|
||||
toggled => { SlashPageData.cb_show_battery_warning(self.checked); }
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Active on Battery");
|
||||
checked <=> SlashPageData.show_on_battery;
|
||||
toggled => { SlashPageData.cb_show_on_battery(self.checked); }
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Active on Boot");
|
||||
checked <=> SlashPageData.show_on_boot;
|
||||
toggled => { SlashPageData.cb_show_on_boot(self.checked); }
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Active on Shutdown");
|
||||
checked <=> SlashPageData.show_on_shutdown;
|
||||
toggled => { SlashPageData.cb_show_on_shutdown(self.checked); }
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Active on Sleep");
|
||||
checked <=> SlashPageData.show_on_sleep;
|
||||
toggled => { SlashPageData.cb_show_on_sleep(self.checked); }
|
||||
}
|
||||
SystemToggle {
|
||||
text: @tr("Active when Lid Closed");
|
||||
checked <=> SlashPageData.show_on_lid_closed;
|
||||
toggled => { SlashPageData.cb_show_on_lid_closed(self.checked); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import { SystemDropdown, RogItem } from "../widgets/common.slint";
|
||||
import { VerticalBox, ScrollView, HorizontalBox } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { SupergfxPageData } from "../types/supergfx_types.slint";
|
||||
|
||||
export { SupergfxPageData }
|
||||
|
||||
export component PageSupergfx inherits Rectangle {
|
||||
background: RogPalette.background;
|
||||
|
||||
ScrollView {
|
||||
VerticalBox {
|
||||
padding: 20px;
|
||||
spacing: 20px;
|
||||
alignment: start;
|
||||
|
||||
// Header
|
||||
Rectangle {
|
||||
height: 40px;
|
||||
background: RogPalette.control-background;
|
||||
border-radius: RogPalette.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
|
||||
Text {
|
||||
text: @tr("Graphics Control (supergfx)");
|
||||
color: RogPalette.accent;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
RogItem {
|
||||
HorizontalBox {
|
||||
Text {
|
||||
text: @tr("Vendor: ") + SupergfxPageData.vendor;
|
||||
color: RogPalette.text-secondary;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main Control
|
||||
RogItem {
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("Current Mode: ") + SupergfxPageData.current_mode;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
SystemDropdown {
|
||||
text: @tr("Graphics Mode");
|
||||
model <=> SupergfxPageData.supported_modes;
|
||||
current_index <=> SupergfxPageData.selected_index;
|
||||
current_value: SupergfxPageData.supported_modes[SupergfxPageData.selected_index];
|
||||
selected => {
|
||||
SupergfxPageData.set_mode(self.current_value);
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("Note: Changing modes requires a logout.");
|
||||
color: RogPalette.text-secondary;
|
||||
font-size: 12px;
|
||||
wrap: word-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { SystemSlider, SystemDropdown, SystemToggle, SystemToggleInt, RogItem } from "../widgets/common.slint";
|
||||
import { Palette, HorizontalBox , VerticalBox, ScrollView, Slider, Button, Switch, ComboBox, GroupBox, StandardButton} from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export struct AttrMinMax {
|
||||
min: int,
|
||||
@@ -52,14 +51,6 @@ export global SystemPageData {
|
||||
callback cb_panel_overdrive(int);
|
||||
in-out property <int> boot_sound;
|
||||
callback cb_boot_sound(int);
|
||||
in-out property <int> kbd_leds_awake;
|
||||
callback cb_kbd_leds_awake(int);
|
||||
in-out property <int> kbd_leds_sleep;
|
||||
callback cb_kbd_leds_sleep(int);
|
||||
in-out property <int> kbd_leds_boot;
|
||||
callback cb_kbd_leds_boot(int);
|
||||
in-out property <int> kbd_leds_shutdown;
|
||||
callback cb_kbd_leds_shutdown(int);
|
||||
in-out property <int> screen_auto_brightness;
|
||||
callback cb_screen_auto_brightness(int);
|
||||
in-out property <int> mcu_powersave;
|
||||
@@ -67,6 +58,13 @@ export global SystemPageData {
|
||||
in-out property <int> mini_led_mode;
|
||||
callback cb_mini_led_mode(int);
|
||||
|
||||
in-out property <float> screenpad_gamma;
|
||||
callback cb_screenpad_gamma(float);
|
||||
// percentage
|
||||
in-out property <int> screenpad_brightness: 50;
|
||||
callback cb_screenpad_brightness(int);
|
||||
in-out property <bool> screenpad_sync_with_primary: false;
|
||||
callback cb_screenpad_sync_with_primary(bool);
|
||||
|
||||
in-out property <bool> asus_armoury_loaded: false;
|
||||
|
||||
@@ -146,27 +144,22 @@ export component PageSystem inherits Rectangle {
|
||||
property <bool> show_fade_cover: false;
|
||||
property <bool> show_throttle_advanced: false;
|
||||
clip: true;
|
||||
//padding only has effect on layout elements
|
||||
//padding: 8px;
|
||||
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
padding: 10px;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
spacing: 10px;
|
||||
padding: 12px;
|
||||
spacing: 8px;
|
||||
alignment: LayoutAlignment.start;
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-color: RogPalette.control-border;
|
||||
background: Palette.alternate-background;
|
||||
border-color: Palette.border;
|
||||
border-width: 1px;
|
||||
border-radius: 8px;
|
||||
height: 46px;
|
||||
border-radius: 2px;
|
||||
height: 36px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.accent;
|
||||
font-size: 16px;
|
||||
color: Palette.control-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
font-weight: 700;
|
||||
text: @tr("Power settings");
|
||||
}
|
||||
}
|
||||
@@ -205,79 +198,87 @@ export component PageSystem inherits Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
if SystemPageData.screenpad_brightness != -1: RogItem {
|
||||
HorizontalLayout {
|
||||
padding-left: 10px;
|
||||
padding-right: 20px;
|
||||
HorizontalLayout {
|
||||
width: 40%;
|
||||
alignment: LayoutAlignment.space-between;
|
||||
padding-right: 15px;
|
||||
Text {
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: Palette.control-foreground;
|
||||
text: @tr("Screenpad brightness");
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
width: 38%;
|
||||
alignment: LayoutAlignment.stretch;
|
||||
screen_bright := Slider {
|
||||
enabled: true;
|
||||
minimum: 0;
|
||||
maximum: 100;
|
||||
value: SystemPageData.screenpad_brightness;
|
||||
released(value) => {
|
||||
// SystemPageData.screenpad_brightness = self.value;
|
||||
SystemPageData.cb_screenpad_brightness(Math.floor(self.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
width: 20%;
|
||||
padding-left: 14px;
|
||||
alignment: LayoutAlignment.stretch;
|
||||
Switch {
|
||||
text: @tr("Sync with primary");
|
||||
checked <=> SystemPageData.screenpad_sync_with_primary;
|
||||
toggled => {
|
||||
SystemPageData.cb_screenpad_sync_with_primary(self.checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-color: RogPalette.control-border;
|
||||
background: Palette.alternate-background;
|
||||
border-color: Palette.border;
|
||||
border-width: 1px;
|
||||
border-radius: 8px;
|
||||
height: 46px;
|
||||
border-radius: 2px;
|
||||
height: 36px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.accent;
|
||||
font-size: 16px;
|
||||
color: Palette.control-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
font-weight: 700;
|
||||
text: @tr("Armoury settings");
|
||||
}
|
||||
}
|
||||
|
||||
if !SystemPageData.asus_armoury_loaded: Rectangle {
|
||||
border-width: 3px;
|
||||
border-color: red;
|
||||
background: maroon;
|
||||
// background: darkred;
|
||||
max-height: 30px;
|
||||
VerticalBox {
|
||||
Text {
|
||||
text: @tr("no_asus_armoury_driver_1" => "The asus-armoury driver is not loaded");
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: @tr("no_asus_armoury_driver_2" => "For advanced features you will require a kernel with this driver added.");
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GroupBox {
|
||||
title: @tr("Keyboard Power Management");
|
||||
HorizontalLayout {
|
||||
spacing: 10px;
|
||||
if SystemPageData.kbd_leds_awake != -1: SystemToggleInt {
|
||||
text: @tr("Keyboard Awake Effect");
|
||||
checked_int <=> SystemPageData.kbd_leds_awake;
|
||||
toggled => {
|
||||
SystemPageData.cb_kbd_leds_awake(SystemPageData.kbd_leds_awake)
|
||||
}
|
||||
}
|
||||
|
||||
if SystemPageData.kbd_leds_sleep != -1: SystemToggleInt {
|
||||
text: @tr("Keyboard Sleep Effect");
|
||||
checked_int <=> SystemPageData.kbd_leds_sleep;
|
||||
toggled => {
|
||||
SystemPageData.cb_kbd_leds_sleep(SystemPageData.kbd_leds_sleep)
|
||||
}
|
||||
}
|
||||
|
||||
if SystemPageData.kbd_leds_boot != -1: SystemToggleInt {
|
||||
text: @tr("Keyboard Boot Effect");
|
||||
checked_int <=> SystemPageData.kbd_leds_boot;
|
||||
toggled => {
|
||||
SystemPageData.cb_kbd_leds_boot(SystemPageData.kbd_leds_boot)
|
||||
}
|
||||
}
|
||||
|
||||
if SystemPageData.kbd_leds_shutdown != -1: SystemToggleInt {
|
||||
text: @tr("Keyboard Shutdown Effect");
|
||||
checked_int <=> SystemPageData.kbd_leds_shutdown;
|
||||
toggled => {
|
||||
SystemPageData.cb_kbd_leds_shutdown(SystemPageData.kbd_leds_shutdown)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
padding: 0px;
|
||||
spacing: 10px;
|
||||
@@ -331,7 +332,6 @@ export component PageSystem inherits Rectangle {
|
||||
Text {
|
||||
font-size: 16px;
|
||||
text: @tr("ppt_warning" => "The following settings are not applied until the toggle is enabled.");
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,7 +500,7 @@ export component PageSystem inherits Rectangle {
|
||||
if root.show_fade_cover: Rectangle {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: RogPalette.background;
|
||||
background: Palette.background;
|
||||
opacity: 0.9;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
@@ -516,24 +516,25 @@ export component PageSystem inherits Rectangle {
|
||||
}
|
||||
|
||||
if root.show_throttle_advanced: Rectangle {
|
||||
background: Palette.background;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 1;
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
padding: 50px;
|
||||
padding-top: 5px;
|
||||
padding-bottom: 100px;
|
||||
alignment: start;
|
||||
padding: 5px;
|
||||
padding-top: 15px;
|
||||
spacing: 10px;
|
||||
GroupBox {
|
||||
VerticalBox {
|
||||
alignment: start;
|
||||
spacing: 10px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
text: @tr("Energy Performance Preference linked to Throttle Policy");
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
SystemToggle {
|
||||
@@ -565,7 +566,7 @@ export component PageSystem inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemDropdown {
|
||||
text: @tr("EPP for Quiet Policy");
|
||||
text: @tr("EPP for ") + SystemPageData.platform_profile_choices[2] + @tr(" Policy");
|
||||
current_index <=> SystemPageData.profile_quiet_epp;
|
||||
current_value: SystemPageData.energy_performance_choices[SystemPageData.profile_quiet_epp];
|
||||
model <=> SystemPageData.energy_performance_choices;
|
||||
@@ -578,13 +579,13 @@ export component PageSystem inherits Rectangle {
|
||||
|
||||
GroupBox {
|
||||
VerticalBox {
|
||||
alignment: start;
|
||||
spacing: 10px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
text: @tr("Throttle Policy for power state");
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
@@ -636,8 +637,8 @@ export component PageSystem inherits Rectangle {
|
||||
Button {
|
||||
x: root.width - self.width - 6px;
|
||||
y: 6px;
|
||||
text: "X";
|
||||
height: 40px;
|
||||
text: "✕";
|
||||
height: 34px;
|
||||
clicked => {
|
||||
root.show_throttle_advanced = false;
|
||||
root.show_fade_cover = false;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
export global RogPalette {
|
||||
out property <brush> background: #0a0a0a;
|
||||
out property <brush> alternate-background: #111111;
|
||||
out property <brush> control-background: #1e1e1e;
|
||||
out property <brush> control-border: #333333;
|
||||
out property <brush> control-border-hover: #555555;
|
||||
out property <brush> control-border-checked: #ff0033; // ROG Red
|
||||
out property <brush> text-primary: #ffffff;
|
||||
out property <brush> text-secondary: #aaaaaa;
|
||||
out property <brush> accent: #ff0033;
|
||||
out property <brush> accent-hover: #d60000;
|
||||
out property <length> border-radius: 4px;
|
||||
}
|
||||
@@ -8,13 +8,6 @@ export enum AuraDevType {
|
||||
AnimeOrSlash,
|
||||
}
|
||||
|
||||
// Software animation modes for keyboards that only support Static
|
||||
export enum SoftAnimationMode {
|
||||
None,
|
||||
Rainbow,
|
||||
ColorCycle,
|
||||
}
|
||||
|
||||
export struct AuraEffect {
|
||||
/// The effect type
|
||||
mode: int,
|
||||
@@ -53,8 +46,10 @@ export struct LaptopAuraPower {
|
||||
states: [AuraPowerState],
|
||||
}
|
||||
|
||||
// Modes with colour1: Static,Breathe,Star,Rain,Highlight,Laser,Ripple,Pulse,Comet,Flash (excl. Strobe,Rainbow,Nothing)
|
||||
// Modes with colour2: Breathe, Star only.
|
||||
// Speed: Breathe,Strobe,Rainbow,Star,Rain,Highlight,Laser,Ripple. Direction: Rainbow only.
|
||||
export global AuraPageData {
|
||||
// The ordering must match the rog-aura crate
|
||||
in-out property <[string]> power_zone_names: [
|
||||
@tr("Aura power zone" => "Logo"),
|
||||
@tr("Aura power zone" => "Keyboard"),
|
||||
@@ -94,15 +89,9 @@ export global AuraPageData {
|
||||
@tr("Basic aura mode" => "Comet"),
|
||||
@tr("Basic aura mode" => "Flash"),
|
||||
];
|
||||
in-out property <[string]> available_mode_names: [
|
||||
@tr("Basic aura mode" => "Static"),
|
||||
@tr("Basic aura mode" => "Breathe"),
|
||||
@tr("Basic aura mode" => "Strobe"),
|
||||
];
|
||||
in-out property <[string]> available_mode_names: [ @tr("Basic aura mode" => "Static"), @tr("Basic aura mode" => "Breathe"), @tr("Basic aura mode" => "Strobe") ];
|
||||
in-out property <int> current_available_mode: 0;
|
||||
in-out property <[int]> supported_basic_modes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12];
|
||||
in-out property <int> led_mode;
|
||||
callback cb_led_mode(int);
|
||||
in-out property <[string]> zone_names: [
|
||||
@tr("Aura zone" => "None"),
|
||||
@tr("Aura zone" => "Key1"),
|
||||
@@ -113,51 +102,57 @@ export global AuraPageData {
|
||||
@tr("Aura zone" => "Lightbar Left"),
|
||||
@tr("Aura zone" => "Lightbar Right"),
|
||||
];
|
||||
in-out property <int> zone;
|
||||
in-out property <[string]> direction_names: [
|
||||
@tr("Aura direction" => "Right"),
|
||||
@tr("Aura direction" => "Left"),
|
||||
@tr("Aura direction" => "Up"),
|
||||
@tr("Aura direction" => "Down"),
|
||||
];
|
||||
in-out property <int> direction;
|
||||
in-out property <[string]> speed_names: [
|
||||
@tr("Aura speed" => "Low"),
|
||||
@tr("Aura speed" => "Medium"),
|
||||
@tr("Aura speed" => "High"),
|
||||
];
|
||||
in-out property <int> speed;
|
||||
|
||||
in-out property <AuraEffect> led_mode_data: {
|
||||
mode: 0,
|
||||
zone: 0,
|
||||
colour1: Colors.aquamarine,
|
||||
colourbox1: Colors.aquamarine,
|
||||
colour2: Colors.hotpink,
|
||||
colourbox2: Colors.hotpink,
|
||||
speed: 0,
|
||||
direction: 0,
|
||||
};
|
||||
callback cb_led_mode_data(AuraEffect);
|
||||
in-out property <color> color1;
|
||||
in-out property <brush> colorbox1;
|
||||
in-out property <color> color2;
|
||||
in-out property <brush> colorbox2;
|
||||
|
||||
out property <bool> colour1_enabled: led_mode_data.mode == 0 || led_mode_data.mode == 1 || led_mode_data.mode == 4 || led_mode_data.mode == 6 || led_mode_data.mode == 7 || led_mode_data.mode == 8 || led_mode_data.mode == 10 || led_mode_data.mode == 11 || led_mode_data.mode == 12;
|
||||
out property <bool> colour2_enabled: led_mode_data.mode == 1 || led_mode_data.mode == 4;
|
||||
out property <bool> speed_enabled: led_mode_data.mode == 1 || led_mode_data.mode == 2 || led_mode_data.mode == 3 || led_mode_data.mode == 4 || led_mode_data.mode == 5 || led_mode_data.mode == 6 || led_mode_data.mode == 7 || led_mode_data.mode == 8;
|
||||
out property <bool> direction_enabled: led_mode_data.mode == 3;
|
||||
|
||||
callback apply_led_mode_data();
|
||||
callback apply_effect(AuraEffect);
|
||||
apply_effect(e) => { led_mode_data = e; apply_led_mode_data(); }
|
||||
in-out property <int> zone;
|
||||
in-out property <int> speed;
|
||||
in-out property <int> direction;
|
||||
|
||||
callback update_led_mode_data(AuraEffect);
|
||||
update_led_mode_data(data) => {
|
||||
led_mode_data = data;
|
||||
current_available_mode = data.mode;
|
||||
zone = data.zone;
|
||||
speed = data.speed;
|
||||
direction = data.direction;
|
||||
color1 = data.colour1;
|
||||
color2 = data.colour2;
|
||||
colorbox1 = data.colour1;
|
||||
colorbox2 = data.colour2;
|
||||
update_led_mode_data(d) => {
|
||||
led_mode_data = d;
|
||||
zone = d.zone;
|
||||
speed = d.speed;
|
||||
direction = d.direction;
|
||||
color1 = d.colour1;
|
||||
color2 = d.colour2;
|
||||
colorbox1 = d.colour1;
|
||||
colorbox2 = d.colour2;
|
||||
}
|
||||
callback cb_hex_from_colour(color) -> string;
|
||||
callback cb_hex_to_colour(string) -> color;
|
||||
in-out property <AuraDevType> device_type: AuraDevType.Old;
|
||||
// List of indexes to power_zone_names. Must correspond to rog-aura crate
|
||||
in-out property <[PowerZones]> supported_power_zones: [
|
||||
PowerZones.Keyboard,
|
||||
PowerZones.Lightbar,
|
||||
@@ -173,16 +168,4 @@ export global AuraPageData {
|
||||
}]
|
||||
};
|
||||
callback cb_led_power(LaptopAuraPower);
|
||||
|
||||
// Software animation properties (for Static-only keyboards)
|
||||
in-out property <[string]> soft_animation_modes: [
|
||||
@tr("Animation mode" => "None"),
|
||||
@tr("Animation mode" => "Rainbow"),
|
||||
@tr("Animation mode" => "Color Cycle"),
|
||||
];
|
||||
in-out property <int> soft_animation_mode: 0;
|
||||
in-out property <float> soft_animation_speed: 200; // ms between updates
|
||||
in-out property <bool> soft_animation_available: false; // Set true when only Static mode is supported
|
||||
callback cb_soft_animation_mode(int);
|
||||
callback cb_soft_animation_speed(int);
|
||||
}
|
||||
|
||||
@@ -35,64 +35,314 @@ export global FanPageData {
|
||||
in-out property <bool> quiet_gpu_enabled: true;
|
||||
in-out property <bool> quiet_mid_enabled: false;
|
||||
|
||||
in-out property <bool> is_busy_cpu: false;
|
||||
in-out property <bool> is_busy_gpu: false;
|
||||
in-out property <bool> is_busy_mid: false;
|
||||
in-out property <bool> show_custom_warning: false;
|
||||
|
||||
callback set_fan_data(FanType, Profile, bool, [Node]);
|
||||
callback set_profile_default(Profile);
|
||||
callback set_is_busy(FanType, bool);
|
||||
// Last applied cache for Cancel button
|
||||
in-out property <[Node]> last_applied_cpu_balanced: [];
|
||||
in-out property <[Node]> last_applied_gpu_balanced: [];
|
||||
in-out property <[Node]> last_applied_mid_balanced: [];
|
||||
in-out property <[Node]> last_applied_cpu_performance: [];
|
||||
in-out property <[Node]> last_applied_gpu_performance: [];
|
||||
in-out property <[Node]> last_applied_mid_performance: [];
|
||||
in-out property <[Node]> last_applied_cpu_quiet: [];
|
||||
in-out property <[Node]> last_applied_gpu_quiet: [];
|
||||
in-out property <[Node]> last_applied_mid_quiet: [];
|
||||
|
||||
callback cancel(FanType, Profile);
|
||||
|
||||
in-out property <[Node]> balanced_cpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> balanced_mid: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> balanced_gpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 25px }, { x: 80px, y: 55px }, { x: 90px, y: 85px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
|
||||
in-out property <[Node]> performance_cpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
|
||||
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> performance_mid: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
|
||||
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> performance_gpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 10px }, { x: 50px, y: 30px }, { x: 60px, y: 50px },
|
||||
{ x: 70px, y: 70px }, { x: 80px, y: 85px }, { x: 90px, y: 95px }, { x: 98px, y: 100px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
|
||||
in-out property <[Node]> quiet_cpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> quiet_mid: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
in-out property <[Node]> quiet_gpu: [
|
||||
{ x: 30px, y: 0px }, { x: 40px, y: 0px }, { x: 50px, y: 0px }, { x: 60px, y: 0px },
|
||||
{ x: 70px, y: 20px }, { x: 80px, y: 40px }, { x: 90px, y: 70px }, { x: 98px, y: 90px },
|
||||
{
|
||||
x: 10px,
|
||||
y: 10px,
|
||||
},
|
||||
{
|
||||
x: 40px,
|
||||
y: 30px,
|
||||
},
|
||||
{
|
||||
x: 50px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 55px,
|
||||
y: 50px,
|
||||
},
|
||||
{
|
||||
x: 60px,
|
||||
y: 60px,
|
||||
},
|
||||
{
|
||||
x: 65px,
|
||||
y: 70px,
|
||||
},
|
||||
{
|
||||
x: 70px,
|
||||
y: 80px,
|
||||
},
|
||||
{
|
||||
x: 90px,
|
||||
y: 100px,
|
||||
},
|
||||
];
|
||||
|
||||
function set_fan(profile: Profile, fan: FanType, data: [Node]) {
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export global ScreenpadPageData {
|
||||
in-out property <int> brightness: -1;
|
||||
in-out property <float> gamma: 1.0;
|
||||
in-out property <bool> sync_with_primary: false;
|
||||
in-out property <bool> power: true;
|
||||
|
||||
callback cb_brightness(int);
|
||||
callback cb_gamma(float);
|
||||
callback cb_sync_with_primary(bool);
|
||||
callback cb_power(bool);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
export global SlashPageData {
|
||||
in-out property <bool> enabled;
|
||||
callback cb_enabled(bool);
|
||||
|
||||
in-out property <float> brightness;
|
||||
callback cb_brightness(float);
|
||||
|
||||
in-out property <float> interval;
|
||||
callback cb_interval(float);
|
||||
|
||||
in-out property <[string]> modes: [
|
||||
@tr("Static"),
|
||||
@tr("Bounce"),
|
||||
@tr("Slash"),
|
||||
@tr("Loading"),
|
||||
@tr("BitStream"),
|
||||
@tr("Transmission"),
|
||||
@tr("Flow"),
|
||||
@tr("Flux"),
|
||||
@tr("Phantom"),
|
||||
@tr("Spectrum"),
|
||||
@tr("Hazard"),
|
||||
@tr("Interfacing"),
|
||||
@tr("Ramp"),
|
||||
@tr("GameOver"),
|
||||
@tr("Start"),
|
||||
@tr("Buzzer"),
|
||||
];
|
||||
in-out property <int> mode_index;
|
||||
callback cb_mode_index(int);
|
||||
|
||||
in-out property <bool> show_battery_warning;
|
||||
callback cb_show_battery_warning(bool);
|
||||
|
||||
in-out property <bool> show_on_battery;
|
||||
callback cb_show_on_battery(bool);
|
||||
|
||||
in-out property <bool> show_on_boot;
|
||||
callback cb_show_on_boot(bool);
|
||||
|
||||
in-out property <bool> show_on_shutdown;
|
||||
callback cb_show_on_shutdown(bool);
|
||||
|
||||
in-out property <bool> show_on_sleep;
|
||||
callback cb_show_on_sleep(bool);
|
||||
|
||||
in-out property <bool> show_on_lid_closed;
|
||||
callback cb_show_on_lid_closed(bool);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
export global SupergfxPageData {
|
||||
in-out property <string> current_mode: "Hybrid";
|
||||
in-out property <[string]> supported_modes: ["Hybrid", "Integrated"];
|
||||
in-out property <int> selected_index: 0;
|
||||
|
||||
in-out property <string> vendor: "Unknown";
|
||||
|
||||
callback set_mode(string);
|
||||
callback refresh();
|
||||
}
|
||||
@@ -1,14 +1,10 @@
|
||||
import { VerticalBox, HorizontalBox, GroupBox } from "std-widgets.slint";
|
||||
import { Palette, VerticalBox, HorizontalBox, GroupBox } from "std-widgets.slint";
|
||||
import { SystemToggleVert, SystemDropdown } from "common.slint";
|
||||
import { PowerZones } from "../types/aura_types.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export component AuraPowerGroup inherits Rectangle {
|
||||
min-width: row.min-width;
|
||||
border-radius: 8px;
|
||||
background: RogPalette.control-background;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
opacity: 0.9;
|
||||
in-out property <string> group-title;
|
||||
in-out property <bool> boot_checked;
|
||||
in-out property <bool> awake_checked;
|
||||
@@ -18,11 +14,12 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
callback awake_toggled(bool);
|
||||
callback sleep_toggled(bool);
|
||||
callback shutdown_toggled(bool);
|
||||
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.alternate-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text <=> root.group-title;
|
||||
}
|
||||
@@ -30,7 +27,7 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
row := HorizontalBox {
|
||||
alignment: LayoutAlignment.center;
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Boot");
|
||||
checked <=> root.boot_checked;
|
||||
@@ -40,7 +37,7 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Awake");
|
||||
checked <=> root.awake_checked;
|
||||
@@ -50,7 +47,7 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Sleep");
|
||||
checked <=> root.sleep_checked;
|
||||
@@ -60,7 +57,7 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Shutdown");
|
||||
checked <=> root.shutdown_checked;
|
||||
@@ -74,10 +71,7 @@ export component AuraPowerGroup inherits Rectangle {
|
||||
|
||||
export component AuraPowerGroupOld inherits Rectangle {
|
||||
min-width: row.min-width;
|
||||
border-radius: 8px;
|
||||
background: RogPalette.control-background;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
opacity: 0.9;
|
||||
in-out property <int> current_zone;
|
||||
in-out property <[int]> zones;
|
||||
in-out property <[string]> zone_strings;
|
||||
@@ -89,11 +83,12 @@ export component AuraPowerGroupOld inherits Rectangle {
|
||||
callback awake_toggled(bool);
|
||||
callback sleep_toggled(bool);
|
||||
callback selected_zone(int);
|
||||
|
||||
VerticalBox {
|
||||
spacing: 10px;
|
||||
Text {
|
||||
font-size: 18px;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.alternate-foreground;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text <=> root.group-title;
|
||||
}
|
||||
@@ -112,7 +107,7 @@ export component AuraPowerGroupOld inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Boot");
|
||||
checked <=> root.boot_checked;
|
||||
@@ -122,7 +117,7 @@ export component AuraPowerGroupOld inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Awake");
|
||||
checked <=> root.awake_checked;
|
||||
@@ -132,7 +127,7 @@ export component AuraPowerGroupOld inherits Rectangle {
|
||||
}
|
||||
|
||||
SystemToggleVert {
|
||||
min-width: 96px;
|
||||
min-width: 128px;
|
||||
max-height: 42px;
|
||||
text: @tr("Sleep");
|
||||
checked <=> root.sleep_checked;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Palette, Slider, HorizontalBox, Button, LineEdit } from "std-widgets.slint";
|
||||
|
||||
export component ColourSlider inherits VerticalLayout {
|
||||
spacing: 10px;
|
||||
spacing: 12px;
|
||||
in-out property <bool> enabled;
|
||||
property <string> hex: "#FF0000";
|
||||
in-out property <float> c1value <=> c1.value;
|
||||
@@ -102,9 +102,9 @@ export component ColourSlider inherits VerticalLayout {
|
||||
hex = set_hex_from_colour(final_colour);
|
||||
}
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
border-width: 2px;
|
||||
border-radius: 7px;
|
||||
height: 28px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
border-color: Palette.border;
|
||||
// 13 colours
|
||||
background: !root.enabled ? Palette.alternate-background : @linear-gradient(90deg, base_colours[0], base_colours[1], base_colours[2], base_colours[3], base_colours[4], base_colours[5], base_colours[6], base_colours[7], base_colours[8], base_colours[9], base_colours[10], base_colours[11], base_colours[12], base_colours[13], base_colours[14], base_colours[15], base_colours[16], base_colours[17], base_colours[18], base_colours[19], base_colours[20], base_colours[21], base_colours[22], base_colours[23], base_colours[24], base_colours[25], base_colours[26], base_colours[27], base_colours[28], base_colours[29], base_colours[30], base_colours[31], base_colours[32], base_colours[33], base_colours[34], base_colours[35]);
|
||||
@@ -127,9 +127,9 @@ export component ColourSlider inherits VerticalLayout {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
border-width: 2px;
|
||||
border-radius: 7px;
|
||||
height: 28px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
border-color: Palette.border;
|
||||
// 11 colours
|
||||
background: !root.enabled ? Palette.alternate-background : @linear-gradient(90deg, base_saturation[0], base_saturation[1], base_saturation[2], base_saturation[3], base_saturation[4], base_saturation[5], base_saturation[6], base_saturation[7], base_saturation[8], base_saturation[9], base_saturation[10]);
|
||||
@@ -151,9 +151,9 @@ export component ColourSlider inherits VerticalLayout {
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 32px;
|
||||
border-width: 2px;
|
||||
border-radius: 7px;
|
||||
height: 28px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
border-color: Palette.border;
|
||||
// 11 colours
|
||||
background: !root.enabled ? Palette.alternate-background : @linear-gradient(90deg, base_value[0], base_value[1], base_value[2], base_value[3], base_value[4], base_value[5], base_value[6], base_value[7], base_value[8], base_value[9], base_value[10]);
|
||||
@@ -191,8 +191,8 @@ export component ColourSlider inherits VerticalLayout {
|
||||
|
||||
Rectangle {
|
||||
width: self.height;
|
||||
border-width: 2px;
|
||||
border-radius: 7px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
border-color: Palette.border;
|
||||
background <=> root.colourbox;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { VerticalBox , StandardButton, Button, HorizontalBox, ComboBox, Switch, Slider} from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { Palette, VerticalBox , StandardButton, Button, HorizontalBox, ComboBox, Switch, Slider} from "std-widgets.slint";
|
||||
|
||||
export component RogItem inherits Rectangle {
|
||||
in property <bool> enabled: true;
|
||||
background: root.enabled ? RogPalette.control-background : RogPalette.control-background.darker(0.5);
|
||||
border-color: root.enabled ? RogPalette.control-border : RogPalette.control-border.darker(0.3);
|
||||
border-width: 1px; // Thinner border for modern look
|
||||
border-radius: RogPalette.border-radius;
|
||||
min-height: 48px;
|
||||
max-height: 56px;
|
||||
opacity: root.enabled ? 1.0 : 0.6;
|
||||
border-color: Palette.border;
|
||||
border-width: 1px;
|
||||
border-radius: 2px;
|
||||
min-height: 44px;
|
||||
max-height: 44px;
|
||||
}
|
||||
|
||||
export component SystemSlider inherits RogItem {
|
||||
@@ -21,6 +17,7 @@ export component SystemSlider inherits RogItem {
|
||||
callback released(float);
|
||||
|
||||
in property <string> help_text;
|
||||
in property <bool> enabled: true;
|
||||
in property <bool> has_reset: false;
|
||||
callback cb_do_reset();
|
||||
|
||||
@@ -32,24 +29,24 @@ export component SystemSlider inherits RogItem {
|
||||
HorizontalLayout {
|
||||
spacing: 6px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
text: root.text;
|
||||
}
|
||||
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
horizontal-alignment: TextHorizontalAlignment.right;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.accent;
|
||||
color: Palette.control-foreground;
|
||||
text: "\{Math.round(root.value)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalBox {
|
||||
padding-right: 20px;
|
||||
padding-right: 10px;
|
||||
slider := Slider {
|
||||
enabled: root.enabled;
|
||||
maximum: root.maximum;
|
||||
@@ -66,11 +63,10 @@ export component SystemSlider inherits RogItem {
|
||||
y: help.y - self.height + help.height - 10px;
|
||||
Rectangle {
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: Colors.black;
|
||||
border-radius: RogPalette.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.accent;
|
||||
background: RogPalette.control-background;
|
||||
drop-shadow-color: black;
|
||||
border-radius: 10px;
|
||||
border-color: Palette.accent-background;
|
||||
background: Palette.background;
|
||||
Dialog {
|
||||
title: root.title;
|
||||
VerticalBox {
|
||||
@@ -80,12 +76,12 @@ export component SystemSlider inherits RogItem {
|
||||
wrap: TextWrap.word-wrap;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
text: root.title;
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: 1px;
|
||||
background: RogPalette.control-border;
|
||||
border-color: black;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
Text {
|
||||
@@ -93,7 +89,6 @@ export component SystemSlider inherits RogItem {
|
||||
font-size: 16px;
|
||||
wrap: TextWrap.word-wrap;
|
||||
text: root.help_text;
|
||||
color: RogPalette.text-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,18 +113,16 @@ export component SystemSlider inherits RogItem {
|
||||
y: reset.y - self.height + reset.height;
|
||||
Rectangle {
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: Colors.black;
|
||||
border-radius: RogPalette.border-radius;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.accent;
|
||||
background: RogPalette.control-background;
|
||||
drop-shadow-color: black;
|
||||
border-radius: 10px;
|
||||
border-color: Palette.accent-background;
|
||||
background: Palette.background;
|
||||
Dialog {
|
||||
Text {
|
||||
max-width: 420px;
|
||||
font-size: 16px;
|
||||
wrap: TextWrap.word-wrap;
|
||||
text: @tr("confirm_reset" => "Are you sure you want to reset this?");
|
||||
color: RogPalette.text-primary;
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
@@ -168,9 +161,9 @@ export component SystemToggle inherits RogItem {
|
||||
alignment: LayoutAlignment.start;
|
||||
padding-left: 10px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
text: root.text;
|
||||
}
|
||||
}
|
||||
@@ -199,9 +192,9 @@ export component SystemToggleInt inherits RogItem {
|
||||
alignment: LayoutAlignment.start;
|
||||
padding-left: 10px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
text: root.text;
|
||||
}
|
||||
}
|
||||
@@ -229,10 +222,10 @@ export component SystemToggleVert inherits RogItem {
|
||||
alignment: LayoutAlignment.space-around;
|
||||
padding-top: 8px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.bottom;
|
||||
horizontal-alignment: TextHorizontalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
text: root.text;
|
||||
}
|
||||
|
||||
@@ -260,9 +253,9 @@ export component SystemDropdown inherits RogItem {
|
||||
alignment: LayoutAlignment.start;
|
||||
padding-left: 10px;
|
||||
Text {
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
vertical-alignment: TextVerticalAlignment.center;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
text: root.text;
|
||||
}
|
||||
}
|
||||
@@ -294,28 +287,24 @@ export component PopupNotification {
|
||||
height: root.height;
|
||||
// TODO: add properties to display
|
||||
Rectangle {
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.accent;
|
||||
background: RogPalette.background;
|
||||
// TODO: drop shadows slow
|
||||
// drop-shadow-offset-x: 7px;
|
||||
// drop-shadow-offset-y: 7px;
|
||||
// drop-shadow-color: black;
|
||||
// drop-shadow-blur: 30px;
|
||||
border-width: 2px;
|
||||
border-color: Palette.accent-background;
|
||||
background: Palette.background;
|
||||
|
||||
VerticalLayout {
|
||||
Dialog {
|
||||
VerticalLayout {
|
||||
alignment: start;
|
||||
Text {
|
||||
text: heading;
|
||||
color: RogPalette.text-primary;
|
||||
color: Palette.control-foreground;
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: content;
|
||||
color: RogPalette.text-secondary;
|
||||
color: Palette.control-foreground;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Palette } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export struct Node { x: length, y: length}
|
||||
|
||||
@@ -45,7 +44,7 @@ export component Graph inherits Rectangle {
|
||||
for n in 11: Path {
|
||||
viewbox-width: self.width / 1px;
|
||||
viewbox-height: self.height / 1px;
|
||||
stroke: RogPalette.control-border;
|
||||
stroke: Palette.alternate-foreground.darker(200%);
|
||||
stroke-width: 1px;
|
||||
MoveTo {
|
||||
x: scale_x_to_graph(n * 10px) / 1px;
|
||||
@@ -61,7 +60,7 @@ export component Graph inherits Rectangle {
|
||||
}
|
||||
|
||||
for n in 11: Text {
|
||||
color: RogPalette.text-secondary;
|
||||
color: Palette.accent-background;
|
||||
font-size <=> root.axis_font_size;
|
||||
text: "\{n * 10}c";
|
||||
x: scale_x_to_graph(n * 10px) - self.width / 3;
|
||||
@@ -71,7 +70,7 @@ export component Graph inherits Rectangle {
|
||||
for n in 11: Path {
|
||||
viewbox-width: self.width / 1px;
|
||||
viewbox-height: self.height / 1px;
|
||||
stroke: RogPalette.control-border;
|
||||
stroke: Palette.alternate-foreground.darker(200%);
|
||||
stroke-width: 1px;
|
||||
MoveTo {
|
||||
x: 0;
|
||||
@@ -87,7 +86,7 @@ export component Graph inherits Rectangle {
|
||||
}
|
||||
|
||||
for n in 11: Text {
|
||||
color: RogPalette.text-secondary;
|
||||
color: Palette.accent-background;
|
||||
font-size <=> root.axis_font_size;
|
||||
text: "\{n * 10}%";
|
||||
x: - self.width;
|
||||
@@ -98,7 +97,7 @@ export component Graph inherits Rectangle {
|
||||
if idx + 1 != nodes.length: Path {
|
||||
viewbox-width: self.width / 1px;
|
||||
viewbox-height: self.height / 1px;
|
||||
stroke: RogPalette.accent;
|
||||
stroke: Palette.control-foreground;
|
||||
stroke-width: 2px;
|
||||
MoveTo {
|
||||
x: scale_x_to_graph(nodes[idx].x) / 1px;
|
||||
@@ -115,19 +114,19 @@ export component Graph inherits Rectangle {
|
||||
for n[idx] in nodes: Rectangle {
|
||||
states [
|
||||
pressed when touch.pressed: {
|
||||
point.background: RogPalette.accent;
|
||||
tip.background: RogPalette.accent;
|
||||
point.background: Palette.selection-background;
|
||||
tip.background: Palette.selection-background;
|
||||
tip.opacity: 1.0;
|
||||
}
|
||||
hover when touch.has-hover: {
|
||||
point.background: RogPalette.accent;
|
||||
tip.background: RogPalette.accent;
|
||||
point.background: Palette.accent-background;
|
||||
tip.background: Palette.accent-background;
|
||||
tip.opacity: 1.0;
|
||||
}
|
||||
]
|
||||
//
|
||||
point := Rectangle {
|
||||
background: RogPalette.text-primary;
|
||||
background: Palette.control-foreground;
|
||||
x: scale_x_to_graph(n.x) - self.width / 2;
|
||||
y: graph.height - scale_y_to_graph(n.y) - self.height / 2;
|
||||
width: 18px;
|
||||
@@ -143,14 +142,10 @@ export component Graph inherits Rectangle {
|
||||
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < nodes[idx - 1].x {
|
||||
n.x = nodes[idx - 1].x + pad;
|
||||
}
|
||||
|
||||
// Y-Axis: Monotonic Non-Decreasing
|
||||
if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) > nodes[idx + 1].y {
|
||||
n.y = nodes[idx + 1].y; // Allow equality
|
||||
n.y = nodes[idx + 1].y - pad;
|
||||
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < nodes[idx - 1].y {
|
||||
n.y = nodes[idx - 1].y; // Allow equality
|
||||
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < 0.0 {
|
||||
n.y = 0px;
|
||||
n.y = nodes[idx - 1].y + pad;
|
||||
}
|
||||
} else if idx == 0 {
|
||||
if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < 0.0 {
|
||||
@@ -158,12 +153,10 @@ export component Graph inherits Rectangle {
|
||||
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) > nodes[idx + 1].x {
|
||||
n.x = nodes[idx + 1].x - pad;
|
||||
}
|
||||
|
||||
// Y-Axis: <= Next Point
|
||||
if n.y - scale_y_to_node(self.mouse-y - self.pressed-y) < 0.0 {
|
||||
n.y = 0px; // Allow 0 RPM
|
||||
n.y = 1px;
|
||||
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) > nodes[idx + 1].y {
|
||||
n.y = nodes[idx + 1].y; // Allow equality
|
||||
n.y = nodes[idx + 1].y - pad;
|
||||
}
|
||||
} else if idx == nodes.length - 1 {
|
||||
if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) > scale_x_to_node(graph.width) {
|
||||
@@ -171,14 +164,10 @@ export component Graph inherits Rectangle {
|
||||
} else if n.x + scale_x_to_node(self.mouse-x - self.pressed-x) < nodes[idx - 1].x {
|
||||
n.x = nodes[idx - 1].x + pad;
|
||||
}
|
||||
|
||||
// Y-Axis: >= Previous Point
|
||||
if n.y - scale_y_to_node(self.mouse-y - self.pressed-y) > scale_y_to_node(graph.height) {
|
||||
n.y = scale_y_to_node(graph.height);
|
||||
n.y = scale_y_to_node(graph.height - 1px);
|
||||
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < nodes[idx - 1].y {
|
||||
n.y = nodes[idx - 1].y; // Allow equality
|
||||
} else if n.y + scale_y_to_node(self.height - self.mouse-y - self.pressed-y) < 0.0 {
|
||||
n.y = 0px;
|
||||
n.y = nodes[idx - 1].y + pad;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,12 +189,13 @@ export component Graph inherits Rectangle {
|
||||
}
|
||||
|
||||
tip := Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
background: Palette.control-foreground;
|
||||
opacity: 0.3;
|
||||
border-radius: 12px;
|
||||
x: final_x_pos();
|
||||
y: final_y_pos();
|
||||
width: label.preferred-width;
|
||||
height: label.preferred-height;
|
||||
width: label.preferred-width + 14px;
|
||||
height: label.preferred-height + 4px;
|
||||
function x_pos() -> length {
|
||||
scale_x_to_graph(n.x) - label.preferred-width - 8px
|
||||
}
|
||||
@@ -235,8 +225,8 @@ export component Graph inherits Rectangle {
|
||||
}
|
||||
//
|
||||
label := Text {
|
||||
color: RogPalette.text-primary;
|
||||
font-size: 16px;
|
||||
color: Palette.accent-foreground;
|
||||
font-size: 14px;
|
||||
text: "\{Math.floor(n.x / 1px)}c, \{fan_pct()}%";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { HorizontalBox, VerticalBox } from "std-widgets.slint";
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { Palette, HorizontalBox, VerticalBox } from "std-widgets.slint";
|
||||
|
||||
component SideBarItem inherits Rectangle {
|
||||
// padding only has effect on layout elements
|
||||
// padding: 10px;
|
||||
in property <bool> selected;
|
||||
in property <bool> has-focus;
|
||||
in-out property <string> text <=> label.text;
|
||||
@@ -27,34 +24,22 @@ component SideBarItem inherits Rectangle {
|
||||
state.opacity: 0.8;
|
||||
}
|
||||
]
|
||||
|
||||
state := Rectangle {
|
||||
opacity: 0;
|
||||
border-width: 0px; // Modern look: no full border, maybe just a left bar?
|
||||
// Or keep the ROG style border
|
||||
border-color: RogPalette.accent;
|
||||
background: root.selected ? RogPalette.control-background : RogPalette.alternate-background;
|
||||
|
||||
// Add a red indicator line on the left for selected items
|
||||
Rectangle {
|
||||
x: 0;
|
||||
width: 4px;
|
||||
height: 100%;
|
||||
background: root.selected ? RogPalette.accent : Colors.transparent;
|
||||
}
|
||||
|
||||
background: Palette.selection-background;
|
||||
animate opacity { duration: 150ms; }
|
||||
// animate border-width { duration: 150ms; }
|
||||
height: l.preferred-height;
|
||||
}
|
||||
|
||||
l := HorizontalBox {
|
||||
x: 4px;
|
||||
y: (parent.height - self.height) / 2;
|
||||
spacing: 0px;
|
||||
label := Text {
|
||||
color: root.selected ? RogPalette.accent : RogPalette.text-primary;
|
||||
color: Palette.foreground;
|
||||
vertical-alignment: center;
|
||||
font-size: 14px;
|
||||
font-weight: root.selected ? 700 : 400;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,20 +52,17 @@ component SideBarItem inherits Rectangle {
|
||||
export component SideBar inherits Rectangle {
|
||||
in property <[string]> model: [];
|
||||
in property <[bool]> available: [];
|
||||
in property <string> title <=> label.text;
|
||||
in property <bool> is_tuf: false;
|
||||
out property <int> current-item: 0;
|
||||
out property <int> current-focused: fs.has-focus ? fs.focused-tab : -1;
|
||||
|
||||
// The currently focused tab
|
||||
width: 160px;
|
||||
width: 180px;
|
||||
forward-focus: fs;
|
||||
accessible-role: tab;
|
||||
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
|
||||
Rectangle {
|
||||
border-width: 0px;
|
||||
// border-color: RogPalette.accent;
|
||||
border-radius: 0px;
|
||||
background: RogPalette.alternate-background; // Darker sidebar
|
||||
background: Palette.alternate-background;
|
||||
fs := FocusScope {
|
||||
key-pressed(event) => {
|
||||
if (event.text == "\n") {
|
||||
@@ -113,21 +95,26 @@ export component SideBar inherits Rectangle {
|
||||
|
||||
VerticalBox {
|
||||
spacing: 4px;
|
||||
padding: 0px;
|
||||
alignment: start;
|
||||
label := Text {
|
||||
font-size: 24px; // Larger brand text
|
||||
font-weight: 800;
|
||||
|
||||
Image {
|
||||
height: 100px;
|
||||
// TODO: change if TUF on the logo in the menu on the main page
|
||||
// If running on a TUF model, replace the ROG red with TUF orange
|
||||
// (add data/tuf-control-center.png and switch here when available)
|
||||
source: @image-url("../../data/rog-control-center.png");
|
||||
horizontal-alignment: center;
|
||||
color: RogPalette.accent; // ROG Red brand text
|
||||
image-fit: contain;
|
||||
}
|
||||
|
||||
// Spacer after brand text
|
||||
Rectangle {
|
||||
height: 20px;
|
||||
height: 1px;
|
||||
background: Palette.border;
|
||||
}
|
||||
|
||||
navigation := VerticalLayout {
|
||||
spacing: 4px; // Spacing between items
|
||||
spacing: -6px;
|
||||
alignment: start;
|
||||
vertical-stretch: 0;
|
||||
for item[index] in root.model: SideBarItem {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
|
||||
export global SystemStatus {
|
||||
in property <int> cpu_temp: 0;
|
||||
in property <int> gpu_temp: 0;
|
||||
in property <int> cpu_fan: 0;
|
||||
in property <int> gpu_fan: 0;
|
||||
in property <string> power_w: "--";
|
||||
in property <string> power_avg_w: "--";
|
||||
}
|
||||
|
||||
component StatusItem inherits Rectangle {
|
||||
in property <string> label;
|
||||
in property <string> value;
|
||||
in property <string> unit;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 5px;
|
||||
Text { text: label; color: RogPalette.text-secondary; font-weight: 700; vertical-alignment: center; }
|
||||
Text { text: value; color: RogPalette.text-primary; vertical-alignment: center; }
|
||||
Text { text: unit; color: RogPalette.text-secondary; font-size: 12px; vertical-alignment: center; }
|
||||
}
|
||||
}
|
||||
|
||||
export component StatusBar inherits Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
height: 30px;
|
||||
|
||||
// Simulated top border
|
||||
Rectangle {
|
||||
y: 0px;
|
||||
x: 0px;
|
||||
width: parent.width;
|
||||
height: 1px;
|
||||
background: RogPalette.control-border;
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
spacing: 20px;
|
||||
alignment: space-between;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 20px;
|
||||
StatusItem { label: "CPU"; value: SystemStatus.cpu_temp; unit: "°C"; }
|
||||
StatusItem { label: "GPU"; value: SystemStatus.gpu_temp; unit: "°C"; }
|
||||
}
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 20px;
|
||||
StatusItem { label: "PWR"; value: SystemStatus.power_w; unit: "W"; }
|
||||
StatusItem { label: "AVG"; value: SystemStatus.power_avg_w; unit: "W"; }
|
||||
StatusItem { label: "CPU Fan"; value: SystemStatus.cpu_fan; unit: "RPM"; }
|
||||
StatusItem { label: "GPU Fan"; value: SystemStatus.gpu_fan; unit: "RPM"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
import { RogPalette } from "../themes/rog_theme.slint";
|
||||
import { SystemStatus } from "../widgets/status_bar.slint";
|
||||
|
||||
component StatusItem inherits Rectangle {
|
||||
in property <string> label;
|
||||
in property <string> value;
|
||||
in property <string> unit;
|
||||
|
||||
HorizontalLayout {
|
||||
spacing: 8px;
|
||||
Text {
|
||||
text: label;
|
||||
color: RogPalette.text-secondary;
|
||||
font-weight: 700;
|
||||
vertical-alignment: center;
|
||||
font-size: 13px;
|
||||
}
|
||||
Text {
|
||||
text: value;
|
||||
color: RogPalette.text-primary;
|
||||
vertical-alignment: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
Text {
|
||||
text: unit;
|
||||
color: RogPalette.text-secondary;
|
||||
font-size: 11px;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export component TrayTooltip inherits Window {
|
||||
always-on-top: true;
|
||||
no-frame: true;
|
||||
background: transparent;
|
||||
width: 280px;
|
||||
height: 160px;
|
||||
|
||||
Rectangle {
|
||||
background: RogPalette.control-background;
|
||||
border-radius: 8px;
|
||||
border-width: 1px;
|
||||
border-color: RogPalette.control-border;
|
||||
drop-shadow-blur: 10px;
|
||||
drop-shadow-color: rgba(0,0,0,0.5);
|
||||
|
||||
VerticalLayout {
|
||||
padding: 15px;
|
||||
spacing: 12px;
|
||||
|
||||
Text {
|
||||
text: "System Statistics";
|
||||
color: RogPalette.accent;
|
||||
font-size: 16px;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
spacing: 15px;
|
||||
Row {
|
||||
StatusItem { label: "CPU"; value: SystemStatus.cpu_temp; unit: "°C"; }
|
||||
StatusItem { label: "GPU"; value: SystemStatus.gpu_temp; unit: "°C"; }
|
||||
}
|
||||
Row {
|
||||
StatusItem { label: "FAN"; value: SystemStatus.cpu_fan; unit: "RPM"; }
|
||||
StatusItem { label: "GPU"; value: SystemStatus.gpu_fan; unit: "RPM"; }
|
||||
}
|
||||
Row {
|
||||
StatusItem { label: "PWR"; value: SystemStatus.power_w; unit: "W"; }
|
||||
StatusItem { label: "AVG"; value: SystemStatus.power_avg_w; unit: "W"; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use zbus::proxy;
|
||||
#[proxy(
|
||||
interface = "xyz.ljones.Anime",
|
||||
default_service = "xyz.ljones.Asusd",
|
||||
default_path = "/xyz/ljones"
|
||||
default_path = "/xyz/ljones/aura/anime"
|
||||
)]
|
||||
pub trait Anime {
|
||||
/// DeviceState method
|
||||
|
||||
@@ -253,8 +253,18 @@ impl FirmwareAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
pub enum FirmwareAttributeType {
|
||||
#[default]
|
||||
Immediate,
|
||||
Ppt,
|
||||
Gpu,
|
||||
Bios,
|
||||
}
|
||||
|
||||
macro_rules! define_attribute_getters {
|
||||
($($attr:ident),*) => {
|
||||
// Accept a list of attribute idents and an optional `types { .. }` block
|
||||
( $( $attr:ident ),* $(,)? $( ; types { $( $tattr:ident : $ptype:ident ),* $(,)? } )? ) => {
|
||||
impl FirmwareAttributes {
|
||||
$(
|
||||
pub fn $attr(&self) -> Option<&Attribute> {
|
||||
@@ -268,6 +278,17 @@ macro_rules! define_attribute_getters {
|
||||
});
|
||||
)*
|
||||
}
|
||||
|
||||
impl FirmwareAttribute {
|
||||
pub fn property_type(&self) -> FirmwareAttributeType {
|
||||
match <&str>::from(*self) {
|
||||
$(
|
||||
$( stringify!($tattr) => FirmwareAttributeType::$ptype, )*
|
||||
)?
|
||||
_ => FirmwareAttributeType::Immediate,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,6 +320,33 @@ define_attribute_getters!(
|
||||
gpu_mux_mode,
|
||||
mini_led_mode,
|
||||
screen_auto_brightness
|
||||
; types {
|
||||
ppt_pl1_spl: Ppt,
|
||||
ppt_pl2_sppt: Ppt,
|
||||
ppt_apu_sppt: Ppt,
|
||||
ppt_platform_sppt: Ppt,
|
||||
ppt_fppt: Ppt,
|
||||
nv_dynamic_boost: Ppt,
|
||||
nv_temp_target: Ppt,
|
||||
dgpu_base_tgp: Ppt,
|
||||
dgpu_tgp: Ppt,
|
||||
|
||||
gpu_mux_mode: Gpu,
|
||||
egpu_connected: Gpu,
|
||||
egpu_enable: Gpu,
|
||||
dgpu_disable: Gpu,
|
||||
|
||||
boot_sound: Bios,
|
||||
|
||||
mcu_powersave: Immediate,
|
||||
|
||||
screen_auto_brightness: Immediate,
|
||||
mini_led_mode: Immediate,
|
||||
panel_hd_mode: Immediate,
|
||||
panel_od: Immediate,
|
||||
|
||||
charge_mode: Immediate,
|
||||
}
|
||||
);
|
||||
|
||||
/// CamelCase names of the properties. Intended for use with DBUS
|
||||
@@ -346,33 +394,6 @@ pub enum FirmwareAttribute {
|
||||
PptEnabled = 24,
|
||||
None = 25,
|
||||
ScreenAutoBrightness = 26,
|
||||
KbdLedsAwake = 27,
|
||||
KbdLedsSleep = 28,
|
||||
KbdLedsBoot = 29,
|
||||
KbdLedsShutdown = 30,
|
||||
}
|
||||
|
||||
impl FirmwareAttribute {
|
||||
pub fn is_ppt(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
FirmwareAttribute::PptPl1Spl
|
||||
| FirmwareAttribute::PptPl2Sppt
|
||||
| FirmwareAttribute::PptPl3Fppt
|
||||
| FirmwareAttribute::PptFppt
|
||||
| FirmwareAttribute::PptApuSppt
|
||||
| FirmwareAttribute::PptPlatformSppt
|
||||
)
|
||||
}
|
||||
|
||||
pub fn is_dgpu(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
FirmwareAttribute::NvDynamicBoost
|
||||
| FirmwareAttribute::NvTempTarget
|
||||
| FirmwareAttribute::DgpuTgp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for FirmwareAttribute {
|
||||
@@ -394,10 +415,6 @@ impl From<&str> for FirmwareAttribute {
|
||||
"nv_tgp" => Self::DgpuTgp,
|
||||
"charge_mode" => Self::ChargeMode,
|
||||
"boot_sound" => Self::BootSound,
|
||||
"kbd_leds_awake" => Self::KbdLedsAwake,
|
||||
"kbd_leds_sleep" => Self::KbdLedsSleep,
|
||||
"kbd_leds_boot" => Self::KbdLedsBoot,
|
||||
"kbd_leds_shutdown" => Self::KbdLedsShutdown,
|
||||
"mcu_powersave" => Self::McuPowersave,
|
||||
"panel_overdrive" => Self::PanelOverdrive,
|
||||
"panel_hd_mode" => Self::PanelHdMode,
|
||||
@@ -443,10 +460,6 @@ impl From<FirmwareAttribute> for &str {
|
||||
FirmwareAttribute::DgpuDisable => "dgpu_disable",
|
||||
FirmwareAttribute::GpuMuxMode => "gpu_mux_mode",
|
||||
FirmwareAttribute::MiniLedMode => "mini_led_mode",
|
||||
FirmwareAttribute::KbdLedsAwake => "kbd_leds_awake",
|
||||
FirmwareAttribute::KbdLedsSleep => "kbd_leds_sleep",
|
||||
FirmwareAttribute::KbdLedsBoot => "kbd_leds_boot",
|
||||
FirmwareAttribute::KbdLedsShutdown => "kbd_leds_shutdown",
|
||||
FirmwareAttribute::PendingReboot => "pending_reboot",
|
||||
FirmwareAttribute::ScreenAutoBrightness => "screen_auto_brightness",
|
||||
FirmwareAttribute::None => "none",
|
||||
|
||||
1
rust-toolchain
Normal file
1
rust-toolchain
Normal file
@@ -0,0 +1 @@
|
||||
stable
|
||||
70
simulators/src/animatrix/map_g635l.rs
Normal file
70
simulators/src/animatrix/map_g635l.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
use super::Row;
|
||||
|
||||
// TODO: This is a placeholder for G635L map
|
||||
pub const G635L: [Row; 63] = [
|
||||
Row(0x01, 7, 32, 0),
|
||||
Row(0x01, 7 + 34, 32, 0),
|
||||
Row(0x01, 7 + 68, 32, 0),
|
||||
Row(0x01, 7 + 102, 32, 0), // 34 len
|
||||
Row(0x01, 7 + 136, 32, 0),
|
||||
Row(0x01, 7 + 170, 34, 0),
|
||||
Row(0x01, 7 + 204, 34, 0),
|
||||
Row(0x01, 7 + 238, 34, 0),
|
||||
Row(0x01, 7 + 272, 34, 0),
|
||||
Row(0x01, 7 + 306, 34, 0),
|
||||
Row(0x01, 7 + 340, 34, 0),
|
||||
Row(0x01, 7 + 374, 34, 0),
|
||||
Row(0x01, 7 + 408, 33, 1),
|
||||
Row(0x01, 7 + 441, 33, 1),
|
||||
Row(0x01, 7 + 474, 32, 2),
|
||||
Row(0x01, 7 + 506, 32, 2),
|
||||
Row(0x01, 7 + 538, 31, 3),
|
||||
Row(0x01, 7 + 569, 31, 3),
|
||||
Row(0x01, 7 + 600, 28, 4),
|
||||
//
|
||||
Row(0x74, 7 + 1, 3, 28 + 4), // adds to end of previous
|
||||
Row(0x74, 7 + 3, 30, 4),
|
||||
Row(0x74, 7 + 33, 29, 5),
|
||||
Row(0x74, 7 + 62, 29, 5),
|
||||
Row(0x74, 7 + 91, 28, 6),
|
||||
Row(0x74, 7 + 119, 28, 6),
|
||||
Row(0x74, 7 + 147, 27, 7),
|
||||
Row(0x74, 7 + 174, 27, 7),
|
||||
Row(0x74, 7 + 202, 26, 9),
|
||||
Row(0x74, 7 + 228, 26, 9),
|
||||
Row(0x74, 7 + 254, 25, 10),
|
||||
Row(0x74, 7 + 278, 25, 9), // WEIRD OFFSET
|
||||
Row(0x74, 7 + 303, 24, 10),
|
||||
Row(0x74, 7 + 327, 24, 10),
|
||||
Row(0x74, 7 + 351, 23, 11),
|
||||
Row(0x74, 7 + 374, 23, 11),
|
||||
Row(0x74, 7 + 397, 22, 12),
|
||||
Row(0x74, 7 + 419, 22, 12),
|
||||
Row(0x74, 7 + 441, 21, 13),
|
||||
Row(0x74, 7 + 462, 21, 13),
|
||||
Row(0x74, 7 + 483, 20, 14),
|
||||
Row(0x74, 7 + 503, 20, 14),
|
||||
Row(0x74, 7 + 523, 19, 15),
|
||||
Row(0x74, 7 + 542, 19, 15),
|
||||
Row(0x74, 7 + 561, 18, 16),
|
||||
Row(0x74, 7 + 579, 18, 16),
|
||||
Row(0x74, 7 + 597, 17, 17),
|
||||
Row(0x74, 7 + 614, 13, 17),
|
||||
//
|
||||
Row(0xe7, 7 + 1, 4, 13 + 18), // adds to end of previous
|
||||
Row(0xe7, 7 + 4, 16, 18),
|
||||
Row(0xe7, 7 + 20, 16, 18),
|
||||
Row(0xe7, 7 + 36, 15, 19),
|
||||
Row(0xe7, 7 + 51, 15, 19),
|
||||
Row(0xe7, 7 + 66, 14, 20),
|
||||
Row(0xe7, 7 + 80, 12, 20), // too long? 14
|
||||
Row(0xe7, 7 + 94, 13, 21),
|
||||
Row(0xe7, 7 + 107, 13, 21),
|
||||
Row(0xe7, 7 + 120, 12, 12), // Actual display end
|
||||
Row(0xe7, 7 + 132, 12, 22),
|
||||
Row(0xe7, 7 + 144, 11, 23),
|
||||
Row(0xe7, 7 + 155, 11, 23),
|
||||
Row(0xe7, 7 + 166, 10, 24),
|
||||
Row(0xe7, 7 + 176, 10, 24),
|
||||
Row(0xe7, 7 + 186, 9, 25),
|
||||
];
|
||||
74
simulators/src/animatrix/map_g835l.rs
Normal file
74
simulators/src/animatrix/map_g835l.rs
Normal file
@@ -0,0 +1,74 @@
|
||||
use super::Row;
|
||||
|
||||
// G835L layout: 68 rows (triangle + rectangle), 2 packets
|
||||
pub const G835L: [Row; 69] = [
|
||||
Row(0x01, 7, 0, 0),
|
||||
Row(0x01, 8, 0, 0),
|
||||
Row(0x01, 9, 1, 0),
|
||||
Row(0x01, 11, 1, 0),
|
||||
Row(0x01, 13, 2, 0),
|
||||
Row(0x01, 16, 2, 0),
|
||||
Row(0x01, 19, 3, 0),
|
||||
Row(0x01, 23, 3, 0),
|
||||
Row(0x01, 27, 4, 0),
|
||||
Row(0x01, 32, 4, 0),
|
||||
Row(0x01, 37, 5, 0),
|
||||
Row(0x01, 43, 5, 0),
|
||||
Row(0x01, 49, 6, 0),
|
||||
Row(0x01, 56, 6, 0),
|
||||
Row(0x01, 63, 7, 0),
|
||||
Row(0x01, 71, 7, 0),
|
||||
Row(0x01, 79, 8, 0),
|
||||
Row(0x01, 88, 8, 0),
|
||||
Row(0x01, 97, 9, 0),
|
||||
Row(0x01, 107, 9, 0),
|
||||
Row(0x01, 117, 10, 0),
|
||||
Row(0x01, 128, 10, 0),
|
||||
Row(0x01, 139, 11, 0),
|
||||
Row(0x01, 151, 11, 0),
|
||||
Row(0x01, 163, 12, 0),
|
||||
Row(0x01, 176, 12, 0),
|
||||
Row(0x01, 189, 13, 0),
|
||||
Row(0x01, 203, 13, 0),
|
||||
Row(0x01, 217, 14, 0),
|
||||
Row(0x01, 232, 14, 0),
|
||||
Row(0x01, 247, 14, 1),
|
||||
Row(0x01, 262, 14, 1),
|
||||
Row(0x01, 277, 14, 2),
|
||||
Row(0x01, 292, 14, 2),
|
||||
Row(0x01, 307, 14, 3),
|
||||
Row(0x01, 322, 14, 3),
|
||||
Row(0x01, 337, 14, 4),
|
||||
Row(0x01, 352, 14, 4),
|
||||
Row(0x01, 367, 14, 5),
|
||||
Row(0x01, 382, 14, 5),
|
||||
Row(0x01, 397, 14, 6),
|
||||
Row(0x01, 412, 14, 6),
|
||||
Row(0x01, 427, 14, 7),
|
||||
Row(0x01, 442, 14, 7),
|
||||
Row(0x01, 457, 14, 8),
|
||||
Row(0x01, 472, 14, 8),
|
||||
Row(0x01, 487, 14, 9),
|
||||
Row(0x01, 502, 14, 9),
|
||||
Row(0x01, 517, 14, 10),
|
||||
Row(0x01, 532, 14, 10),
|
||||
Row(0x01, 547, 14, 11),
|
||||
Row(0x01, 562, 14, 11),
|
||||
Row(0x01, 577, 14, 12),
|
||||
Row(0x01, 592, 14, 12),
|
||||
Row(0x01, 607, 14, 13),
|
||||
Row(0x01, 622, 11, 13),
|
||||
Row(0x74, 7, 2, 25),
|
||||
Row(0x74, 10, 14, 14),
|
||||
Row(0x74, 25, 14, 14),
|
||||
Row(0x74, 40, 14, 15),
|
||||
Row(0x74, 55, 14, 15),
|
||||
Row(0x74, 70, 14, 16),
|
||||
Row(0x74, 85, 14, 16),
|
||||
Row(0x74, 100, 14, 17),
|
||||
Row(0x74, 115, 14, 17),
|
||||
Row(0x74, 130, 14, 18),
|
||||
Row(0x74, 145, 14, 18),
|
||||
Row(0x74, 160, 14, 19),
|
||||
Row(0x74, 175, 14, 19),
|
||||
];
|
||||
@@ -1,9 +1,13 @@
|
||||
use rog_anime::AnimeType;
|
||||
|
||||
use self::map_g635l::G635L;
|
||||
use self::map_g835l::G835L;
|
||||
use self::map_ga401::GA401;
|
||||
use self::map_ga402::GA402;
|
||||
use self::map_gu604::GU604;
|
||||
|
||||
mod map_g635l;
|
||||
mod map_g835l;
|
||||
mod map_ga401;
|
||||
mod map_ga402;
|
||||
mod map_gu604;
|
||||
@@ -38,30 +42,18 @@ pub struct AniMatrix {
|
||||
|
||||
impl AniMatrix {
|
||||
pub fn new(model: AnimeType) -> Self {
|
||||
let led_shape = match model {
|
||||
AnimeType::GA401 => LedShape {
|
||||
vertical: 2,
|
||||
horizontal: 5,
|
||||
},
|
||||
AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => {
|
||||
LedShape {
|
||||
vertical: 2,
|
||||
horizontal: 5,
|
||||
}
|
||||
}
|
||||
AnimeType::GU604 => LedShape {
|
||||
vertical: 2,
|
||||
horizontal: 5,
|
||||
},
|
||||
let led_shape = LedShape {
|
||||
vertical: 2,
|
||||
horizontal: 5,
|
||||
};
|
||||
|
||||
// Do a hard mapping of each (derived from wireshardk captures)
|
||||
let rows = match model {
|
||||
AnimeType::GA401 => GA401.to_vec(),
|
||||
AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => {
|
||||
GA402.to_vec()
|
||||
}
|
||||
AnimeType::GA402 | AnimeType::Unsupported => GA402.to_vec(),
|
||||
AnimeType::GU604 => GU604.to_vec(),
|
||||
AnimeType::G635L => G635L.to_vec(),
|
||||
AnimeType::G835L => G835L.to_vec(),
|
||||
};
|
||||
|
||||
Self { rows, led_shape }
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::env;
|
||||
use std::error::Error;
|
||||
use std::str::FromStr;
|
||||
|
||||
use log::error;
|
||||
use rog_anime::usb::{PROD_ID, VENDOR_ID};
|
||||
use rog_anime::{AnimeType, USB_PREFIX2};
|
||||
use sdl2::event::Event;
|
||||
@@ -20,6 +19,7 @@ pub struct VirtAnimeMatrix {
|
||||
animatrix: AniMatrix,
|
||||
}
|
||||
|
||||
// TODO: This isn't working
|
||||
impl VirtAnimeMatrix {
|
||||
pub fn new(model: AnimeType) -> Self {
|
||||
VirtAnimeMatrix {
|
||||
@@ -86,8 +86,12 @@ impl VirtAnimeMatrix {
|
||||
]
|
||||
.to_vec(),
|
||||
})
|
||||
.map_err(|err| error!("Could not create virtual device: {:?}", err))
|
||||
.expect("Could not create virtual device"),
|
||||
.unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Could not create virtual device: {err:?}. \
|
||||
Try loading the uhid module and ensure you have the necessary permissions."
|
||||
)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +118,7 @@ impl VirtAnimeMatrix {
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() <= 1 {
|
||||
println!("Must supply arg, one of <GA401, GA402, GU604>");
|
||||
println!("Must supply arg, one of <GA401, GA402, GU604, G835L>");
|
||||
return Ok(());
|
||||
}
|
||||
let anime_type = AnimeType::from_str(&args[1])?;
|
||||
|
||||
Reference in New Issue
Block a user