mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
More updating to zbus 4.0.1
This commit is contained in:
2628
Cargo.lock
generated
2628
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
39
Cargo.toml
39
Cargo.toml
@@ -1,14 +1,39 @@
|
||||
[workspace]
|
||||
members = ["asusctl", "asusd", "asusd-user", "config-traits", "cpuctl", "dmi-id", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
|
||||
default-members = ["asusctl", "asusd", "asusd-user", "cpuctl", "rog-control-center"]
|
||||
members = [
|
||||
"asusctl",
|
||||
"asusd",
|
||||
"asusd-user",
|
||||
"config-traits",
|
||||
"cpuctl",
|
||||
"dmi-id",
|
||||
"rog-platform",
|
||||
"rog-dbus",
|
||||
"rog-anime",
|
||||
"rog-aura",
|
||||
"rog-profiles",
|
||||
"rog-control-center",
|
||||
"simulators",
|
||||
]
|
||||
default-members = [
|
||||
"asusctl",
|
||||
"asusd",
|
||||
"asusd-user",
|
||||
"cpuctl",
|
||||
"rog-control-center",
|
||||
]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "5.0.8"
|
||||
rust-version = "1.75"
|
||||
rust-version = "1.76"
|
||||
|
||||
[workspace.dependencies]
|
||||
tokio = { version = "^1.23.0", default-features = false, features = ["macros", "sync"]}
|
||||
tokio = { version = "^1.23.0", default-features = false, features = [
|
||||
"macros",
|
||||
"sync",
|
||||
"time",
|
||||
"rt",
|
||||
] }
|
||||
concat-idents = "^1.1"
|
||||
dirs = "^4.0"
|
||||
smol = "^1.3"
|
||||
@@ -39,7 +64,9 @@ gif = "^0.12.0"
|
||||
|
||||
versions = "4.1"
|
||||
|
||||
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", rev = "54176413b81189a3e4edbdc20a0b4f7e2e35c063", default-features = false, features = ["z"] }
|
||||
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", rev = "54176413b81189a3e4edbdc20a0b4f7e2e35c063", default-features = false, features = [
|
||||
"z",
|
||||
] }
|
||||
|
||||
[profile.release]
|
||||
# thin = 57s, asusd = 9.0M
|
||||
@@ -61,4 +88,4 @@ opt-level = 3
|
||||
[workspace.dependencies.cargo-husky]
|
||||
version = "1"
|
||||
default-features = false
|
||||
features = ["user-hooks"]
|
||||
features = ["user-hooks"]
|
||||
|
||||
@@ -16,12 +16,13 @@ dmi_id = { path = "../dmi-id" }
|
||||
|
||||
gumdrop.workspace = true
|
||||
toml.workspace = true
|
||||
zbus.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
gif.workspace = true
|
||||
tinybmp.workspace = true
|
||||
glam.workspace = true
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
tokio = { version = "^1.23.0", default-features = false, features = ["macros", "sync", "rt", "time"]}
|
||||
tokio.workspace = true
|
||||
|
||||
cargo-husky.workspace = true
|
||||
@@ -9,7 +9,7 @@ use rog_anime::error::AnimeError;
|
||||
use rog_anime::{ActionData, ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
||||
use rog_dbus::RogDbusClientBlocking;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use zbus::dbus_interface;
|
||||
use zbus::interface;
|
||||
use zbus::zvariant::{ObjectPath, Type};
|
||||
|
||||
use crate::config::ConfigAnime;
|
||||
@@ -175,7 +175,7 @@ impl CtrlAnime<'static> {
|
||||
// - Do actions
|
||||
// - Write config if required
|
||||
// - Unset inner_early_return
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlAnime<'static> {
|
||||
pub fn insert_asus_gif(
|
||||
&mut self,
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use zbus::dbus_proxy;
|
||||
use zbus::proxy;
|
||||
|
||||
#[dbus_proxy(
|
||||
#[proxy(
|
||||
interface = "org.asuslinux.Daemon",
|
||||
default_path = "/org/asuslinux/Anime"
|
||||
)]
|
||||
|
||||
@@ -10,7 +10,7 @@ use rog_anime::usb::{
|
||||
};
|
||||
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
||||
use zbus::export::futures_util::lock::Mutex;
|
||||
use zbus::{dbus_interface, CacheProperties, Connection, SignalContext};
|
||||
use zbus::{interface, CacheProperties, Connection, SignalContext};
|
||||
|
||||
use super::CtrlAnime;
|
||||
use crate::error::RogError;
|
||||
@@ -43,7 +43,7 @@ impl crate::ZbusRun for CtrlAnimeZbus {
|
||||
// None of these calls can be guarnateed to succeed unless we loop until okay
|
||||
// If the try_lock *does* succeed then any other thread trying to lock will not
|
||||
// grab it until we finish.
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlAnimeZbus {
|
||||
/// Writes a data stream of length. Will force system thread to exit until
|
||||
/// it is restarted
|
||||
@@ -58,14 +58,14 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
|
||||
/// Set base brightness level
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn brightness(&self) -> Brightness {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.display_brightness
|
||||
}
|
||||
|
||||
/// Set base brightness level
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_brightness(&self, brightness: Brightness) {
|
||||
let mut lock = self.0.lock().await;
|
||||
lock.node
|
||||
@@ -86,7 +86,7 @@ impl CtrlAnimeZbus {
|
||||
lock.config.write();
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn builtins_enabled(&self) -> bool {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.builtin_anims_enabled
|
||||
@@ -94,7 +94,7 @@ impl CtrlAnimeZbus {
|
||||
|
||||
/// Enable the builtin animations or not. This is quivalent to "Powersave
|
||||
/// animations" in Armory crate
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_builtins_enabled(&self, enabled: bool) {
|
||||
let mut lock = self.0.lock().await;
|
||||
lock.node
|
||||
@@ -125,14 +125,14 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn builtin_animations(&self) -> Animations {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.builtin_anims
|
||||
}
|
||||
|
||||
/// Set which builtin animation is used for each stage
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_builtin_animations(&self, settings: Animations) {
|
||||
let mut lock = self.0.lock().await;
|
||||
lock.node
|
||||
@@ -157,14 +157,14 @@ impl CtrlAnimeZbus {
|
||||
lock.config.write();
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn enable_display(&self) -> bool {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.display_enabled
|
||||
}
|
||||
|
||||
/// Set whether the AniMe is enabled at all
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_enable_display(&self, enabled: bool) {
|
||||
let mut lock = self.0.lock().await;
|
||||
lock.node
|
||||
@@ -177,14 +177,14 @@ impl CtrlAnimeZbus {
|
||||
lock.config.write();
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn off_when_unplugged(&self) -> bool {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.off_when_unplugged
|
||||
}
|
||||
|
||||
/// Set if to turn the AniMe Matrix off when external power is unplugged
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_off_when_unplugged(&self, enabled: bool) {
|
||||
let mut lock = self.0.lock().await;
|
||||
let manager = get_logind_manager().await;
|
||||
@@ -201,28 +201,28 @@ impl CtrlAnimeZbus {
|
||||
lock.config.write();
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn off_when_suspended(&self) -> bool {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.off_when_suspended
|
||||
}
|
||||
|
||||
/// Set if to turn the AniMe Matrix off when the laptop is suspended
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_off_when_suspended(&self, enabled: bool) {
|
||||
let mut lock = self.0.lock().await;
|
||||
lock.config.off_when_suspended = enabled;
|
||||
lock.config.write();
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn off_when_lid_closed(&self) -> bool {
|
||||
let lock = self.0.lock().await;
|
||||
lock.config.off_when_lid_closed
|
||||
}
|
||||
|
||||
/// Set if to turn the AniMe Matrix off when the lid is closed
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_off_when_lid_closed(&self, enabled: bool) {
|
||||
let mut lock = self.0.lock().await;
|
||||
let manager = get_logind_manager().await;
|
||||
@@ -250,7 +250,7 @@ impl CtrlAnimeZbus {
|
||||
}
|
||||
|
||||
/// Get the device state as stored by asusd
|
||||
// #[dbus_interface(property)]
|
||||
// #[zbus(property)]
|
||||
async fn device_state(&self) -> DeviceState {
|
||||
let lock = self.0.lock().await;
|
||||
DeviceState::from(&lock.config)
|
||||
|
||||
@@ -10,7 +10,7 @@ use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
||||
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
||||
use zbus::export::futures_util::StreamExt;
|
||||
use zbus::fdo::Error as ZbErr;
|
||||
use zbus::{dbus_interface, Connection, SignalContext};
|
||||
use zbus::{interface, Connection, SignalContext};
|
||||
|
||||
use super::controller::CtrlKbdLed;
|
||||
use crate::error::RogError;
|
||||
@@ -41,31 +41,31 @@ impl crate::ZbusRun for CtrlAuraZbus {
|
||||
/// The main interface for changing, reading, or notfying signals
|
||||
///
|
||||
/// LED commands are split between Brightness, Modes, Per-Key
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlAuraZbus {
|
||||
/// Return the device type for this Aura keyboard
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn device_type(&self) -> AuraDevice {
|
||||
let ctrl = self.0.lock().await;
|
||||
ctrl.led_prod
|
||||
}
|
||||
|
||||
/// Return the current LED brightness
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
|
||||
}
|
||||
|
||||
/// Set the keyboard brightness level (0-3)
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.sysfs_node.set_brightness(brightness.into())?)
|
||||
}
|
||||
|
||||
/// Total levels of brightness available
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn supported_brightness(&self) -> Vec<LedBrightness> {
|
||||
vec![
|
||||
LedBrightness::Off,
|
||||
@@ -76,26 +76,26 @@ impl CtrlAuraZbus {
|
||||
}
|
||||
|
||||
/// The total available modes
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn supported_basic_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.config.builtins.keys().cloned().collect())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn supported_basic_zones(&self) -> Result<Vec<AuraZone>, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.supported_data.basic_zones.clone())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn supported_power_zones(&self) -> Result<Vec<PowerZones>, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.supported_data.power_zones.clone())
|
||||
}
|
||||
|
||||
/// The current mode data
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
Ok(ctrl.config.current_mode)
|
||||
@@ -105,7 +105,7 @@ impl CtrlAuraZbus {
|
||||
///
|
||||
/// On success the aura config file is read to refresh cached values, then
|
||||
/// the effect is stored and config written to disk.
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
ctrl.config.current_mode = num;
|
||||
@@ -120,7 +120,7 @@ impl CtrlAuraZbus {
|
||||
}
|
||||
|
||||
/// The current mode data
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||
let ctrl = self.0.lock().await;
|
||||
let mode = ctrl.config.current_mode;
|
||||
@@ -134,7 +134,7 @@ impl CtrlAuraZbus {
|
||||
///
|
||||
/// On success the aura config file is read to refresh cached values, then
|
||||
/// the effect is stored and config written to disk.
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
|
||||
let mut ctrl = self.0.lock().await;
|
||||
if !ctrl.supported_data.basic_modes.contains(&effect.mode)
|
||||
@@ -164,7 +164,7 @@ impl CtrlAuraZbus {
|
||||
}
|
||||
|
||||
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn led_power(&self) -> AuraPowerDev {
|
||||
let ctrl = self.0.lock().await;
|
||||
AuraPowerDev::from(&ctrl.config.enabled)
|
||||
@@ -174,7 +174,7 @@ impl CtrlAuraZbus {
|
||||
/// `enabled` sets if the sent array should be disabled or enabled
|
||||
///
|
||||
/// For Modern ROG devices the "enabled" flag is ignored.
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_led_power(&mut self, options: (AuraPowerDev, bool)) -> Result<(), ZbErr> {
|
||||
let enabled = options.1;
|
||||
let options = options.0;
|
||||
|
||||
@@ -10,7 +10,7 @@ use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use zbus::{dbus_interface, Connection, SignalContext};
|
||||
use zbus::{interface, Connection, SignalContext};
|
||||
|
||||
use crate::error::RogError;
|
||||
use crate::{CtrlTask, CONFIG_PATH_BASE};
|
||||
@@ -123,7 +123,7 @@ impl CtrlFanCurveZbus {
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlFanCurveZbus {
|
||||
/// Set all fan curves for a profile to enabled status. Will also activate a
|
||||
/// fan curve if in the same profile mode
|
||||
|
||||
@@ -9,7 +9,7 @@ use rog_platform::platform::{GpuMode, Properties, RogPlatform, ThrottlePolicy};
|
||||
use rog_platform::power::AsusPower;
|
||||
use zbus::export::futures_util::lock::Mutex;
|
||||
use zbus::fdo::Error as FdoErr;
|
||||
use zbus::{dbus_interface, Connection, ObjectServer, SignalContext};
|
||||
use zbus::{interface, Connection, ObjectServer, SignalContext};
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_PATH};
|
||||
@@ -285,7 +285,7 @@ impl CtrlPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
#[interface(name = "org.asuslinux.Daemon")]
|
||||
impl CtrlPlatform {
|
||||
/// Returns a list of property names that this system supports
|
||||
async fn supported_properties(&self) -> Vec<Properties> {
|
||||
@@ -372,13 +372,13 @@ impl CtrlPlatform {
|
||||
interfaces
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
||||
let limit = self.power.get_charge_control_end_threshold()?;
|
||||
Ok(limit)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
||||
if !(20..=100).contains(&limit) {
|
||||
return Err(RogError::ChargeLimit(limit))?;
|
||||
@@ -388,7 +388,7 @@ impl CtrlPlatform {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
|
||||
self.platform.get_gpu_mux_mode().map_err(|err| {
|
||||
warn!("RogPlatform: set_gpu_mux_mode {err}");
|
||||
@@ -396,7 +396,7 @@ impl CtrlPlatform {
|
||||
})
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> {
|
||||
if self.platform.has_gpu_mux_mode() {
|
||||
self.set_gfx_mode(mode.into()).map_err(|err| {
|
||||
@@ -439,13 +439,13 @@ impl CtrlPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn throttle_thermal_policy(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
||||
.map(|n| n.into())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_thermal_policy(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
|
||||
// TODO: watch for external changes
|
||||
if self.platform.has_throttle_thermal_policy() {
|
||||
@@ -465,23 +465,23 @@ impl CtrlPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_policy_linked_epp(&self) -> Result<bool, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_policy_linked_epp)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_policy_linked_epp(&self, linked: bool) -> Result<(), zbus::Error> {
|
||||
self.config.lock().await.throttle_policy_linked_epp = linked;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_policy_on_battery(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_policy_on_battery)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_policy_on_battery(
|
||||
&mut self,
|
||||
policy: ThrottlePolicy,
|
||||
@@ -491,12 +491,12 @@ impl CtrlPlatform {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_policy_on_ac(&self) -> Result<ThrottlePolicy, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_policy_on_ac)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_policy_on_ac(&mut self, policy: ThrottlePolicy) -> Result<(), FdoErr> {
|
||||
self.config.lock().await.throttle_policy_on_ac = policy;
|
||||
self.set_throttle_thermal_policy(policy).await?;
|
||||
@@ -505,12 +505,12 @@ impl CtrlPlatform {
|
||||
|
||||
/// The energy_performance_preference for the quiet throttle/platform
|
||||
/// profile
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_quiet_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_quiet_epp)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_quiet_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||
self.config.lock().await.throttle_quiet_epp = epp;
|
||||
@@ -520,12 +520,12 @@ impl CtrlPlatform {
|
||||
|
||||
/// The energy_performance_preference for the balanced throttle/platform
|
||||
/// profile
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_balanced_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_balanced_epp)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_balanced_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||
self.config.lock().await.throttle_balanced_epp = epp;
|
||||
@@ -535,12 +535,12 @@ impl CtrlPlatform {
|
||||
|
||||
/// The energy_performance_preference for the performance throttle/platform
|
||||
/// profile
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn throttle_performance_epp(&self) -> Result<CPUEPP, FdoErr> {
|
||||
Ok(self.config.lock().await.throttle_performance_epp)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_throttle_performance_epp(&mut self, epp: CPUEPP) -> Result<(), FdoErr> {
|
||||
let change_pp = self.config.lock().await.throttle_policy_linked_epp;
|
||||
self.config.lock().await.throttle_performance_epp = epp;
|
||||
@@ -550,12 +550,12 @@ impl CtrlPlatform {
|
||||
|
||||
/// ***********************************************************************
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn post_animation_sound(&self) -> Result<bool, FdoErr> {
|
||||
platform_get_value!(self, post_animation_sound, "post_animation_sound")
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||
if self.platform.has_post_animation_sound() {
|
||||
self.platform.set_post_animation_sound(on).map_err(|err| {
|
||||
@@ -571,34 +571,34 @@ impl CtrlPlatform {
|
||||
|
||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||
/// internal config also.
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn panel_od(&self) -> Result<bool, FdoErr> {
|
||||
platform_get_value!(self, panel_od, "panel_od")
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
|
||||
platform_set_bool!(self, panel_od, "panel_od", overdrive)
|
||||
}
|
||||
|
||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||
/// internal config also.
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn mini_led_mode(&self) -> Result<bool, FdoErr> {
|
||||
platform_get_value!(self, mini_led_mode, "mini_led_mode")
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn dgpu_disable(&self) -> Result<bool, FdoErr> {
|
||||
platform_get_value!(self, dgpu_disable, "dgpu_disable")
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
fn egpu_enable(&self) -> Result<bool, FdoErr> {
|
||||
platform_get_value!(self, egpu_enable, "egpu_enable")
|
||||
}
|
||||
@@ -607,12 +607,12 @@ impl CtrlPlatform {
|
||||
/// Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
|
||||
/// Shown on Intel+Nvidia or AMD+Nvidia based systems:
|
||||
/// * min=5, max=250
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)
|
||||
}
|
||||
@@ -620,72 +620,72 @@ impl CtrlPlatform {
|
||||
/// Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
|
||||
/// on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems:
|
||||
/// * min=5, max=250
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, ppt_pl2_sppt, "ppt_pl2_sppt", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250)
|
||||
}
|
||||
|
||||
/// Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only:
|
||||
/// * min=5, max=250
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn ppt_fppt(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, ppt_fppt, "ppt_fppt", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250)
|
||||
}
|
||||
|
||||
/// Set the APU SPPT limit. Shown on full AMD systems only:
|
||||
/// * min=5, max=130
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn ppt_apu_sppt(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, ppt_apu_sppt, "ppt_apu_sppt", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130)
|
||||
}
|
||||
|
||||
/// Set the platform SPPT limit. Shown on full AMD systems only:
|
||||
/// * min=5, max=130
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn ppt_platform_sppt(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, ppt_platform_sppt, "ppt_platform_sppt", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130)
|
||||
}
|
||||
|
||||
/// Set the dynamic boost limit of the Nvidia dGPU:
|
||||
/// * min=5, max=25
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn nv_dynamic_boost(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, nv_dynamic_boost, "nv_dynamic_boost", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25)
|
||||
}
|
||||
|
||||
/// Set the target temperature limit of the Nvidia dGPU:
|
||||
/// * min=75, max=87
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn nv_temp_target(&self) -> Result<u8, FdoErr> {
|
||||
platform_get_value_if_some!(self, nv_temp_target, "nv_temp_target", 5)
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
#[zbus(property)]
|
||||
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||
platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87)
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
loop {
|
||||
// This is just a blocker to idle and ensure the reator reacts
|
||||
sleep(Duration::from_millis(1000)).await;
|
||||
connection.executor().tick().await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,15 +10,9 @@ edition = "2021"
|
||||
#mocking = []
|
||||
|
||||
[dependencies]
|
||||
# egui = "0.24.1"
|
||||
# eframe = "0.24.1"
|
||||
# egui_plot = "0.24.1"
|
||||
# Stuck on this revision due to crash issues on app close
|
||||
egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||
eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||
|
||||
libappindicator = "0.8" # Tray icon
|
||||
gtk = "0.16"
|
||||
libappindicator = "0.9" # Tray icon
|
||||
gtk = "0.18"
|
||||
|
||||
asusd = { path = "../asusd" }
|
||||
rog_anime = { path = "../rog-anime" }
|
||||
@@ -48,9 +42,18 @@ versions.workspace = true
|
||||
nix = "^0.26.1"
|
||||
tempfile = "3.3.0"
|
||||
|
||||
# [patch.crates-io]
|
||||
# egui = { git = "https://github.com/flukejones/egui" }
|
||||
# eframe = { git = "https://github.com/flukejones/egui" }
|
||||
i-slint-backend-selector = { git = "https://github.com/slint-ui/slint.git" }
|
||||
i-slint-core = { git = "https://github.com/slint-ui/slint.git" }
|
||||
i-slint-backend-winit = { git = "https://github.com/slint-ui/slint.git" }
|
||||
winit = "*"
|
||||
|
||||
[dependencies.slint]
|
||||
git = "https://github.com/slint-ui/slint.git"
|
||||
default-features = false
|
||||
features = ["std", "compat-1-0", "backend-winit-wayland", "backend-linuxkms", "renderer-femtovg"]
|
||||
|
||||
[build-dependencies.slint-build]
|
||||
git = "https://github.com/slint-ui/slint.git"
|
||||
|
||||
[dev-dependencies]
|
||||
cargo-husky.workspace = true
|
||||
39
rog-control-center/build.rs
Normal file
39
rog-control-center/build.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
// use std::fs::OpenOptions;
|
||||
// use std::io::Write;
|
||||
// use diter_protocol::ParameterDefinitions;
|
||||
// use ron::ser::PrettyConfig;
|
||||
|
||||
// const LOCALE_EN: &str =
|
||||
// include_str!("../data/localization/en/parameters.json"); const LOCALE_IT:
|
||||
// &str = include_str!("../data/localization/it/parameters.json");
|
||||
// const LOCALE_ZH: &str =
|
||||
// include_str!("../data/localization/zh/parameters.json");
|
||||
|
||||
// fn write_locales() {
|
||||
// let root = env!("CARGO_MANIFEST_DIR");
|
||||
// let mut path = PathBuf::from_str(root).unwrap();
|
||||
// path.push("src/locales.ron");
|
||||
// let mut file = OpenOptions::new();
|
||||
// file.truncate(true).create(true).write(true);
|
||||
|
||||
// let en: ParameterDefinitions = serde_json::from_str(LOCALE_EN).unwrap();
|
||||
// let mut writer = file.open(path).unwrap();
|
||||
|
||||
// let en = ron::ser::to_string_pretty(&en,
|
||||
// PrettyConfig::new().depth_limit(4)).unwrap(); writer.write_all(en.
|
||||
// to_string().as_bytes()).unwrap();
|
||||
|
||||
// // let it: ParameterDefinitions =
|
||||
// serde_json::from_str(LOCALE_IT).unwrap(); // let zh: ParameterDefinitions
|
||||
// = serde_json::from_str(LOCALE_ZH).unwrap(); }
|
||||
|
||||
fn main() {
|
||||
// write_locales();
|
||||
|
||||
let root = env!("CARGO_MANIFEST_DIR");
|
||||
let mut path = PathBuf::from_str(root).unwrap();
|
||||
path.push("ui/main_window.slint");
|
||||
slint_build::compile(path).unwrap();
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
use std::f64::consts::PI;
|
||||
use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use egui::{Button, RichText};
|
||||
use rog_aura::layouts::KeyLayout;
|
||||
use rog_platform::platform::Properties;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::error::Result;
|
||||
use crate::system_state::SystemState;
|
||||
use crate::{Page, RogDbusClientBlocking};
|
||||
|
||||
pub struct RogApp {
|
||||
pub page: Page,
|
||||
pub states: Arc<Mutex<SystemState>>,
|
||||
// TODO: can probably just open and read whenever
|
||||
pub config: Config,
|
||||
/// Oscillator in percentage
|
||||
pub oscillator1: Arc<AtomicU8>,
|
||||
pub oscillator2: Arc<AtomicU8>,
|
||||
pub oscillator3: Arc<AtomicU8>,
|
||||
/// Frequency of oscillation
|
||||
pub oscillator_freq: Arc<AtomicU8>,
|
||||
/// A toggle that toggles true/false when the oscillator reaches 0
|
||||
pub oscillator_toggle: Arc<AtomicBool>,
|
||||
pub supported_interfaces: Vec<String>,
|
||||
pub supported_properties: Vec<Properties>,
|
||||
}
|
||||
|
||||
impl RogApp {
|
||||
/// Called once before the first frame.
|
||||
pub fn new(
|
||||
config: Config,
|
||||
states: Arc<Mutex<SystemState>>,
|
||||
_cc: &eframe::CreationContext<'_>,
|
||||
) -> Result<Self> {
|
||||
let (dbus, _) = RogDbusClientBlocking::new()?;
|
||||
let supported_interfaces = dbus.proxies().platform().supported_interfaces()?;
|
||||
let supported_properties = dbus.proxies().platform().supported_properties()?;
|
||||
|
||||
// Set up an oscillator to run on a thread.
|
||||
// Helpful for visual effects like colour pulse.
|
||||
let oscillator1 = Arc::new(AtomicU8::new(0));
|
||||
let oscillator2 = Arc::new(AtomicU8::new(0));
|
||||
let oscillator3 = Arc::new(AtomicU8::new(0));
|
||||
|
||||
let oscillator1_1 = oscillator1.clone();
|
||||
let oscillator1_2 = oscillator2.clone();
|
||||
let oscillator1_3 = oscillator3.clone();
|
||||
|
||||
let oscillator_freq = Arc::new(AtomicU8::new(5));
|
||||
let oscillator_freq1 = oscillator_freq.clone();
|
||||
let oscillator_toggle = Arc::new(AtomicBool::new(false));
|
||||
let oscillator_toggle1 = oscillator_toggle.clone();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let started = Instant::now();
|
||||
let mut toggled = false;
|
||||
loop {
|
||||
let time = started.elapsed();
|
||||
// 32 = slow, 16 = med, 8 = fast
|
||||
let scale = oscillator_freq1.load(Ordering::SeqCst) as f64;
|
||||
let elapsed1 = (time.as_millis() as f64 + 333.0) / 10000.0;
|
||||
let elapsed2 = (time.as_millis() as f64 + 666.0) / 10000.0;
|
||||
let elapsed3 = (time.as_millis() as f64 + 999.0) / 10000.0;
|
||||
let tmp1 = ((scale * elapsed1 * PI).cos()).abs();
|
||||
let tmp2 = ((scale * 0.85 * elapsed2 * PI).cos()).abs();
|
||||
let tmp3 = ((scale * 0.7 * elapsed3 * PI).cos()).abs();
|
||||
if tmp1 <= 0.1 && !toggled {
|
||||
let s = oscillator_toggle1.load(Ordering::SeqCst);
|
||||
oscillator_toggle1.store(!s, Ordering::SeqCst);
|
||||
toggled = true;
|
||||
} else if tmp1 > 0.9 {
|
||||
toggled = false;
|
||||
}
|
||||
|
||||
let tmp1 = (255.0 * tmp1 * 100.0 / 255.0) as u8;
|
||||
let tmp2 = (255.0 * tmp2 * 100.0 / 255.0) as u8;
|
||||
let tmp3 = (255.0 * tmp3 * 100.0 / 255.0) as u8;
|
||||
|
||||
oscillator1_1.store(tmp1, Ordering::SeqCst);
|
||||
oscillator1_2.store(tmp2, Ordering::SeqCst);
|
||||
oscillator1_3.store(tmp3, Ordering::SeqCst);
|
||||
|
||||
std::thread::sleep(Duration::from_millis(33));
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Self {
|
||||
supported_interfaces,
|
||||
supported_properties,
|
||||
states,
|
||||
page: Page::System,
|
||||
config,
|
||||
oscillator1,
|
||||
oscillator2,
|
||||
oscillator3,
|
||||
oscillator_toggle,
|
||||
oscillator_freq,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for RogApp {
|
||||
/// Called each time the UI needs repainting, which may be many times per
|
||||
/// second. Put your widgets into a `SidePanel`, `TopPanel`,
|
||||
/// `CentralPanel`, `Window` or `Area`.
|
||||
fn update(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
|
||||
let states = self.states.clone();
|
||||
|
||||
if let Ok(mut states) = states.try_lock() {
|
||||
if states.app_should_update {
|
||||
states.app_should_update = false;
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcut typical display stuff
|
||||
if let Ok(mut states) = states.try_lock() {
|
||||
let layout_testing = states.aura_creation.layout_testing.clone();
|
||||
if let Some(path) = &layout_testing {
|
||||
let modified = path.metadata().unwrap().modified().unwrap();
|
||||
if states.aura_creation.layout_last_modified < modified {
|
||||
states.aura_creation.layout_last_modified = modified;
|
||||
// time to reload the config
|
||||
states.aura_creation.keyboard_layout = KeyLayout::from_file(path).unwrap();
|
||||
}
|
||||
self.aura_page(&mut states, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
self.top_bar(ctx, frame);
|
||||
self.side_panel(ctx);
|
||||
}
|
||||
let page = self.page;
|
||||
|
||||
let mut was_error = false;
|
||||
|
||||
if let Ok(mut states) = states.try_lock() {
|
||||
if let Some(err) = states.error.clone() {
|
||||
was_error = true;
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading(RichText::new("Error!").size(28.0));
|
||||
|
||||
ui.centered_and_justified(|ui| {
|
||||
ui.label(RichText::new(format!("The error was: {:?}", err)).size(22.0));
|
||||
});
|
||||
});
|
||||
egui::TopBottomPanel::bottom("error_bar")
|
||||
.default_height(26.0)
|
||||
.show(ctx, |ui| {
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
|
||||
if ui
|
||||
.add(Button::new(RichText::new("Okay").size(20.0)))
|
||||
.clicked()
|
||||
{
|
||||
states.error = None;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if !was_error {
|
||||
if let Ok(mut states) = states.try_lock() {
|
||||
match page {
|
||||
Page::AppSettings => self.app_settings_page(&mut states, ctx),
|
||||
Page::System => self.system_page(&mut states, ctx),
|
||||
Page::AuraEffects => self.aura_page(&mut states, ctx),
|
||||
Page::AnimeMatrix => self.anime_page(ctx),
|
||||
Page::FanCurves => self.fan_curve_page(&mut states, ctx),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ pub enum Error {
|
||||
XdgVars,
|
||||
Zbus(zbus::Error),
|
||||
Notification(notify_rust::error::Error),
|
||||
Eframe(eframe::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
@@ -25,7 +24,6 @@ impl fmt::Display for Error {
|
||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||
Error::Zbus(err) => write!(f, "Error: {}", err),
|
||||
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
||||
Error::Eframe(err) => write!(f, "Eframe Error: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,9 +53,3 @@ impl From<notify_rust::error::Error> for Error {
|
||||
Error::Notification(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<eframe::Error> for Error {
|
||||
fn from(err: eframe::Error) -> Self {
|
||||
Error::Eframe(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
pub mod app;
|
||||
// These lints need to be allowed due to the generated sources
|
||||
#![allow(clippy::redundant_clone, clippy::cmp_owned)]
|
||||
slint::include_modules!();
|
||||
|
||||
// Intentionally reexport slint so that GUI consumers don't need to add to
|
||||
// `Cargo.toml`
|
||||
use std::fs::{remove_dir_all, File, OpenOptions};
|
||||
use std::io::{Read, Write};
|
||||
use std::process::exit;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
pub use app::RogApp;
|
||||
pub use slint;
|
||||
|
||||
pub mod cli_options;
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
#[cfg(feature = "mocking")]
|
||||
pub mod mocking;
|
||||
pub mod pages;
|
||||
pub mod startup_error;
|
||||
pub mod system_state;
|
||||
pub mod tray;
|
||||
pub mod update_and_notify;
|
||||
pub mod widgets;
|
||||
|
||||
#[cfg(feature = "mocking")]
|
||||
pub use mocking::RogDbusClientBlocking;
|
||||
@@ -44,6 +46,7 @@ pub fn print_versions() {
|
||||
|
||||
pub const SHOWING_GUI: u8 = 1;
|
||||
pub const SHOW_GUI: u8 = 2;
|
||||
pub const QUIT_APP: u8 = 3;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Page {
|
||||
|
||||
@@ -1,30 +1,29 @@
|
||||
use std::borrow::BorrowMut;
|
||||
use std::env::args;
|
||||
use std::io::{Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::thread::{self, sleep, spawn};
|
||||
use std::time::Duration;
|
||||
|
||||
use eframe::HardwareAcceleration;
|
||||
use gumdrop::Options;
|
||||
use log::{debug, error, warn, LevelFilter};
|
||||
use log::{warn, LevelFilter};
|
||||
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
||||
use rog_aura::layouts::KeyLayout;
|
||||
use rog_control_center::cli_options::CliStart;
|
||||
use rog_control_center::config::Config;
|
||||
use rog_control_center::error::Result;
|
||||
use rog_control_center::startup_error::AppErrorShow;
|
||||
use rog_control_center::slint::ComponentHandle;
|
||||
use rog_control_center::system_state::SystemState;
|
||||
use rog_control_center::tray::init_tray;
|
||||
use rog_control_center::update_and_notify::{start_notifications, EnabledNotifications};
|
||||
use rog_control_center::{
|
||||
get_ipc_file, on_tmp_dir_exists, print_versions, RogApp, RogDbusClientBlocking, SHOWING_GUI,
|
||||
SHOW_GUI,
|
||||
get_ipc_file, on_tmp_dir_exists, print_versions, MainWindow, RogDbusClientBlocking, QUIT_APP,
|
||||
SHOWING_GUI, SHOW_GUI,
|
||||
};
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
||||
use tokio::runtime::Runtime;
|
||||
// use winit::monitor::VideoMode;
|
||||
// use winit::window::{Fullscreen, WindowLevel};
|
||||
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
const DATA_DIR: &str = "/usr/share/rog-gui/";
|
||||
@@ -61,44 +60,22 @@ fn main() -> Result<()> {
|
||||
// Enter the runtime so that `tokio::spawn` is available immediately.
|
||||
let _enter = rt.enter();
|
||||
|
||||
let native_options = eframe::NativeOptions {
|
||||
vsync: true,
|
||||
hardware_acceleration: HardwareAcceleration::Preferred,
|
||||
min_window_size: Some(egui::vec2(980.0, 670.0)),
|
||||
max_window_size: Some(egui::vec2(980.0, 670.0)),
|
||||
run_and_return: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let (dbus, _) = RogDbusClientBlocking::new()
|
||||
.map_err(|e| {
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||
)
|
||||
.map_err(|e| error!("{e}"))
|
||||
.ok();
|
||||
.map_err(|_| {
|
||||
// TODO: show an error window
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let supported_properties = match dbus.proxies().platform().supported_properties() {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||
)
|
||||
.map_err(|e| error!("{e}"))
|
||||
.ok();
|
||||
vec![]
|
||||
Err(_e) => {
|
||||
// TODO: show an error window
|
||||
Vec::default()
|
||||
}
|
||||
};
|
||||
|
||||
// Startup
|
||||
let mut config = Config::load()?;
|
||||
let running_in_bg = Arc::new(AtomicBool::new(config.startup_in_background));
|
||||
|
||||
if config.startup_in_background {
|
||||
config.run_in_background = true;
|
||||
@@ -179,6 +156,7 @@ fn main() -> Result<()> {
|
||||
Ok(tmp) => tmp,
|
||||
Err(_) => on_tmp_dir_exists().unwrap(),
|
||||
};
|
||||
dbg!();
|
||||
|
||||
let states = setup_page_state_and_notifs(
|
||||
layout_name,
|
||||
@@ -188,77 +166,107 @@ fn main() -> Result<()> {
|
||||
&config,
|
||||
)?;
|
||||
|
||||
if cli_parsed.board_name.is_some() || cli_parsed.layout_viewing {
|
||||
if let Ok(mut lock) = states.lock() {
|
||||
lock.run_in_bg = false;
|
||||
running_in_bg.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
if config.enable_tray_icon {
|
||||
init_tray(supported_properties, states.clone());
|
||||
}
|
||||
dbg!();
|
||||
|
||||
if let Ok(mut states) = states.lock() {
|
||||
// For some reason the gui is causing a broke pipe error on dbus send, so
|
||||
// replace it.
|
||||
let (asus_dbus, conn) =
|
||||
rog_dbus::RogDbusClientBlocking::new().expect("Couldn't connect to asusd");
|
||||
states.asus_dbus = asus_dbus;
|
||||
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
|
||||
states.gfx_dbus = gfx_dbus;
|
||||
}
|
||||
thread_local! { pub static UI: std::cell::RefCell<Option<MainWindow>> = Default::default()};
|
||||
i_slint_backend_selector::with_platform(|_| Ok(())).unwrap();
|
||||
|
||||
let mut bg_check_spawned = false;
|
||||
loop {
|
||||
if !running_in_bg.load(Ordering::Relaxed) {
|
||||
// blocks until window is closed
|
||||
let states = states.clone();
|
||||
let mut ipc_file = get_ipc_file()?;
|
||||
ipc_file.write_all(&[SHOWING_GUI])?;
|
||||
eframe::run_native(
|
||||
"ROG Control Center",
|
||||
native_options.clone(),
|
||||
Box::new(move |cc| {
|
||||
let cfg = Config::load().unwrap();
|
||||
let app = RogApp::new(cfg, states, cc);
|
||||
Box::new(app.unwrap())
|
||||
}),
|
||||
)?;
|
||||
dbg!();
|
||||
thread::spawn(move || {
|
||||
let mut buf = [0u8; 2];
|
||||
// blocks until it is read, typically the read will happen after a second
|
||||
// process writes to the IPC (so there is data to actually read)
|
||||
loop {
|
||||
get_ipc_file().unwrap().read_exact(&mut buf).unwrap();
|
||||
if buf[0] == SHOW_GUI {
|
||||
println!("Should show window {buf:?}");
|
||||
let mut ipc_file = get_ipc_file().unwrap();
|
||||
ipc_file.write_all(&[SHOWING_GUI, 0]).unwrap();
|
||||
|
||||
running_in_bg.store(true, Ordering::SeqCst);
|
||||
bg_check_spawned = false;
|
||||
}
|
||||
|
||||
if let Ok(lock) = states.try_lock() {
|
||||
if !lock.run_in_bg {
|
||||
break;
|
||||
}
|
||||
|
||||
if lock.run_in_bg && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
|
||||
let running_in_bg = running_in_bg.clone();
|
||||
thread::spawn(move || {
|
||||
let mut buf = [0u8; 4];
|
||||
// blocks until it is read, typically the read will happen after a second
|
||||
// process writes to the IPC (so there is data to actually read)
|
||||
loop {
|
||||
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
||||
running_in_bg.store(false, Ordering::Release);
|
||||
debug!("Wait thread got from tray {buf:#?}");
|
||||
break;
|
||||
let states = states.clone();
|
||||
i_slint_core::api::invoke_from_event_loop(move || {
|
||||
UI.with(|ui| {
|
||||
let mut ui = ui.borrow_mut();
|
||||
if let Some(ui) = ui.as_mut() {
|
||||
ui.window().show().unwrap();
|
||||
ui.window().on_close_requested(|| {
|
||||
let mut ipc_file = get_ipc_file().unwrap();
|
||||
ipc_file.write_all(&[0, 0]).unwrap();
|
||||
slint::CloseRequestResponse::HideWindow
|
||||
});
|
||||
} else {
|
||||
let newui = setup_window(states.clone());
|
||||
newui.window().show().unwrap();
|
||||
println!("New window should be showing now"); // but it isn't
|
||||
newui.window().on_close_requested(|| {
|
||||
let mut ipc_file = get_ipc_file().unwrap();
|
||||
ipc_file.write_all(&[0, 0]).unwrap();
|
||||
slint::CloseRequestResponse::HideWindow
|
||||
});
|
||||
ui.replace(newui);
|
||||
}
|
||||
}
|
||||
});
|
||||
bg_check_spawned = true;
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
} else if buf[1] == QUIT_APP {
|
||||
slint::quit_event_loop().unwrap();
|
||||
} else if buf[0] != SHOWING_GUI {
|
||||
println!("Should hide window {buf:?}");
|
||||
i_slint_core::api::invoke_from_event_loop(move || {
|
||||
UI.with(|ui| {
|
||||
let mut ui = ui.take();
|
||||
if let Some(ui) = ui.borrow_mut() {
|
||||
ui.window().hide().unwrap();
|
||||
}
|
||||
});
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Prevent hogging CPU
|
||||
thread::sleep(Duration::from_millis(500));
|
||||
}
|
||||
slint::run_event_loop_until_quit().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_window(_states: Arc<Mutex<SystemState>>) -> MainWindow {
|
||||
// slint::platform::set_platform(Box::new(i_slint_backend_winit::Backend::new().
|
||||
// unwrap())).unwrap();
|
||||
let ui = MainWindow::new().unwrap();
|
||||
// Example of how to do work in another thread.
|
||||
// The thread itself can keep its own state, and then update vars in the UI
|
||||
// when required.
|
||||
let ui_handle = ui.as_weak();
|
||||
spawn(move || loop {
|
||||
sleep(Duration::from_secs(1));
|
||||
// This is where the actual update happens
|
||||
ui_handle
|
||||
.upgrade_in_event_loop(move |handle| {
|
||||
// handle.set_counter(handle.get_counter() + 1);
|
||||
use i_slint_backend_winit::WinitWindowAccessor;
|
||||
handle
|
||||
.window()
|
||||
.with_winit_window(|winit_window: &winit::window::Window| {
|
||||
// winit_window.set_fullscreen(Some(Fullscreen::Borderless(None)));
|
||||
if !winit_window.has_focus() {
|
||||
// slint::quit_event_loop().unwrap();
|
||||
// handle.hide().unwrap();
|
||||
}
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
});
|
||||
|
||||
ui.on_exit_app(move || {
|
||||
slint::quit_event_loop().unwrap();
|
||||
});
|
||||
|
||||
ui
|
||||
}
|
||||
|
||||
fn setup_page_state_and_notifs(
|
||||
layout_testing: Option<PathBuf>,
|
||||
keyboard_layout: KeyLayout,
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
use crate::RogApp;
|
||||
|
||||
impl RogApp {
|
||||
pub fn anime_page(&mut self, ctx: &eframe::egui::Context) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.label("In progress");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
use crate::system_state::SystemState;
|
||||
use crate::widgets::app_settings;
|
||||
use crate::RogApp;
|
||||
|
||||
impl RogApp {
|
||||
pub fn app_settings_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
|
||||
let Self { config, .. } = self;
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
|
||||
let rect = ui.available_rect_before_wrap();
|
||||
egui::Grid::new("grid_of_bits")
|
||||
.min_col_width(rect.width() / 2.0)
|
||||
.show(ui, |ui| {
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
app_settings(config, states, ui);
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Duration;
|
||||
|
||||
use egui::Color32;
|
||||
use rog_aura::{AuraEffect, AuraModeNum};
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
use crate::widgets::{aura_modes_group, keyboard};
|
||||
use crate::RogApp;
|
||||
|
||||
impl RogApp {
|
||||
pub fn aura_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
|
||||
let Self {
|
||||
oscillator1,
|
||||
oscillator2,
|
||||
oscillator3,
|
||||
oscillator_freq,
|
||||
..
|
||||
} = self;
|
||||
|
||||
let red = oscillator1.load(Ordering::SeqCst) as u32;
|
||||
let green = oscillator2.load(Ordering::SeqCst) as u32;
|
||||
let blue = oscillator3.load(Ordering::SeqCst) as u32;
|
||||
states.aura.nudge_wave(red as u8, green as u8, blue as u8);
|
||||
// let osc = c.r * 255 / osc;
|
||||
let c1 = states
|
||||
.aura
|
||||
.modes
|
||||
.get(&states.aura.current_mode)
|
||||
.unwrap_or(&AuraEffect::default())
|
||||
.colour1;
|
||||
|
||||
let c2 = states
|
||||
.aura
|
||||
.modes
|
||||
.get(&states.aura.current_mode)
|
||||
.unwrap_or(&AuraEffect::default())
|
||||
.colour2;
|
||||
|
||||
let mut colour = Color32::from_rgb(c1.r, c1.g, c1.b);
|
||||
if states.aura.current_mode == AuraModeNum::Pulse {
|
||||
colour = Color32::from_rgb(
|
||||
(red * c1.r as u32 / 100) as u8,
|
||||
(red * c1.g as u32 / 100) as u8,
|
||||
(red * c1.b as u32 / 100) as u8,
|
||||
);
|
||||
} else if states.aura.current_mode == AuraModeNum::Breathe {
|
||||
if self.oscillator_toggle.load(Ordering::SeqCst) {
|
||||
colour = Color32::from_rgb(
|
||||
(red * c2.r as u32 / 100) as u8,
|
||||
(red * c2.g as u32 / 100) as u8,
|
||||
(red * c2.b as u32 / 100) as u8,
|
||||
);
|
||||
} else {
|
||||
colour = Color32::from_rgb(
|
||||
(red * c1.r as u32 / 100) as u8,
|
||||
(red * c1.g as u32 / 100) as u8,
|
||||
(red * c1.b as u32 / 100) as u8,
|
||||
);
|
||||
}
|
||||
} else if states.aura.current_mode == AuraModeNum::Strobe {
|
||||
colour = Color32::from_rgb(
|
||||
(red * 255 / 100) as u8,
|
||||
(green * 255 / 100) as u8,
|
||||
(blue * 255 / 100) as u8,
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: animation of colour changes/periods/blending
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
aura_modes_group(states, oscillator_freq, ui);
|
||||
keyboard(
|
||||
ui,
|
||||
&states.aura_creation.keyboard_layout,
|
||||
&mut states.aura,
|
||||
colour,
|
||||
);
|
||||
});
|
||||
|
||||
// Only do repaint request if on this page
|
||||
ctx.request_repaint_after(Duration::from_millis(33));
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
use egui::{RichText, Ui};
|
||||
use rog_platform::platform::ThrottlePolicy;
|
||||
|
||||
use crate::system_state::{FanCurvesState, SystemState};
|
||||
use crate::widgets::fan_graphs;
|
||||
use crate::{RogApp, RogDbusClientBlocking};
|
||||
|
||||
impl RogApp {
|
||||
pub fn fan_curve_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
|
||||
if let Some(mut throttle) = states.bios.throttle {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("Custom fan curves");
|
||||
Self::fan_curve(
|
||||
&mut throttle,
|
||||
&mut states.fan_curves,
|
||||
&states.asus_dbus,
|
||||
&mut states.error,
|
||||
ui,
|
||||
);
|
||||
|
||||
fan_graphs(
|
||||
&mut states.fan_curves,
|
||||
&states.asus_dbus,
|
||||
&mut states.error,
|
||||
ui,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn fan_curve(
|
||||
current: &mut ThrottlePolicy,
|
||||
curves: &mut FanCurvesState,
|
||||
dbus: &RogDbusClientBlocking<'_>,
|
||||
do_error: &mut Option<String>,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
ui.separator();
|
||||
|
||||
let mut changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Current profile: ");
|
||||
ui.label(RichText::new(format!("{}", current)).strong());
|
||||
});
|
||||
|
||||
ui.horizontal(|ui| {
|
||||
ui.label("Enabled fan-curves: ");
|
||||
let mut checked = false;
|
||||
let mut label = String::default();
|
||||
if let Some(curves) = curves.curves.get_mut(current) {
|
||||
for curve in curves.iter() {
|
||||
label.push_str(&<&str>::from(curve.fan).to_ascii_uppercase());
|
||||
label.push(' ');
|
||||
if curve.enabled {
|
||||
// TODO: it's possible to set just one fan to active
|
||||
checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ui
|
||||
.add(egui::Checkbox::new(
|
||||
&mut checked,
|
||||
RichText::new(label).strong(),
|
||||
))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.fan_curves()
|
||||
.set_fan_curves_enabled(*current, checked)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
if changed {
|
||||
let selected_profile = curves.show_curve;
|
||||
let selected_pu = curves.show_graph;
|
||||
|
||||
match FanCurvesState::new(dbus) {
|
||||
Ok(f) => *curves = f,
|
||||
Err(e) => *do_error = Some(e.to_string()),
|
||||
}
|
||||
|
||||
curves.show_curve = selected_profile;
|
||||
curves.show_graph = selected_pu;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
mod anime_page;
|
||||
mod app_settings;
|
||||
mod aura_page;
|
||||
mod fan_curve_page;
|
||||
mod system_page;
|
||||
@@ -1,50 +0,0 @@
|
||||
use crate::system_state::SystemState;
|
||||
use crate::widgets::{anime_power_group, aura_power_group, platform_profile, rog_bios_group};
|
||||
use crate::RogApp;
|
||||
|
||||
impl RogApp {
|
||||
pub fn system_page(&mut self, states: &mut SystemState, ctx: &eframe::egui::Context) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("Laptop settings");
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
ui.spacing_mut().item_spacing = egui::vec2(8.0, 10.0);
|
||||
let rect = ui.available_rect_before_wrap();
|
||||
egui::Grid::new("grid_of_bits")
|
||||
.min_col_width(rect.width() / 2.0)
|
||||
.show(ui, |ui| {
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
// if self.supported_interfaces {
|
||||
platform_profile(states, ui);
|
||||
// }
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
if self.supported_interfaces.contains(&"Aura".to_string()) {
|
||||
aura_power_group(states, ui);
|
||||
}
|
||||
});
|
||||
ui.end_row();
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
rog_bios_group(states, ui);
|
||||
});
|
||||
ui.end_row();
|
||||
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
if self.supported_interfaces.contains(&"Anime".to_string()) {
|
||||
anime_power_group(states, ui);
|
||||
}
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.separator();
|
||||
});
|
||||
ui.end_row();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
use egui::RichText;
|
||||
|
||||
pub struct AppErrorShow {
|
||||
error: String,
|
||||
}
|
||||
|
||||
impl AppErrorShow {
|
||||
pub fn new(error: String) -> Self {
|
||||
Self { error }
|
||||
}
|
||||
}
|
||||
|
||||
impl eframe::App for AppErrorShow {
|
||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("ROG ERROR");
|
||||
|
||||
ui.centered_and_justified(|ui| {
|
||||
ui.label(RichText::new(format!("The error was: {:?}", self.error)).size(22.0));
|
||||
});
|
||||
|
||||
// egui::TopBottomPanel::bottom("error_bar_2")
|
||||
// .default_height(26.0)
|
||||
// .show(ctx, |ui| {
|
||||
// ui.
|
||||
// with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
|
||||
// if ui
|
||||
// .add(Button::new(RichText::new("Okay").size(20.0)))
|
||||
// .clicked()
|
||||
// {
|
||||
// // frame.close();
|
||||
// // ui.close_menu();
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,11 @@ use std::path::PathBuf;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::SystemTime;
|
||||
|
||||
use egui::Vec2;
|
||||
use log::error;
|
||||
use rog_anime::{Animations, DeviceState};
|
||||
use rog_aura::aura_detection::PowerZones;
|
||||
use rog_aura::layouts::KeyLayout;
|
||||
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
||||
use rog_aura::usb::AuraPowerDev;
|
||||
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
|
||||
use rog_platform::platform::{GpuMode, ThrottlePolicy};
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::FanCurvePU;
|
||||
@@ -69,7 +67,7 @@ pub struct FanCurvesState {
|
||||
pub show_graph: FanCurvePU,
|
||||
pub curves: BTreeMap<ThrottlePolicy, Vec<CurveData>>,
|
||||
pub available_fans: HashSet<FanCurvePU>,
|
||||
pub drag_delta: Vec2,
|
||||
// pub drag_delta: Vec2,
|
||||
}
|
||||
|
||||
impl FanCurvesState {
|
||||
@@ -102,7 +100,7 @@ impl FanCurvesState {
|
||||
show_graph: FanCurvePU::CPU,
|
||||
curves,
|
||||
available_fans,
|
||||
drag_delta: Vec2::default(),
|
||||
// drag_delta: Vec2::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -112,9 +110,6 @@ pub struct AuraState {
|
||||
pub current_mode: AuraModeNum,
|
||||
pub modes: BTreeMap<AuraModeNum, AuraEffect>,
|
||||
pub enabled: AuraPowerDev,
|
||||
pub dev_type: AuraDevice,
|
||||
pub supported_basic_zones: Vec<AuraZone>,
|
||||
pub supported_power_zones: Vec<PowerZones>,
|
||||
/// Brightness from 0-3
|
||||
pub bright: LedBrightness,
|
||||
pub wave_red: [u8; 22],
|
||||
@@ -126,7 +121,10 @@ impl AuraState {
|
||||
pub fn new(layout: &KeyLayout, dbus: &RogDbusClientBlocking<'_>) -> Result<Self> {
|
||||
Ok(Self {
|
||||
current_mode: if !layout.basic_modes().is_empty() {
|
||||
dbus.proxies().aura().led_mode().unwrap_or_default()
|
||||
dbg!();
|
||||
let x = dbus.proxies().aura().led_mode().unwrap_or_default();
|
||||
dbg!();
|
||||
x
|
||||
} else {
|
||||
AuraModeNum::Static
|
||||
},
|
||||
@@ -137,18 +135,7 @@ impl AuraState {
|
||||
BTreeMap::new()
|
||||
},
|
||||
enabled: dbus.proxies().aura().led_power().unwrap_or_default(),
|
||||
supported_basic_zones: dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.supported_basic_zones()
|
||||
.unwrap_or_default(),
|
||||
supported_power_zones: dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.supported_power_zones()
|
||||
.unwrap_or_default(),
|
||||
dev_type: dbus.proxies().aura().device_type().unwrap_or_default(),
|
||||
bright: dbus.proxies().aura().brightness().unwrap_or_default(),
|
||||
bright: Default::default(),
|
||||
wave_red: [0u8; 22],
|
||||
wave_green: [0u8; 22],
|
||||
wave_blue: [0u8; 22],
|
||||
@@ -291,9 +278,9 @@ impl SystemState {
|
||||
tray_enabled: bool,
|
||||
run_in_bg: bool,
|
||||
) -> Result<Self> {
|
||||
dbg!();
|
||||
let (asus_dbus, conn) = RogDbusClientBlocking::new()?;
|
||||
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
|
||||
|
||||
dbg!();
|
||||
let aura = AuraState::new(&keyboard_layout, &asus_dbus)
|
||||
.map_err(|e| {
|
||||
let e = format!("Could not get AuraState state: {e}");
|
||||
@@ -301,6 +288,12 @@ impl SystemState {
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
dbg!();
|
||||
let gfx_dbus = GfxProxyBlocking::builder(&conn)
|
||||
.destination(":org.supergfxctl.Daemon")?
|
||||
.build()
|
||||
.expect("Couldn't connect to supergfxd");
|
||||
dbg!();
|
||||
Ok(Self {
|
||||
aura_creation: AuraCreation::new(layout_testing, keyboard_layout, keyboard_layouts),
|
||||
enabled_notifications,
|
||||
@@ -348,7 +341,9 @@ impl SystemState {
|
||||
impl Default for SystemState {
|
||||
fn default() -> Self {
|
||||
let (asus_dbus, conn) = RogDbusClientBlocking::new().expect("Couldn't connect to asusd");
|
||||
let gfx_dbus = GfxProxyBlocking::new(&conn).expect("Couldn't connect to supergfxd");
|
||||
let gfx_dbus = GfxProxyBlocking::builder(&conn)
|
||||
.build()
|
||||
.expect("Couldn't connect to supergfxd");
|
||||
|
||||
Self {
|
||||
aura_creation: AuraCreation {
|
||||
|
||||
@@ -86,7 +86,7 @@ impl ROGTray {
|
||||
e
|
||||
})?;
|
||||
|
||||
let gfx_proxy = GfxProxyBlocking::new(&conn).map_err(|e| {
|
||||
let gfx_proxy = GfxProxyBlocking::builder(&conn).build().map_err(|e| {
|
||||
error!("ROGTray: {e}");
|
||||
e
|
||||
})?;
|
||||
|
||||
@@ -98,7 +98,7 @@ macro_rules! recv_notif {
|
||||
log::error!("zbus signal: {}: {e}", stringify!($signal));
|
||||
e
|
||||
}).unwrap();
|
||||
let proxy = $proxy::new(&conn).await.map_err(|e| {
|
||||
let proxy = $proxy::builder(&conn).build().await.map_err(|e| {
|
||||
log::error!("zbus signal: {}: {e}", stringify!($signal));
|
||||
e
|
||||
}).unwrap();
|
||||
@@ -446,7 +446,8 @@ pub fn start_notifications(
|
||||
e
|
||||
})
|
||||
.unwrap();
|
||||
let proxy = SuperProxy::new(&conn)
|
||||
let proxy = SuperProxy::builder(&conn)
|
||||
.build()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
error!("zbus signal: receive_notify_action: {e}");
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
use egui::{RichText, Ui};
|
||||
use rog_anime::usb::Brightness;
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn anime_power_group(states: &mut SystemState, ui: &mut Ui) {
|
||||
ui.heading("AniMe Matrix Settings");
|
||||
ui.label("Options are incomplete. Awake + Boot should work");
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
let h = 16.0;
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Display brightness").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Display enabled").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Animations enabled").size(h));
|
||||
});
|
||||
// ui.horizontal_wrapped(|ui| {
|
||||
// ui.label(RichText::new("Sleep").size(h));
|
||||
// });
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
let slider =
|
||||
egui::Slider::new(&mut states.anime.display_brightness, 0..=3).step_by(1.0);
|
||||
if ui.add(slider).drag_released() {
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.anime()
|
||||
.set_brightness(Brightness::from(states.anime.display_brightness))
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui
|
||||
.checkbox(&mut states.anime.display_enabled, "Enable")
|
||||
.changed()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.anime()
|
||||
.set_enable_display(states.anime.display_enabled)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui
|
||||
.checkbox(&mut states.anime.builtin_anims_enabled, "Enable")
|
||||
.changed()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.anime()
|
||||
.set_builtins_enabled(states.anime.builtin_anims_enabled)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
// ui.horizontal_wrapped(|ui| {
|
||||
// if ui.checkbox(&mut states.anime.sleep, "Enable").changed() {
|
||||
// changed = true;
|
||||
// }
|
||||
// });
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
use egui::Ui;
|
||||
|
||||
use crate::config::Config;
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn app_settings(config: &mut Config, states: &mut SystemState, ui: &mut Ui) {
|
||||
ui.heading("App Settings");
|
||||
|
||||
let mut enabled_notifications = if let Ok(lock) = states.enabled_notifications.lock() {
|
||||
lock.clone()
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
|
||||
ui.label("Application settings");
|
||||
let app_changed = ui
|
||||
.checkbox(
|
||||
&mut config.enable_tray_icon,
|
||||
"Enable Tray Icon (restart required)",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(&mut config.run_in_background, "Run in Background")
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(&mut config.startup_in_background, "Startup Hidden")
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.all_enabled,
|
||||
"Enable Notifications",
|
||||
)
|
||||
.clicked();
|
||||
|
||||
// if ui.button("Quit").clicked() {
|
||||
// states.run_in_bg = false;
|
||||
// }
|
||||
|
||||
ui.label("Notification settings");
|
||||
let notif_changed = ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_notify_gfx_status,
|
||||
"Enable dGPU status notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_led_mode_data_changed,
|
||||
"Enable LED mode change notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_dgpu_disable_changed,
|
||||
"Enable dGPU disablement notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_egpu_enable_changed,
|
||||
"Enable eGPU enablement notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_notify_mains_online,
|
||||
"Enable mains (AC) power notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_charge_control_end_threshold_changed,
|
||||
"Enable charge threshold notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_throttle_thermal_policy_changed,
|
||||
"Enable profile change notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_panel_od_changed,
|
||||
"Enable panel overdrive notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_mini_led_mode_changed,
|
||||
"Enable MiniLED mode notification",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.checkbox(
|
||||
&mut enabled_notifications.receive_post_animation_sound_changed,
|
||||
"Enable BIOS post sound notification",
|
||||
)
|
||||
.clicked();
|
||||
|
||||
if app_changed || notif_changed {
|
||||
if let Ok(mut lock) = states.enabled_notifications.lock() {
|
||||
// Replace inner content before save
|
||||
*lock = enabled_notifications;
|
||||
|
||||
config
|
||||
.save(&lock)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
|
||||
states.tray_enabled = config.enable_tray_icon;
|
||||
states.run_in_bg = config.run_in_background;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
use std::sync::atomic::{AtomicU8, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use egui::{RichText, Ui};
|
||||
use rog_aura::layouts::KeyLayout;
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour, Speed};
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn aura_modes_group(states: &mut SystemState, freq: &mut Arc<AtomicU8>, ui: &mut Ui) {
|
||||
let mut changed = false;
|
||||
let mut selected = states.aura.current_mode;
|
||||
let allowed = AuraEffect::allowed_parameters(selected);
|
||||
|
||||
let SystemState { aura_creation, .. } = states;
|
||||
|
||||
let has_keyzones = aura_creation
|
||||
.keyboard_layout
|
||||
.basic_zones()
|
||||
.contains(&AuraZone::Key2);
|
||||
let has_logo = aura_creation
|
||||
.keyboard_layout
|
||||
.basic_zones()
|
||||
.contains(&AuraZone::Logo);
|
||||
let has_lightbar = aura_creation
|
||||
.keyboard_layout
|
||||
.basic_zones()
|
||||
.contains(&AuraZone::BarLeft)
|
||||
|| aura_creation
|
||||
.keyboard_layout
|
||||
.basic_zones()
|
||||
.contains(&AuraZone::BarRight);
|
||||
|
||||
if let Some(p) = aura_creation.layout_testing.as_ref() {
|
||||
ui.heading(format!("{p:?}"));
|
||||
} else {
|
||||
ui.heading("Aura modes");
|
||||
ui.label(
|
||||
"Please note that this section is incomplete and the displayed effects won't match \
|
||||
actual effect",
|
||||
);
|
||||
}
|
||||
let mut item = |a: AuraModeNum, ui: &mut Ui| {
|
||||
if ui
|
||||
.selectable_value(&mut selected, a, format!("{:?}", a))
|
||||
.clicked()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for a in states.aura.modes.keys() {
|
||||
item(*a, ui);
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(effect) = states.aura.modes.get_mut(&selected) {
|
||||
let mut zone_button = |a: AuraZone, ui: &mut Ui| {
|
||||
ui.selectable_value(&mut effect.zone, a, format!("{:?}", a));
|
||||
};
|
||||
let mut speed_button = |a: Speed, ui: &mut Ui| -> bool {
|
||||
if ui
|
||||
.selectable_value(&mut effect.speed, a, format!("{:?}", a))
|
||||
.clicked()
|
||||
{
|
||||
let val = match effect.speed {
|
||||
Speed::Low => 6,
|
||||
Speed::Med => 8,
|
||||
Speed::High => 10,
|
||||
};
|
||||
freq.store(val, Ordering::SeqCst);
|
||||
return true;
|
||||
}
|
||||
false
|
||||
};
|
||||
let mut dir_button = |a: rog_aura::Direction, ui: &mut Ui| -> bool {
|
||||
ui.selectable_value(&mut effect.direction, a, format!("{:?}", a))
|
||||
.clicked()
|
||||
};
|
||||
|
||||
let mut c1: [u8; 3] = effect.colour1.into();
|
||||
let mut c2: [u8; 3] = effect.colour2.into();
|
||||
|
||||
ui.separator();
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
let h = 16.0;
|
||||
ui.set_row_height(22.0);
|
||||
ui.add_enabled_ui(allowed.zone, |ui| {
|
||||
if has_keyzones || has_lightbar || has_logo {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Zone").size(h));
|
||||
});
|
||||
}
|
||||
});
|
||||
ui.add_enabled_ui(allowed.colour1, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Colour 1").size(h));
|
||||
});
|
||||
});
|
||||
ui.add_enabled_ui(allowed.colour2, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Colour 2").size(h));
|
||||
});
|
||||
});
|
||||
ui.add_enabled_ui(allowed.speed, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.set_enabled(allowed.speed);
|
||||
ui.label(RichText::new("Speed").size(h));
|
||||
});
|
||||
});
|
||||
ui.add_enabled_ui(allowed.direction, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.set_enabled(allowed.direction);
|
||||
ui.label(RichText::new("Direction").size(h));
|
||||
});
|
||||
});
|
||||
ui.set_enabled(true);
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
ui.add_enabled_ui(allowed.zone, |ui| {
|
||||
if has_keyzones || has_lightbar || has_logo {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
zone_button(AuraZone::None, ui);
|
||||
if has_keyzones {
|
||||
zone_button(AuraZone::Key1, ui);
|
||||
zone_button(AuraZone::Key2, ui);
|
||||
zone_button(AuraZone::Key3, ui);
|
||||
zone_button(AuraZone::Key4, ui);
|
||||
}
|
||||
if has_logo {
|
||||
zone_button(AuraZone::Logo, ui);
|
||||
}
|
||||
if has_lightbar {
|
||||
zone_button(AuraZone::BarLeft, ui);
|
||||
zone_button(AuraZone::BarRight, ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ui.add_enabled_ui(allowed.colour1, |ui| {
|
||||
if egui::color_picker::color_edit_button_srgb(ui, &mut c1).changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
ui.add_enabled_ui(allowed.colour2, |ui| {
|
||||
if egui::color_picker::color_edit_button_srgb(ui, &mut c2).changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
ui.add_enabled_ui(allowed.speed, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if speed_button(Speed::Low, ui)
|
||||
|| speed_button(Speed::Med, ui)
|
||||
|| speed_button(Speed::High, ui)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ui.add_enabled_ui(allowed.direction, |ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if dir_button(rog_aura::Direction::Left, ui)
|
||||
|| dir_button(rog_aura::Direction::Down, ui)
|
||||
|| dir_button(rog_aura::Direction::Right, ui)
|
||||
|| dir_button(rog_aura::Direction::Up, ui)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
effect.colour1 = Colour::from(&c1);
|
||||
effect.colour2 = Colour::from(&c2);
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
|
||||
// if ui.add(egui::Button::new("Cancel")).clicked() {
|
||||
// match AuraState::new(&aura_creation.keyboard_layout, &states.asus_dbus) {
|
||||
// Ok(a) => states.aura.modes = a.modes,
|
||||
// Err(e) => states.error = Some(e.to_string()),
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ui.add(egui::Button::new("Apply")).clicked() {
|
||||
// changed = true;
|
||||
// }
|
||||
|
||||
if aura_creation.layout_testing.is_some() {
|
||||
if ui.add(egui::Button::new("Next layout")).clicked() {
|
||||
if aura_creation.keyboard_layout_index < aura_creation.keyboard_layouts.len() - 1 {
|
||||
aura_creation.keyboard_layout_index += 1;
|
||||
}
|
||||
aura_creation.layout_testing = Some(
|
||||
aura_creation.keyboard_layouts[aura_creation.keyboard_layout_index].clone(),
|
||||
);
|
||||
aura_creation.keyboard_layout =
|
||||
KeyLayout::from_file(aura_creation.layout_testing.as_ref().unwrap().as_path())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
if ui.add(egui::Button::new("Prev layout")).clicked() {
|
||||
if aura_creation.keyboard_layout_index > 0 {
|
||||
aura_creation.keyboard_layout_index -= 1;
|
||||
}
|
||||
aura_creation.layout_testing = Some(
|
||||
aura_creation.keyboard_layouts[aura_creation.keyboard_layout_index].clone(),
|
||||
);
|
||||
aura_creation.keyboard_layout =
|
||||
KeyLayout::from_file(aura_creation.layout_testing.as_ref().unwrap().as_path())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if changed {
|
||||
states.aura.current_mode = selected;
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.set_led_mode_data(states.aura.modes.get(&selected).unwrap().clone())
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
@@ -1,266 +0,0 @@
|
||||
use egui::{RichText, Ui};
|
||||
use rog_aura::power::{AuraPower, KbAuraPowerState};
|
||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn aura_power_group(states: &mut SystemState, ui: &mut Ui) {
|
||||
ui.heading("Keyboard LED power settings");
|
||||
|
||||
if states.aura.dev_type.is_old_style() || states.aura.dev_type.is_tuf_style() {
|
||||
aura_power1(states, ui);
|
||||
} else if states.aura.dev_type.is_new_style() {
|
||||
aura_power2(states, ui);
|
||||
}
|
||||
}
|
||||
|
||||
fn aura_power1(states: &mut SystemState, ui: &mut Ui) {
|
||||
let enabled_states = &mut states.aura.enabled;
|
||||
let mut boot = enabled_states.old_rog.contains(&AuraDevRog1::Boot);
|
||||
let mut sleep = enabled_states.old_rog.contains(&AuraDevRog1::Sleep);
|
||||
let mut keyboard = enabled_states.old_rog.contains(&AuraDevRog1::Keyboard);
|
||||
let mut lightbar = enabled_states.old_rog.contains(&AuraDevRog1::Lightbar);
|
||||
if states.aura.dev_type == AuraDevice::Tuf {
|
||||
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
||||
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
||||
keyboard = enabled_states.tuf.contains(&AuraDevTuf::Awake);
|
||||
}
|
||||
let mut changed = false;
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
let h = 16.0;
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Boot").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Awake").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Sleep").size(h));
|
||||
});
|
||||
// if supported.keyboard_led.brightness_set {
|
||||
// ui.horizontal_wrapped(|ui| {
|
||||
// ui.label(RichText::new("Brightness").size(h));
|
||||
// });
|
||||
// }
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(&mut boot, "Enable").changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.toggle_value(&mut keyboard, "Keyboard").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if !states.aura.supported_basic_zones.is_empty()
|
||||
&& ui.toggle_value(&mut lightbar, "Lightbar").changed()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(&mut sleep, "Enable").changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
// We currently don't have a watch for system changes here
|
||||
// if supported.keyboard_led.brightness_set {
|
||||
// if ui
|
||||
// .add(egui::Slider::new(
|
||||
// &mut states.aura.bright,
|
||||
// 0..=3,
|
||||
// ))
|
||||
// .changed()
|
||||
// {
|
||||
// let bright = LedBrightness::from(states.aura.bright as
|
||||
// u32); dbus.proxies()
|
||||
// .led()
|
||||
// .set_brightness(bright)
|
||||
// .map_err(|err| {
|
||||
// states.error = Some(err.to_string());
|
||||
// })
|
||||
// .ok();
|
||||
// }
|
||||
// }
|
||||
});
|
||||
});
|
||||
|
||||
if changed {
|
||||
if states.aura.dev_type == AuraDevice::Tuf {
|
||||
let mut enabled = Vec::new();
|
||||
let mut disabled = Vec::new();
|
||||
|
||||
let mut modify_tuf = |b: bool, a: AuraDevTuf| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.tuf.contains(&a) {
|
||||
enabled_states.tuf.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.tuf.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.tuf.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.tuf.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
modify_tuf(boot, AuraDevTuf::Boot);
|
||||
modify_tuf(sleep, AuraDevTuf::Sleep);
|
||||
modify_tuf(keyboard, AuraDevTuf::Awake);
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDevTuf>| {
|
||||
let options = AuraPowerDev {
|
||||
tuf: data,
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.set_led_power((options, enable))
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(true, enabled);
|
||||
send(false, disabled);
|
||||
} else {
|
||||
let mut enabled = Vec::new();
|
||||
let mut disabled = Vec::new();
|
||||
|
||||
let mut modify_x1866 = |b: bool, a: AuraDevRog1| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.old_rog.contains(&a) {
|
||||
enabled_states.old_rog.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.old_rog.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.old_rog.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.old_rog.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
modify_x1866(boot, AuraDevRog1::Boot);
|
||||
modify_x1866(sleep, AuraDevRog1::Sleep);
|
||||
modify_x1866(keyboard, AuraDevRog1::Keyboard);
|
||||
if !states.aura.supported_basic_zones.is_empty() {
|
||||
modify_x1866(lightbar, AuraDevRog1::Lightbar);
|
||||
}
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDevRog1>| {
|
||||
let options = AuraPowerDev {
|
||||
old_rog: data,
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.set_led_power((options, enable))
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(true, enabled);
|
||||
send(false, disabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn aura_power2(states: &mut SystemState, ui: &mut Ui) {
|
||||
let AuraPower {
|
||||
keyboard,
|
||||
logo,
|
||||
lightbar,
|
||||
lid,
|
||||
rear_glow,
|
||||
} = &mut states.aura.enabled.rog;
|
||||
|
||||
const LABELS: [&str; 4] = ["Boot", "Awake", "Sleep", "Shutdown"];
|
||||
|
||||
let mut changed = false;
|
||||
let mut item = |power: &mut KbAuraPowerState, ui: &mut Ui| {
|
||||
ui.vertical(|ui| {
|
||||
if states.aura.supported_power_zones.contains(&power.zone) {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new(format!("{:?}", power.zone)).size(14.0));
|
||||
});
|
||||
if ui.checkbox(&mut power.boot, LABELS[0]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.awake, LABELS[1]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.sleep, LABELS[2]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
if ui.checkbox(&mut power.shutdown, LABELS[3]).changed() {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
item(lid, ui);
|
||||
item(logo, ui);
|
||||
item(keyboard, ui);
|
||||
item(lightbar, ui);
|
||||
item(rear_glow, ui);
|
||||
});
|
||||
|
||||
if changed {
|
||||
let mut send = |enable: bool, data: AuraPower| {
|
||||
let options = AuraPowerDev {
|
||||
rog: data,
|
||||
..Default::default()
|
||||
};
|
||||
// build data to send
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.aura()
|
||||
.set_led_power((options, enable))
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(
|
||||
true,
|
||||
AuraPower {
|
||||
keyboard: *keyboard,
|
||||
logo: *logo,
|
||||
lightbar: *lightbar,
|
||||
lid: *lid,
|
||||
rear_glow: *rear_glow,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,208 +0,0 @@
|
||||
use egui::plot::{Line, Plot, Points};
|
||||
use egui::Ui;
|
||||
use rog_platform::platform::ThrottlePolicy;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::FanCurvePU;
|
||||
|
||||
use crate::system_state::FanCurvesState;
|
||||
use crate::RogDbusClientBlocking;
|
||||
|
||||
pub fn fan_graphs(
|
||||
curves: &mut FanCurvesState,
|
||||
dbus: &RogDbusClientBlocking<'_>,
|
||||
do_error: &mut Option<String>,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
if curves.available_fans.is_empty() {
|
||||
return; // TODO:
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
let mut item = |profile: ThrottlePolicy, ui: &mut Ui| {
|
||||
ui.group(|ui| {
|
||||
if ui
|
||||
.selectable_value(&mut curves.show_curve, profile, format!("{profile:?}"))
|
||||
.clicked()
|
||||
{
|
||||
dbus.proxies()
|
||||
.platform()
|
||||
.set_throttle_thermal_policy(profile)
|
||||
.ok();
|
||||
}
|
||||
ui.add_enabled_ui(curves.show_curve == profile, |ui| {
|
||||
if curves.available_fans.contains(&FanCurvePU::CPU) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
}
|
||||
if curves.available_fans.contains(&FanCurvePU::GPU) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
}
|
||||
if curves.available_fans.contains(&FanCurvePU::MID) {
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::MID,
|
||||
format!("{:?}", FanCurvePU::MID),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for a in &curves.curves {
|
||||
item(*a.0, ui);
|
||||
}
|
||||
});
|
||||
|
||||
let curve = curves.curves.get_mut(&curves.show_curve).unwrap();
|
||||
|
||||
let mut data = &mut CurveData::default();
|
||||
for c in curve {
|
||||
if c.fan == curves.show_graph {
|
||||
data = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let mut points: Vec<[f64; 2]> = data
|
||||
.temp
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, x)| {
|
||||
let x = *x as f64;
|
||||
let y = ((data.pwm[idx] as u32) * 100 / 255) as f64;
|
||||
[x, y]
|
||||
})
|
||||
.collect();
|
||||
|
||||
for i in 0..points.len() - 1 {
|
||||
if i > 0 && i < points.len() - 1 {
|
||||
if points[i][0] < points[i - 1][0] {
|
||||
points[i][0] = points[i - 1][0] + 1.0;
|
||||
data.temp[i] = points[i - 1][0] as u8;
|
||||
}
|
||||
if points[i][0] >= points[i + 1][0] {
|
||||
points[i + 1][0] = points[i][0] + 1.0;
|
||||
data.temp[i + 1] = points[i][0] as u8;
|
||||
}
|
||||
if points[i][1] < points[i - 1][1] {
|
||||
points[i][1] = points[i - 1][1] + 1.0;
|
||||
data.pwm[i] = (points[i - 1][1] * 255.0 / 100.0 + 1.0).floor() as u8;
|
||||
}
|
||||
if points[i][1] >= points[i + 1][1] {
|
||||
points[i + 1][1] = points[i][1] + 1.0;
|
||||
data.pwm[i + 1] = (points[i][1] * 255.0 / 100.0 + 1.0).floor() as u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let line = Line::new(points.clone()).width(2.0);
|
||||
let points = Points::new(points).radius(3.0);
|
||||
|
||||
Plot::new("fan_curves")
|
||||
.view_aspect(1.666)
|
||||
// .center_x_axis(true)
|
||||
// .center_y_axis(true)
|
||||
.include_x(0.0)
|
||||
.include_x(104.0)
|
||||
.include_y(0.0)
|
||||
.include_y(106.0)
|
||||
.allow_scroll(false)
|
||||
.allow_drag(false)
|
||||
.allow_boxed_zoom(false)
|
||||
// .x_axis_formatter(|d, _r| format!("{}", d))
|
||||
// .y_axis_formatter(|d, _r| format!("{:.*}%", 1, d))
|
||||
.label_formatter(|name, value| {
|
||||
if !name.is_empty() {
|
||||
format!("{}: {:.*}%", name, 1, value.y)
|
||||
} else {
|
||||
format!("Temp {}c\nFan {:.*}%", value.x as u8, 1, value.y)
|
||||
}
|
||||
})
|
||||
.show(ui, |plot_ui| {
|
||||
if plot_ui.plot_hovered() {
|
||||
let mut idx = 0;
|
||||
|
||||
if let Some(point) = plot_ui.pointer_coordinate() {
|
||||
let mut x: i32 = point.x as i32;
|
||||
for (i, n) in data.temp.iter().enumerate() {
|
||||
let tmp = x.min((point.x as i32 - *n as i32).abs());
|
||||
if tmp < x {
|
||||
x = tmp;
|
||||
idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if plot_ui.plot_clicked() {
|
||||
data.temp[idx] = point.x as u8;
|
||||
data.pwm[idx] = (point.y * 255.0 / 100.0) as u8;
|
||||
} else {
|
||||
let drag = plot_ui.pointer_coordinate_drag_delta();
|
||||
if drag.length_sq() != 0.0 {
|
||||
data.temp[idx] = (point.x as f32 + drag.x) as u8;
|
||||
data.pwm[idx] = ((point.y as f32 + drag.y) * 255.0 / 100.0) as u8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plot_ui.line(line);
|
||||
plot_ui.points(points);
|
||||
});
|
||||
|
||||
let mut set = false;
|
||||
let mut clear = false;
|
||||
let mut reset = false;
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
|
||||
set = ui.add(egui::Button::new("Apply Profile")).clicked();
|
||||
clear = ui.add(egui::Button::new("Clear Profile Changes")).clicked();
|
||||
reset = ui.add(egui::Button::new("Factory Reset Profile")).clicked();
|
||||
});
|
||||
|
||||
if set {
|
||||
dbus.proxies()
|
||||
.fan_curves()
|
||||
.set_fan_curve(curves.show_curve, data.clone())
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
if clear {
|
||||
if let Ok(curve) = dbus
|
||||
.proxies()
|
||||
.fan_curves()
|
||||
.fan_curve_data(curves.show_curve)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
{
|
||||
if let Some(value) = curves.curves.get_mut(&curves.show_curve) {
|
||||
*value = curve;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if reset {
|
||||
dbus.proxies()
|
||||
.fan_curves()
|
||||
.reset_profile_curves(curves.show_curve)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
|
||||
match FanCurvesState::new(dbus) {
|
||||
Ok(f) => *curves = f,
|
||||
Err(e) => *do_error = Some(e.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
use egui::{Color32, Pos2};
|
||||
use rog_aura::advanced::LedCode;
|
||||
use rog_aura::layouts::{KeyLayout, KeyShape};
|
||||
use rog_aura::{AdvancedAuraType, AuraModeNum};
|
||||
|
||||
use crate::system_state::AuraState;
|
||||
|
||||
const SCALE: f32 = 2.0;
|
||||
|
||||
// TODO:
|
||||
// - Multizone: draw regions? While iterating keys check if located in one of
|
||||
// the 4 regions and mark
|
||||
// - Tab for advanced effects
|
||||
// - Keys need to select colour themselves
|
||||
|
||||
pub fn keyboard(
|
||||
ui: &mut egui::Ui,
|
||||
keyboard_layout: &KeyLayout,
|
||||
states: &mut AuraState,
|
||||
colour: Color32,
|
||||
) {
|
||||
let (keyboard_is_multizoned, keyboard_width, keyboard_is_per_key) =
|
||||
match keyboard_layout.advanced_type() {
|
||||
AdvancedAuraType::PerKey => (false, 0.0, true),
|
||||
AdvancedAuraType::None => (false, keyboard_layout.max_width(), false),
|
||||
AdvancedAuraType::Zoned(zones) => {
|
||||
let width = if let Some(row) = keyboard_layout.rows_ref().get(2) {
|
||||
row.width()
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
(!zones.contains(&LedCode::SingleZone), width, false)
|
||||
}
|
||||
};
|
||||
let mut start_pos = None;
|
||||
|
||||
let y = ui.spacing().interact_size.y;
|
||||
let this_size = ui.available_size();
|
||||
let keys_width = keyboard_layout.max_width() * SCALE * y;
|
||||
let keys_height = keyboard_layout.max_height() * SCALE * y;
|
||||
let keyboard_height = keyboard_layout.keyboard_height() * SCALE;
|
||||
let x_start = (this_size.x - keys_width) / SCALE;
|
||||
let y_start = (this_size.y - keys_height) / SCALE;
|
||||
|
||||
// Initial colour states
|
||||
let mut input_colour = colour;
|
||||
let mut key_colour = colour;
|
||||
if states.current_mode == AuraModeNum::Rainbow && !keyboard_is_per_key {
|
||||
key_colour = Color32::from_rgb(
|
||||
(states.wave_red[0] as u32 * 255 / 100) as u8,
|
||||
(states.wave_green[0] as u32 * 255 / 100) as u8,
|
||||
(states.wave_blue[0] as u32 * 255 / 100) as u8,
|
||||
);
|
||||
}
|
||||
|
||||
ui.spacing_mut().item_spacing = egui::vec2(0.0, 0.0);
|
||||
blank(ui, 0.0, y_start / y);
|
||||
|
||||
for row in keyboard_layout.rows() {
|
||||
ui.horizontal_top(|ui| {
|
||||
blank(ui, x_start / y, 0.0);
|
||||
for (i, key) in row.row().enumerate() {
|
||||
// For per-key rainbow which cascades across
|
||||
if states.current_mode == AuraModeNum::Rainbow && keyboard_is_per_key
|
||||
|| key.0.is_lightbar_zone()
|
||||
{
|
||||
key_colour = Color32::from_rgb(
|
||||
(states.wave_red[i] as u32 * 255 / 100) as u8,
|
||||
(states.wave_green[i] as u32 * 255 / 100) as u8,
|
||||
(states.wave_blue[i] as u32 * 255 / 100) as u8,
|
||||
);
|
||||
}
|
||||
|
||||
if (keyboard_is_multizoned && !key.0.is_lightbar_zone())
|
||||
&& states.current_mode == AuraModeNum::Rainbow
|
||||
{
|
||||
input_colour = key_colour;
|
||||
key_colour = Color32::TRANSPARENT;
|
||||
}
|
||||
|
||||
let label = <&str>::from(key.0);
|
||||
let mut shape = key.1.clone();
|
||||
shape.scale(SCALE);
|
||||
|
||||
match shape {
|
||||
KeyShape::Led {
|
||||
width,
|
||||
height,
|
||||
pad_left,
|
||||
pad_right,
|
||||
pad_top,
|
||||
pad_bottom,
|
||||
} => {
|
||||
let (pos, response) = key_shape(
|
||||
ui, key_colour, width, height, pad_left, pad_right, pad_top, pad_bottom,
|
||||
);
|
||||
if start_pos.is_none() {
|
||||
start_pos = Some(pos);
|
||||
} else if let Some(old_pos) = start_pos.as_mut() {
|
||||
if !key.0.is_lightbar_zone() {
|
||||
if pos.x < old_pos.x {
|
||||
old_pos.x = pos.x;
|
||||
}
|
||||
if pos.y < old_pos.y {
|
||||
old_pos.y = pos.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
if response.on_hover_text(label).clicked() && keyboard_is_per_key {
|
||||
// TODO: set an effect on the LedCode
|
||||
}
|
||||
}
|
||||
KeyShape::Blank { width, height } => {
|
||||
blank(ui, width, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if keyboard_is_multizoned {
|
||||
let zone_width = keyboard_width * SCALE / 4.0 - 0.1;
|
||||
for n in 0..4 {
|
||||
if states.current_mode == AuraModeNum::Rainbow {
|
||||
input_colour = Color32::from_rgba_unmultiplied(
|
||||
(states.wave_red[n] as u32 * 255 / 100) as u8,
|
||||
(states.wave_green[n] as u32 * 255 / 100) as u8,
|
||||
(states.wave_blue[n] as u32 * 255 / 100) as u8,
|
||||
70,
|
||||
);
|
||||
}
|
||||
if let Some(mut pos) = start_pos {
|
||||
pos.x += n as f32 * zone_width * y;
|
||||
let response = zone_shape(ui, input_colour, pos, zone_width, keyboard_height);
|
||||
let label = format!("Zone {}", 1 + n);
|
||||
if response.on_hover_text(label).clicked() {
|
||||
// TODO: set an effect on the zone
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn key_shape(
|
||||
ui: &mut egui::Ui,
|
||||
colour: Color32,
|
||||
width: f32,
|
||||
height: f32,
|
||||
pad_left: f32,
|
||||
pad_right: f32,
|
||||
pad_top: f32,
|
||||
pad_bottom: f32,
|
||||
) -> (egui::Pos2, egui::Response) {
|
||||
// First, get some space
|
||||
let y = ui.spacing().interact_size.y;
|
||||
let desired_size = y * egui::vec2(width + pad_left + pad_right, height + pad_top + pad_bottom);
|
||||
let (mut rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
|
||||
// rect = rect.shrink(3.0);
|
||||
if response.clicked() {
|
||||
response.mark_changed();
|
||||
}
|
||||
response.widget_info(|| {
|
||||
egui::WidgetInfo::selected(egui::WidgetType::Checkbox, response.clicked(), "")
|
||||
});
|
||||
|
||||
if ui.is_rect_visible(rect) {
|
||||
// Now set the actual visible rect
|
||||
let visuals = ui.style().interact_selectable(&response, true);
|
||||
let size = y * egui::vec2(width, height);
|
||||
rect.set_width(size.x);
|
||||
rect.set_height(size.y);
|
||||
let center = Pos2::new(
|
||||
rect.center().x + pad_left * y,
|
||||
rect.center().y + pad_top * y,
|
||||
);
|
||||
rect.set_center(center);
|
||||
// let rect = rect.expand(visuals.expansion);
|
||||
ui.painter().rect(rect, 0.1, colour, visuals.fg_stroke);
|
||||
}
|
||||
|
||||
(rect.left_top(), response)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn zone_shape(
|
||||
ui: &mut egui::Ui,
|
||||
mut colour: Color32,
|
||||
pos: Pos2,
|
||||
width: f32,
|
||||
height: f32,
|
||||
) -> egui::Response {
|
||||
// First, get some space
|
||||
let y = ui.spacing().interact_size.y;
|
||||
let desired_size = y * egui::vec2(width, height);
|
||||
let rect = egui::Rect::from_min_size(pos, desired_size);
|
||||
let mut response = ui.allocate_rect(rect, egui::Sense::click());
|
||||
// rect = rect.shrink(3.0);
|
||||
if response.clicked() {
|
||||
response.mark_changed();
|
||||
}
|
||||
response.widget_info(|| {
|
||||
egui::WidgetInfo::selected(egui::WidgetType::Checkbox, response.clicked(), "")
|
||||
});
|
||||
|
||||
if ui.is_rect_visible(rect) {
|
||||
// Now set the actual visible rect
|
||||
let visuals = ui.style().interact_selectable(&response, true);
|
||||
// let rect = rect.expand(visuals.expansion);
|
||||
colour[3] = 20;
|
||||
ui.painter().rect(rect, 0.1, colour, visuals.fg_stroke);
|
||||
}
|
||||
|
||||
response
|
||||
}
|
||||
|
||||
fn blank(ui: &mut egui::Ui, ux: f32, uy: f32) {
|
||||
let desired_size = ui.spacing().interact_size.y * egui::vec2(ux, uy);
|
||||
ui.allocate_exact_size(desired_size, egui::Sense::click());
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
mod anime_power;
|
||||
mod app_settings;
|
||||
mod aura_modes;
|
||||
mod aura_power;
|
||||
mod fan_graph;
|
||||
mod keyboard_layout;
|
||||
mod rog_bios;
|
||||
mod side_panel;
|
||||
mod top_bar;
|
||||
|
||||
pub use anime_power::*;
|
||||
pub use app_settings::*;
|
||||
pub use aura_modes::*;
|
||||
pub use aura_power::*;
|
||||
pub use fan_graph::*;
|
||||
pub use keyboard_layout::*;
|
||||
pub use rog_bios::*;
|
||||
@@ -1,153 +0,0 @@
|
||||
use egui::Ui;
|
||||
use rog_platform::platform::{GpuMode, ThrottlePolicy};
|
||||
|
||||
use crate::system_state::SystemState;
|
||||
|
||||
pub fn platform_profile(states: &mut SystemState, ui: &mut Ui) {
|
||||
if let Some(mut throttle) = states.bios.throttle {
|
||||
ui.heading("Platform profile");
|
||||
|
||||
let mut item = |p: ThrottlePolicy, ui: &mut Ui| {
|
||||
if ui
|
||||
.selectable_value(&mut throttle, p, format!("{p:?}"))
|
||||
.clicked()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_throttle_thermal_policy(throttle)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for a in ThrottlePolicy::list() {
|
||||
item(a, ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rog_bios_group(states: &mut SystemState, ui: &mut Ui) {
|
||||
ui.heading("Bios options");
|
||||
|
||||
if let Some(mut limit) = states.bios.charge_limit {
|
||||
let slider = egui::Slider::new(&mut limit, 20..=100)
|
||||
.text("Charging limit")
|
||||
.step_by(1.0);
|
||||
if ui.add(slider).drag_released() {
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_charge_control_end_threshold(limit)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut sound) = states.bios.post_sound {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(&mut sound, "POST sound"))
|
||||
.changed()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_post_animation_sound(sound)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut overdrive) = states.bios.panel_overdrive {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(&mut overdrive, "Panel overdrive"))
|
||||
.changed()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_panel_od(overdrive)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut mini_led_mode) = states.bios.mini_led_mode {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(&mut mini_led_mode, "MiniLED backlight"))
|
||||
.changed()
|
||||
{
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_mini_led_mode(mini_led_mode)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut gpu_mux_mode) = states.bios.gpu_mux_mode {
|
||||
let mut changed = false;
|
||||
|
||||
let mut reboot_required = false;
|
||||
if let Ok(mode) = states.asus_dbus.proxies().platform().gpu_mux_mode() {
|
||||
reboot_required = GpuMode::from(mode) != gpu_mux_mode;
|
||||
}
|
||||
|
||||
ui.group(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
ui.horizontal_wrapped(|ui| ui.label("GPU MUX mode"));
|
||||
ui.horizontal_wrapped(|ui| ui.label("NOTE: Value does not change until rebooted"));
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
changed = ui
|
||||
.selectable_value(
|
||||
&mut gpu_mux_mode,
|
||||
GpuMode::Discrete,
|
||||
"Dedicated (Ultimate)",
|
||||
)
|
||||
.clicked()
|
||||
|| ui
|
||||
.selectable_value(
|
||||
&mut gpu_mux_mode,
|
||||
GpuMode::Optimus,
|
||||
"Optimus (Hybrid)",
|
||||
)
|
||||
.clicked();
|
||||
});
|
||||
|
||||
if reboot_required {
|
||||
ui.horizontal_wrapped(|ui| ui.heading("REBOOT REQUIRED"));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if changed {
|
||||
states
|
||||
.asus_dbus
|
||||
.proxies()
|
||||
.platform()
|
||||
.set_gpu_mux_mode(gpu_mux_mode)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
use crate::{Page, RogApp};
|
||||
|
||||
impl RogApp {
|
||||
pub fn side_panel(&mut self, ctx: &eframe::egui::Context) {
|
||||
egui::SidePanel::left("side_panel")
|
||||
.resizable(false)
|
||||
.default_width(60.0) // TODO: set size to match icon buttons when done
|
||||
.show(ctx, |ui| {
|
||||
let Self { page, .. } = self;
|
||||
|
||||
ui.heading("Functions");
|
||||
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::System, "System Settings")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::System;
|
||||
}
|
||||
|
||||
if self.supported_interfaces.contains(&"FanCurves".to_owned()) {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::FanCurves, "Fan Curves")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::FanCurves;
|
||||
}
|
||||
}
|
||||
|
||||
if self.supported_interfaces.contains(&"Aura".to_owned()) {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::AuraEffects, "Keyboard Aura")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::AuraEffects;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Anime page is not complete
|
||||
if self.supported_interfaces.contains(&"Anime".to_owned()) {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::AnimeMatrix, "AniMe Matrix")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::AnimeMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::AppSettings, "App Settings")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::AppSettings;
|
||||
}
|
||||
|
||||
ui.with_layout(egui::Layout::bottom_up(egui::Align::LEFT), |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 0.0;
|
||||
ui.label("Source code ");
|
||||
ui.hyperlink_to(
|
||||
"rog-gui.",
|
||||
"https://gitlab.com/asus-linux/asusctl/-/tree/main/rog-control-center",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
use egui::{vec2, Align2, Button, FontId, Id, Rect, RichText, Sense, Vec2};
|
||||
|
||||
use crate::{RogApp, VERSION};
|
||||
|
||||
impl RogApp {
|
||||
pub fn top_bar(&mut self, ctx: &eframe::egui::Context, frame: &mut eframe::Frame) {
|
||||
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
|
||||
// The top panel is often a good place for a menu bar:
|
||||
egui::menu::bar(ui, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
self.dark_light_mode_buttons(ui);
|
||||
egui::warn_if_debug_build(ui);
|
||||
});
|
||||
|
||||
// Drag area
|
||||
let text_color = ctx.style().visuals.text_color();
|
||||
let mut titlebar_rect = ui.available_rect_before_wrap();
|
||||
titlebar_rect.max.x -= titlebar_rect.height();
|
||||
if ui
|
||||
.interact(titlebar_rect, Id::new("title_bar"), Sense::drag())
|
||||
.drag_started()
|
||||
{
|
||||
frame.drag_window();
|
||||
}
|
||||
|
||||
let height = titlebar_rect.height();
|
||||
|
||||
// Paint the title:
|
||||
ui.painter().text(
|
||||
titlebar_rect.right_top() + vec2(0.0, height / 2.0),
|
||||
Align2::RIGHT_CENTER,
|
||||
format!("v{}", VERSION),
|
||||
FontId::proportional(height - 2.0),
|
||||
text_color,
|
||||
);
|
||||
// Add the close button:
|
||||
let close_response = ui.put(
|
||||
Rect::from_min_size(titlebar_rect.right_top(), Vec2::splat(height)),
|
||||
Button::new(RichText::new("❌").size(height - 4.0)).frame(false),
|
||||
);
|
||||
if close_response.clicked() {
|
||||
frame.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn dark_light_mode_buttons(&mut self, ui: &mut egui::Ui) {
|
||||
let load_from_cfg = self.config.dark_mode != ui.ctx().style().visuals.dark_mode;
|
||||
|
||||
if ui
|
||||
.add(egui::SelectableLabel::new(
|
||||
!self.config.dark_mode,
|
||||
"☀ Light",
|
||||
))
|
||||
.clicked()
|
||||
|| (load_from_cfg && !self.config.dark_mode)
|
||||
{
|
||||
ui.ctx().set_visuals(egui::Visuals::light());
|
||||
}
|
||||
if ui
|
||||
.add(egui::SelectableLabel::new(self.config.dark_mode, "🌙 Dark"))
|
||||
.clicked()
|
||||
|| (load_from_cfg && self.config.dark_mode)
|
||||
{
|
||||
ui.ctx().set_visuals(egui::Visuals::dark());
|
||||
}
|
||||
|
||||
let applied_dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||
|
||||
if self.config.dark_mode != applied_dark_mode {
|
||||
self.config.dark_mode = applied_dark_mode;
|
||||
let tmp = self.config.enabled_notifications.clone();
|
||||
self.config.save(&tmp).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
246
rog-control-center/ui/common_widgets.slint
Normal file
246
rog-control-center/ui/common_widgets.slint
Normal file
@@ -0,0 +1,246 @@
|
||||
import { VerticalBox , StandardButton, Button} from "std-widgets.slint";
|
||||
import { Theme } from "globals.slint";
|
||||
|
||||
export component SquareImageButton inherits Rectangle {
|
||||
// if (AppConsts.sdfsdf.length < 0): Rectangle { background: red; }
|
||||
|
||||
callback clicked;
|
||||
in-out property <image> img;
|
||||
border-radius: 7px;
|
||||
border-width: 2px;
|
||||
border-color: Theme.control-outline;
|
||||
background: Theme.image-button-background;
|
||||
touch := TouchArea {
|
||||
clicked => {
|
||||
root.clicked();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
height: 90%;
|
||||
width: 90%;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
source <=> root.img;
|
||||
image-fit: contain;
|
||||
// colorize: Theme.control-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
export component RoundImageButton inherits Rectangle {
|
||||
callback clicked;
|
||||
in-out property <image> img;
|
||||
in property <length> size;
|
||||
width: self.size;
|
||||
height: self.size;
|
||||
border-radius: root.width / 2;
|
||||
border-width: 6px;
|
||||
border-color: Theme.control-outline;
|
||||
background: Theme.image-button-background;
|
||||
touch := TouchArea {
|
||||
clicked => {
|
||||
root.clicked();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
height: 60%;
|
||||
width: 60%;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
source <=> root.img;
|
||||
image-fit: contain;
|
||||
// colorize: Theme.control-secondary;
|
||||
}
|
||||
}
|
||||
|
||||
export component SquareCharButton inherits Rectangle {
|
||||
callback clicked;
|
||||
in-out property <string> char;
|
||||
border-radius: 7px;
|
||||
border-width: 2px;
|
||||
border-color: Theme.control-outline;
|
||||
background: Theme.image-button-background;
|
||||
touch := TouchArea {
|
||||
clicked => {
|
||||
root.clicked();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
// height: 90%;
|
||||
// width: 90%;
|
||||
x: (parent.width - self.width) / 2;
|
||||
y: (parent.height - self.height) / 2;
|
||||
text: char;
|
||||
font-size: 28px;
|
||||
font-weight: 900;
|
||||
horizontal-alignment: center;
|
||||
vertical-alignment: center;
|
||||
color: Theme.control-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
// A variable bar that can be single or double ended
|
||||
export component ValueBar inherits Rectangle {
|
||||
in property <float> value: 0.0;
|
||||
in property <float> min: 0.0;
|
||||
in property <float> max: 1.0;
|
||||
function percentage(min: float, max: float, value: float) -> float{
|
||||
if (min < 0.0 && max > 0.0) {
|
||||
// do a percentage of each half as 0-50%
|
||||
if (value >= max + min) {
|
||||
return (value - (max + min) / 2) / (max - min);
|
||||
|
||||
}
|
||||
return 0.50 - (value - (min - max) / 2) / (max - min);
|
||||
|
||||
}
|
||||
return (value - min) / (max - min);
|
||||
|
||||
}
|
||||
|
||||
function set_x(min: float, max: float, value: float, width: length) -> length{
|
||||
if (min < 0.0 && max > 0.0) {
|
||||
if (value < max + min) {
|
||||
return width / 2 - width * (percentage(min, max, value));
|
||||
|
||||
}
|
||||
return width / 2;
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border-radius: 3px;
|
||||
background: Theme.neutral-box;
|
||||
Rectangle {
|
||||
x: set_x(root.min, root.max, root.value, root.width);
|
||||
width: parent.x + parent.width * percentage(root.min, root.max, root.value);
|
||||
border-radius: parent.border-radius;
|
||||
background: Theme.control-secondary;
|
||||
}
|
||||
|
||||
Text {
|
||||
vertical-alignment: center;
|
||||
horizontal-alignment: center;
|
||||
text: root.value;
|
||||
font-size: root.height;
|
||||
font-weight: 900;
|
||||
color: Theme.control-foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Single direction spinbox
|
||||
export component SpinBoxUni inherits Rectangle {
|
||||
in-out property <int> value;
|
||||
in property <int> minimum;
|
||||
in property <int> maximum: 100;
|
||||
height: 32px;
|
||||
HorizontalLayout {
|
||||
spacing: 12px;
|
||||
padding: 0;
|
||||
SquareCharButton {
|
||||
width: root.height - parent.padding * 2;
|
||||
char: "-";
|
||||
clicked => {
|
||||
if (root.value > root.minimum) {
|
||||
root.value -= 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
border-radius: 3px;
|
||||
border-width: 2px;
|
||||
border-color: Theme.control-outline;
|
||||
// TODO: replace with visual min/max drawing
|
||||
Text {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
vertical-alignment: center;
|
||||
horizontal-alignment: center;
|
||||
text: root.value;
|
||||
color: Theme.control-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
SquareCharButton {
|
||||
width: root.height - parent.padding * 2;
|
||||
char: "+";
|
||||
clicked => {
|
||||
if (root.value < root.maximum) {
|
||||
root.value += 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export component PopupNotification {
|
||||
in property <string> heading;
|
||||
in property <string> content;
|
||||
_p := PopupWindow {
|
||||
x: root.x;
|
||||
y: root.y;
|
||||
width: root.width;
|
||||
height: root.height;
|
||||
// TODO: add properties to display
|
||||
Rectangle {
|
||||
border-width: 2px;
|
||||
border-color: Theme.control-outline;
|
||||
background: Theme.notification-background;
|
||||
// TODO: drop shadows slow
|
||||
// drop-shadow-offset-x: 7px;
|
||||
// drop-shadow-offset-y: 7px;
|
||||
// drop-shadow-color: black;
|
||||
// drop-shadow-blur: 30px;
|
||||
VerticalLayout {
|
||||
Dialog {
|
||||
VerticalLayout {
|
||||
alignment: start;
|
||||
Text {
|
||||
text: heading;
|
||||
color: Theme.text-foreground-color;
|
||||
font-size: 32px;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
Text {
|
||||
text: content;
|
||||
color: Theme.text-foreground-color;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
kind: ok;
|
||||
}
|
||||
|
||||
StandardButton {
|
||||
kind: cancel;
|
||||
}
|
||||
|
||||
Button {
|
||||
text: "More Info";
|
||||
dialog-button-role: action;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function show() {
|
||||
_p.show();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
39
rog-control-center/ui/globals.slint
Normal file
39
rog-control-center/ui/globals.slint
Normal file
@@ -0,0 +1,39 @@
|
||||
struct ButtonColours {
|
||||
base: color,
|
||||
pressed: color,
|
||||
hovered: color,
|
||||
}
|
||||
|
||||
export global AppSize {
|
||||
out property <length> width: 800px;
|
||||
out property <length> height: 480px;
|
||||
}
|
||||
|
||||
export global Theme {
|
||||
out property <color> window-background: #000000;
|
||||
out property <color> neutral-box: #BDC0D1;
|
||||
// The background colour of pages and bars
|
||||
out property <color> background-color: root.dark-mode ? #12387b : white;
|
||||
out property <color> text-foreground-color: root.dark-mode ? #F4F6FF : black;
|
||||
out property <color> secondary-foreground-color: root.dark-mode ? #C1C3CA : #6C6E7A;
|
||||
out property <color> image-button-background: root.dark-mode ? root.window-background : white;
|
||||
out property <color> toolbar-background: root.background-color;
|
||||
out property <color> notification-border: root.background-color;
|
||||
out property <color> notification-background: root.background-color;
|
||||
out property <color> control-outline: #FFBF63;
|
||||
out property <color> control-secondary: #6284FF;
|
||||
out property <color> control-foreground: root.dark-mode ? white : #122F7B;
|
||||
out property <color> push-button-base: #FFBF63;
|
||||
out property <ButtonColours> push-button: {
|
||||
base: root.push-button-base,
|
||||
pressed: root.push-button-base.darker(40%),
|
||||
hovered: root.push-button-base.darker(20%),
|
||||
};
|
||||
out property <color> push-button-text-color: white;
|
||||
out property <length> base-font-size: 16px;
|
||||
in property <bool> dark-mode: true;
|
||||
}
|
||||
|
||||
export global IconImages {
|
||||
//out property <image> two_t: @image-url("images/parameters/2t.png");
|
||||
}
|
||||
120
rog-control-center/ui/main_window.slint
Normal file
120
rog-control-center/ui/main_window.slint
Normal file
@@ -0,0 +1,120 @@
|
||||
import { Button, VerticalBox } from "std-widgets.slint";
|
||||
import { SpinBoxUni, ValueBar, SquareImageButton, RoundImageButton } from "common_widgets.slint";
|
||||
import { Theme, AppSize } from "globals.slint";
|
||||
import { PageSystem } from "pages/system.slint";
|
||||
import { SideBar } from "widgets/sidebar.slint";
|
||||
import { PageAbout } from "pages/about.slint";
|
||||
import { PageGpu } from "pages/gpu.slint";
|
||||
import { PageFans } from "pages/fans.slint";
|
||||
import { PageAnime } from "pages/anime.slint";
|
||||
import { PageAura } from "pages/aura.slint";
|
||||
|
||||
export { AppSize, Theme }
|
||||
|
||||
export component MainWindow inherits Window {
|
||||
default-font-family: "DejaVu Sans";
|
||||
private property <bool> show-notif;
|
||||
private property <bool> fade-cover;
|
||||
callback exit-app();
|
||||
callback request-increase-value();
|
||||
callback show-notification(bool);
|
||||
show-notification(yes) => {
|
||||
show-notif = yes;
|
||||
fade-cover = yes;
|
||||
|
||||
}
|
||||
height: AppSize.height;
|
||||
width: AppSize.width;
|
||||
background: Colors.orange;
|
||||
HorizontalLayout {
|
||||
padding: 0px;
|
||||
side-bar := SideBar {
|
||||
title: @tr("ROG");
|
||||
model: [
|
||||
@tr("Menu" => "System Control"),
|
||||
@tr("Menu" => "Keyboard Aura"),
|
||||
@tr("Menu" => "AniMe Matrix"),
|
||||
@tr("Menu" => "Fan Curves"),
|
||||
@tr("Menu" => "GPU Control"),
|
||||
@tr("Menu" => "About"),
|
||||
];
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Colors.purple;
|
||||
if(side-bar.current-item == 0): PageSystem {
|
||||
width: root.width - side-bar.width;
|
||||
height: root.height + 12px;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 1): PageAura {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 2): PageAnime {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 3): PageFans {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 4): PageGpu {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
|
||||
if(side-bar.current-item == 5): PageAbout {
|
||||
width: root.width - side-bar.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if fade-cover: Rectangle {
|
||||
x: 0px;
|
||||
y: 0px;
|
||||
width: root.width;
|
||||
height: root.height;
|
||||
background: Colors.rgba(25,33,23,20);
|
||||
opacity: 0.7;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
clicked => {
|
||||
// toolbar-dropdown.close();
|
||||
if (show-notif) {
|
||||
show-notif = false;
|
||||
|
||||
}
|
||||
fade-cover = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: or use Dialogue
|
||||
if show-notif: Rectangle {
|
||||
x: root.width / 8;
|
||||
y: root.height / 8;
|
||||
height: (root.height / 8) * 6;
|
||||
width: (root.width / 8) * 6;
|
||||
TouchArea {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
clicked => {
|
||||
show-notif = false;
|
||||
exit-app();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add properties to display
|
||||
Rectangle {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: Theme.neutral-box;
|
||||
Text {
|
||||
text: "Click here to exit";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
18
rog-control-center/ui/pages/about.slint
Normal file
18
rog-control-center/ui/pages/about.slint
Normal file
@@ -0,0 +1,18 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
import { AboutSlint } from "std-widgets.slint";
|
||||
|
||||
export component PageAbout inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
AboutSlint {}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
rog-control-center/ui/pages/anime.slint
Normal file
50
rog-control-center/ui/pages/anime.slint
Normal file
@@ -0,0 +1,50 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
|
||||
export component PageAnime inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: 10.5;
|
||||
min: 0.0;
|
||||
max: 100.0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: -70;
|
||||
min: -100;
|
||||
max: 0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: 40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
rog-control-center/ui/pages/aura.slint
Normal file
50
rog-control-center/ui/pages/aura.slint
Normal file
@@ -0,0 +1,50 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
|
||||
export component PageAura inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: 10.5;
|
||||
min: 0.0;
|
||||
max: 100.0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: -70;
|
||||
min: -100;
|
||||
max: 0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: 40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
rog-control-center/ui/pages/fans.slint
Normal file
50
rog-control-center/ui/pages/fans.slint
Normal file
@@ -0,0 +1,50 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
|
||||
export component PageFans inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: 10.5;
|
||||
min: 0.0;
|
||||
max: 100.0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: -70;
|
||||
min: -100;
|
||||
max: 0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: 40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
rog-control-center/ui/pages/gpu.slint
Normal file
50
rog-control-center/ui/pages/gpu.slint
Normal file
@@ -0,0 +1,50 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
|
||||
export component PageGpu inherits VerticalLayout {
|
||||
Rectangle {
|
||||
clip: true;
|
||||
// TODO: slow with border-radius
|
||||
padding: 8px;
|
||||
// height: parent.height - infobar.height - mainview.padding - self.padding * 2;
|
||||
// TODO: border-radius: 8px;
|
||||
mainview := VerticalLayout {
|
||||
padding: 10px;
|
||||
spacing: 10px;
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: 10.5;
|
||||
min: 0.0;
|
||||
max: 100.0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 40px;
|
||||
value: -70;
|
||||
min: -100;
|
||||
max: 0;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: 40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
|
||||
ValueBar {
|
||||
height: 80px;
|
||||
value: -40;
|
||||
min: -50;
|
||||
max: 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
rog-control-center/ui/pages/system.slint
Normal file
113
rog-control-center/ui/pages/system.slint
Normal file
@@ -0,0 +1,113 @@
|
||||
import { ValueBar } from "../common_widgets.slint";
|
||||
import { Theme } from "../globals.slint";
|
||||
import { HorizontalBox , VerticalBox, ScrollView} from "std-widgets.slint";
|
||||
|
||||
export component PageSystem inherits Rectangle {
|
||||
background: Theme.background-color;
|
||||
ScrollView {
|
||||
VerticalLayout {
|
||||
// padding: 10px;
|
||||
spacing: 10px;
|
||||
min-height: root.height;
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("ChargeMode" => "Charging mode");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("ChargeLimit" => "Charge limit");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PanelOverdrive" => "Panel Overdrive");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PerformanceProfile" => "Performance Profile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("nv_dynamic_boost" => "nv_dynamic_boost");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("nv_temp_target" => "nv_temp_target");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("ppt_pl1_spl" => "ppt_pl1_spl");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("ppt_pl2_sppt" => "ppt_pl2_sppt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PanelOverdrive" => "Panel Overdrive");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PerformanceProfile" => "Performance Profile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PanelOverdrive" => "Panel Overdrive");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PerformanceProfile" => "Performance Profile");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
background: Theme.background-color;
|
||||
VerticalBox {
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PanelOverdrive" => "Panel Overdrive");
|
||||
}
|
||||
|
||||
Text {
|
||||
color: Theme.text-foreground-color;
|
||||
text: @tr("PerformanceProfile" => "Performance Profile");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
rog-control-center/ui/widgets/sidebar.slint
Normal file
125
rog-control-center/ui/widgets/sidebar.slint
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
import { StyleMetrics } from "std-widgets.slint";
|
||||
|
||||
component SideBarItem inherits Rectangle {
|
||||
in property <bool> selected;
|
||||
in property <bool> has-focus;
|
||||
in-out property <string> text<=> label.text;
|
||||
callback clicked<=>touch.clicked;
|
||||
min-height: l.preferred-height;
|
||||
states [
|
||||
pressed when touch.pressed: {
|
||||
state.opacity: 0.8;
|
||||
}
|
||||
hover when touch.has-hover: {
|
||||
state.opacity: 0.6;
|
||||
}
|
||||
selected when root.selected: {
|
||||
state.opacity: 1;
|
||||
}
|
||||
focused when root.has-focus: {
|
||||
state.opacity: 0.8;
|
||||
}
|
||||
]
|
||||
|
||||
state := Rectangle {
|
||||
opacity: 0;
|
||||
background: StyleMetrics.window-background;
|
||||
animate opacity{ duration: 150ms;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
l := HorizontalLayout {
|
||||
y: (parent.height - self.height) / 2;
|
||||
padding: StyleMetrics.layout-padding;
|
||||
spacing: 0px;
|
||||
label := Text {
|
||||
color: StyleMetrics.default-text-color;
|
||||
vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
|
||||
touch := TouchArea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
export component SideBar inherits Rectangle {
|
||||
in property <[string]> model: [];
|
||||
in property <string> title<=> label.text;
|
||||
out property <int> current-item: 0;
|
||||
out property <int> current-focused: fs.has-focus ? fs.focused-tab : -1;
|
||||
// The currently focused tab
|
||||
|
||||
width: 180px;
|
||||
forward-focus: fs;
|
||||
accessible-role: tab;
|
||||
accessible-delegate-focus: root.current-focused >= 0 ? root.current-focused : root.current-item;
|
||||
Rectangle {
|
||||
background: StyleMetrics.window-background.darker(0.2);
|
||||
fs := FocusScope {
|
||||
key-pressed(event) => {
|
||||
if (event.text == "\n") {
|
||||
root.current-item = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.UpArrow) {
|
||||
self.focused-tab = Math.max(self.focused-tab - 1, 0);
|
||||
return accept;
|
||||
}
|
||||
if (event.text == Key.DownArrow) {
|
||||
self.focused-tab = Math.min(self.focused-tab + 1, root.model.length - 1);
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
}
|
||||
key-released(event) => {
|
||||
if (event.text == " ") {
|
||||
root.current-item = root.current-focused;
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
}
|
||||
property <int> focused-tab: 0;
|
||||
x: 0;
|
||||
width: 0;
|
||||
// Do not react on clicks
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
padding-top: StyleMetrics.layout-padding;
|
||||
padding-bottom: StyleMetrics.layout-padding;
|
||||
spacing: StyleMetrics.layout-spacing;
|
||||
alignment: start;
|
||||
label := Text {
|
||||
font-size: 16px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
navigation := VerticalLayout {
|
||||
alignment: start;
|
||||
vertical-stretch: 0;
|
||||
for item [index] in root.model: SideBarItem {
|
||||
clicked => {
|
||||
root.current-item = index;
|
||||
}
|
||||
has-focus: index == root.current-focused;
|
||||
text: item;
|
||||
selected: index == root.current-item;
|
||||
}
|
||||
}
|
||||
|
||||
VerticalLayout {
|
||||
bottom := VerticalLayout {
|
||||
padding-left: StyleMetrics.layout-padding;
|
||||
padding-right: StyleMetrics.layout-padding;
|
||||
@children
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
use rog_anime::usb::Brightness;
|
||||
use rog_anime::{Animations, AnimeDataBuffer, DeviceState as AnimeDeviceState};
|
||||
use zbus::dbus_proxy;
|
||||
use zbus::proxy;
|
||||
|
||||
#[dbus_proxy(
|
||||
#[proxy(
|
||||
interface = "org.asuslinux.Daemon",
|
||||
default_service = "org.asuslinux.Daemon",
|
||||
default_path = "/org/asuslinux/Anime"
|
||||
@@ -18,48 +18,48 @@ trait Anime {
|
||||
fn write(&self, input: AnimeDataBuffer) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyDeviceState signal
|
||||
#[dbus_proxy(signal)]
|
||||
#[zbus(signal)]
|
||||
fn notify_device_state(&self, data: AnimeDeviceState) -> zbus::Result<()>;
|
||||
|
||||
/// Brightness property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn brightness(&self) -> zbus::Result<Brightness>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_brightness(&self, value: Brightness) -> zbus::Result<()>;
|
||||
|
||||
/// BuiltinAnimations property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn builtin_animations(&self) -> zbus::Result<Animations>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_builtin_animations(&self, value: Animations) -> zbus::Result<()>;
|
||||
|
||||
/// BuiltinsEnabled property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn builtins_enabled(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_builtins_enabled(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// EnableDisplay property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn enable_display(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_enable_display(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// OffWhenLidClosed property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn off_when_lid_closed(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_off_when_lid_closed(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// OffWhenSuspended property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn off_when_suspended(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_off_when_suspended(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// OffWhenUnplugged property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn off_when_unplugged(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_off_when_unplugged(&self, value: bool) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ use rog_aura::aura_detection::PowerZones;
|
||||
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
||||
use zbus::blocking::Connection;
|
||||
use zbus::{dbus_proxy, Result};
|
||||
use zbus::{proxy, Result};
|
||||
|
||||
const BLOCKING_TIME: u64 = 33; // 100ms = 10 FPS, max 50ms = 20 FPS, 40ms = 25 FPS
|
||||
|
||||
#[dbus_proxy(
|
||||
#[proxy(
|
||||
interface = "org.asuslinux.Daemon",
|
||||
default_service = "org.asuslinux.Daemon",
|
||||
default_path = "/org/asuslinux/Aura"
|
||||
@@ -44,47 +44,47 @@ trait Aura {
|
||||
fn direct_addressing_raw(&self, data: UsbPackets) -> zbus::Result<()>;
|
||||
|
||||
/// Brightness property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn brightness(&self) -> zbus::Result<LedBrightness>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_brightness(&self, value: LedBrightness) -> zbus::Result<()>;
|
||||
|
||||
/// DeviceType property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn device_type(&self) -> zbus::Result<AuraDevice>;
|
||||
|
||||
/// LedMode property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn led_mode(&self) -> zbus::Result<AuraModeNum>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_led_mode(&self, value: AuraModeNum) -> zbus::Result<()>;
|
||||
|
||||
/// LedModeData property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn led_mode_data(&self) -> zbus::Result<AuraEffect>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_led_mode_data(&self, value: AuraEffect) -> zbus::Result<()>;
|
||||
|
||||
/// LedPower property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn led_power(&self) -> zbus::Result<AuraPowerDev>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_led_power(&self, value: (AuraPowerDev, bool)) -> zbus::Result<()>;
|
||||
|
||||
/// SupportedBrightness property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn supported_brightness(&self) -> zbus::Result<Vec<LedBrightness>>;
|
||||
|
||||
/// SupportedBasicModes property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn supported_basic_modes(&self) -> zbus::Result<Vec<AuraModeNum>>;
|
||||
|
||||
/// SupportedBasicZones property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn supported_basic_zones(&self) -> zbus::Result<Vec<AuraZone>>;
|
||||
|
||||
/// SupportedPowerZones property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn supported_power_zones(&self) -> zbus::Result<Vec<PowerZones>>;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
use rog_platform::platform::ThrottlePolicy;
|
||||
use rog_profiles::fan_curve_set::CurveData;
|
||||
use rog_profiles::FanCurvePU;
|
||||
use zbus::dbus_proxy;
|
||||
use zbus::proxy;
|
||||
|
||||
#[dbus_proxy(
|
||||
#[proxy(
|
||||
interface = "org.asuslinux.Daemon",
|
||||
default_service = "org.asuslinux.Daemon",
|
||||
default_path = "/org/asuslinux/FanCurves"
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use rog_platform::platform::{GpuMode, Properties, ThrottlePolicy};
|
||||
use zbus::dbus_proxy;
|
||||
use zbus::proxy;
|
||||
|
||||
#[dbus_proxy(
|
||||
#[proxy(
|
||||
interface = "org.asuslinux.Daemon",
|
||||
default_service = "org.asuslinux.Daemon",
|
||||
default_path = "/org/asuslinux/Platform"
|
||||
@@ -39,88 +39,88 @@ trait Platform {
|
||||
fn supported_properties(&self) -> zbus::Result<Vec<Properties>>;
|
||||
|
||||
/// ChargeControlEndThreshold property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn charge_control_end_threshold(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_charge_control_end_threshold(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// DgpuDisable property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn dgpu_disable(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// EgpuEnable property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn egpu_enable(&self) -> zbus::Result<bool>;
|
||||
|
||||
/// GpuMuxMode property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn gpu_mux_mode(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_gpu_mux_mode(&self, value: GpuMode) -> zbus::Result<()>;
|
||||
|
||||
/// MiniLedMode property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn mini_led_mode(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_mini_led_mode(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// NvDynamicBoost property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn nv_dynamic_boost(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_nv_dynamic_boost(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// NvTempTarget property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn nv_temp_target(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_nv_temp_target(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// PanelOd property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn panel_od(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_panel_od(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// PostAnimationSound property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn post_animation_sound(&self) -> zbus::Result<bool>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_post_animation_sound(&self, value: bool) -> zbus::Result<()>;
|
||||
|
||||
/// PptApuSppt property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn ppt_apu_sppt(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_ppt_apu_sppt(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// PptFppt property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn ppt_fppt(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_ppt_fppt(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// PptPl1Spl property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn ppt_pl1_spl(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_ppt_pl1_spl(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// PptPl2Sppt property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn ppt_pl2_sppt(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_ppt_pl2_sppt(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// PptPlatformSppt property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn ppt_platform_sppt(&self) -> zbus::Result<u8>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_ppt_platform_sppt(&self, value: u8) -> zbus::Result<()>;
|
||||
|
||||
/// ThrottlePolicy property
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn throttle_thermal_policy(&self) -> zbus::Result<ThrottlePolicy>;
|
||||
#[dbus_proxy(property)]
|
||||
#[zbus(property)]
|
||||
fn set_throttle_thermal_policy(&self, value: ThrottlePolicy) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user