From 5d4b164b3b1ff92ef19890107cb1625f105ea1ae Mon Sep 17 00:00:00 2001 From: Denis Benato Date: Sat, 24 Jan 2026 16:48:18 +0100 Subject: [PATCH] fix: LEDs managfement in rogcc --- rog-control-center/src/main.rs | 13 +- rog-control-center/src/ui/mod.rs | 7 +- rog-control-center/src/ui/setup_aura.rs | 277 ++++++++++--------- rog-control-center/ui/pages/aura.slint | 121 ++++---- rog-control-center/ui/types/aura_types.slint | 52 ++-- 5 files changed, 249 insertions(+), 221 deletions(-) diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index 8e3811d6..24a905b7 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -187,12 +187,18 @@ async fn main() -> Result<()> { slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/translations/")); } + // Prefetch supported Aura modes once at startup and move into the + // spawned UI thread so the UI uses a stable, immutable list. + let prefetched_supported: std::sync::Arc>> = std::sync::Arc::new( + rog_control_center::ui::setup_aura::prefetch_supported_basic_modes().await, + ); + thread::spawn(move || { let mut state = AppState::StartingUp; loop { if is_rog_ally { let config_copy_2 = config.clone(); - let newui = setup_window(config.clone()); + let newui = setup_window(config.clone(), prefetched_supported.clone()); newui.window().on_close_requested(move || { exit(0); }); @@ -233,6 +239,9 @@ async fn main() -> Result<()> { let config_copy = config.clone(); let app_state_copy = app_state.clone(); + // Avoid moving the original `prefetched_supported` into the + // closure — clone an Arc for the closure to capture. + let pref_for_invoke = prefetched_supported.clone(); slint::invoke_from_event_loop(move || { UI.with(|ui| { let app_state_copy = app_state_copy.clone(); @@ -247,7 +256,7 @@ async fn main() -> Result<()> { }); } else { let config_copy_2 = config_copy.clone(); - let newui = setup_window(config_copy); + let newui = setup_window(config_copy, pref_for_invoke.clone()); newui.window().on_close_requested(move || { if let Ok(mut app_state) = app_state_copy.lock() { *app_state = AppState::MainWindowClosed; diff --git a/rog-control-center/src/ui/mod.rs b/rog-control-center/src/ui/mod.rs index ae73dced..81a45e82 100644 --- a/rog-control-center/src/ui/mod.rs +++ b/rog-control-center/src/ui/mod.rs @@ -82,7 +82,10 @@ pub fn show_toast( }; } -pub fn setup_window(config: Arc>) -> MainWindow { +pub fn setup_window( + config: Arc>, + prefetched_supported: std::sync::Arc>>, +) -> MainWindow { slint::set_xdg_app_id("rog-control-center") .map_err(|e| warn!("Couldn't set application ID: {e:?}")) .ok(); @@ -119,7 +122,7 @@ pub fn setup_window(config: Arc>) -> MainWindow { setup_system_page_callbacks(&ui, config.clone()); } if available.contains(&"xyz.ljones.Aura".to_string()) { - setup_aura_page(&ui, config.clone()); + setup_aura_page(&ui, config.clone(), prefetched_supported.as_ref().clone()); } if available.contains(&"xyz.ljones.Anime".to_string()) { setup_anime_page(&ui, config.clone()); diff --git a/rog-control-center/src/ui/setup_aura.rs b/rog-control-center/src/ui/setup_aura.rs index 31938416..5ef41040 100644 --- a/rog-control-center/src/ui/setup_aura.rs +++ b/rog-control-center/src/ui/setup_aura.rs @@ -34,63 +34,108 @@ fn decode_hex(s: &str) -> RgbaColor { } } -/// Returns the first available Aura interface -// TODO: return all async fn find_aura_iface() -> Result, Box> { let conn = zbus::Connection::system().await?; - let f = zbus::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").await?; - let interfaces = f.get_managed_objects().await?; - let mut aura_paths = Vec::new(); - for v in interfaces.iter() { - for k in v.1.keys() { - if k.as_str() == "xyz.ljones.Aura" { - println!("Found aura device at {}, {}", v.0, k); - aura_paths.push(v.0.clone()); - } - } + let mgr = zbus::fdo::ObjectManagerProxy::new(&conn, "xyz.ljones.Asusd", "/").await?; + let objs = mgr.get_managed_objects().await?; + let mut paths: Vec = objs + .iter() + .filter(|(_, ifaces)| ifaces.keys().any(|k| k.as_str() == "xyz.ljones.Aura")) + .map(|(p, _)| p.clone()) + .collect(); + if paths.len() > 1 { + log::debug!("Multiple aura devices: {paths:?}"); } - if aura_paths.len() > 1 { - println!("Multiple aura devices found: {aura_paths:?}"); - println!("TODO: enable selection"); - } - if let Some(path) = aura_paths.first() { - return Ok(AuraProxy::builder(&conn) - .path(path.clone())? - .destination("xyz.ljones.Asusd")? - .build() - .await?); - } - - Err("No Aura interface".into()) + let path = paths.pop().ok_or("No Aura interface")?; + AuraProxy::builder(&conn) + .path(path)? + .destination("xyz.ljones.Asusd")? + .build() + .await + .map_err(Into::into) } -pub fn setup_aura_page(ui: &MainWindow, _states: Arc>) { - ui.global::().on_cb_hex_from_colour(|c| { +pub async fn prefetch_supported_basic_modes() -> Option> { + let proxy = find_aura_iface().await.ok()?; + let modes = proxy.supported_basic_modes().await.ok()?; + Some(modes.iter().map(|n| (*n).into()).collect()) +} + +pub fn setup_aura_page( + ui: &MainWindow, + _states: Arc>, + prefetched_supported: Option>, +) { + let g = ui.global::(); + g.on_cb_hex_from_colour(|c| { format!("#{:02X}{:02X}{:02X}", c.red(), c.green(), c.blue()).into() }); - - ui.global::() - .on_cb_hex_to_colour(|s| decode_hex(s.as_str()).into()); + g.on_cb_hex_to_colour(|s| decode_hex(s.as_str()).into()); let handle = ui.as_weak(); tokio::spawn(async move { let Ok(aura) = find_aura_iface().await else { - info!("This device appears to have no aura interfaces"); + info!("No aura interfaces"); return Ok::<(), zbus::Error>(()); }; set_ui_props_async!(handle, aura, AuraPageData, brightness); - set_ui_props_async!(handle, aura, AuraPageData, led_mode); - set_ui_props_async!(handle, aura, AuraPageData, led_mode_data); set_ui_props_async!(handle, aura, AuraPageData, led_power); set_ui_props_async!(handle, aura, AuraPageData, device_type); + if let Ok(data) = aura.led_mode_data().await { + let d = data.into(); + handle + .upgrade_in_event_loop(move |h| { + h.global::().invoke_update_led_mode_data(d); + }) + .ok(); + } + + let modes_vec: Vec = match prefetched_supported { + Some(p) => p, + None => aura + .supported_basic_modes() + .await + .ok() + .map(|m| m.iter().map(|n| (*n).into()).collect()) + .unwrap_or_default(), + }; + let current_mode: Option = aura.led_mode().await.ok().map(|m| m.into()); + + handle + .upgrade_in_event_loop(move |handle| { + let names = handle.global::().get_mode_names(); + let mut raws = Vec::new(); + let mut mode_names = Vec::new(); + for (i, name) in names.iter().enumerate() { + let raw = i as i32; + if modes_vec.contains(&raw) && i != 9 { + raws.push(raw); + mode_names.push(name.clone()); + } + } + handle + .global::() + .set_supported_basic_modes(raws.as_slice().into()); + handle + .global::() + .set_available_mode_names(mode_names.as_slice().into()); + if let Some(cm) = current_mode { + let idx = raws.iter().position(|&r| r == cm).unwrap_or(0) as i32; + handle + .global::() + .set_current_available_mode(idx); + } + }) + .map_err(|e| error!("{e}")) + .ok(); + if let Ok(mut pow3r) = aura.supported_power_zones().await { - let dev_type = aura + let dev = aura .device_type() .await .unwrap_or(AuraDeviceType::LaptopKeyboard2021); - log::debug!("Available LED power modes {pow3r:?}"); handle .upgrade_in_event_loop(move |handle| { let names: Vec = handle @@ -98,135 +143,103 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc>) { .get_power_zone_names() .iter() .collect(); - - if dev_type.is_old_laptop() { - // Need to add the specific KeyboardAndLightbar + if dev.is_old_laptop() { if pow3r.contains(&PowerZones::Keyboard) && pow3r.contains(&PowerZones::Lightbar) { pow3r.push(PowerZones::KeyboardAndLightbar); } - let names: Vec = - pow3r.iter().map(|n| names[(*n) as usize].clone()).collect(); + let n: Vec = + pow3r.iter().map(|z| names[(*z) as usize].clone()).collect(); handle .global::() - .set_power_zone_names_old(names.as_slice().into()); + .set_power_zone_names_old(n.as_slice().into()); } else { - let power: Vec = - pow3r.iter().map(|p| (*p).into()).collect(); - + let p: Vec = pow3r.iter().map(|z| (*z).into()).collect(); handle .global::() - .set_supported_power_zones(power.as_slice().into()); + .set_supported_power_zones(p.as_slice().into()); } }) .ok(); } - if let Ok(modes) = aura.supported_basic_modes().await { - log::debug!("Available LED modes {modes:?}"); - handle - .upgrade_in_event_loop(move |handle| { - let m: Vec = modes.iter().map(|n| (*n).into()).collect(); - handle - .global::() - .set_supported_basic_modes(m.as_slice().into()); - // Get the translated names - let names = handle.global::().get_mode_names(); - - let res: Vec = names - .iter() - .enumerate() - .filter(|(n, _)| modes.contains(&(*n as i32).into()) && *n != 9) - .map(|(_, i)| i) - .collect(); - handle - .global::() - .set_available_mode_names(res.as_slice().into()); - }) - .map_err(|e| error!("{e:}")) - .ok(); - } - - let proxy_copy = aura.clone(); + let proxy = aura.clone(); + let weak = handle.clone(); handle - .upgrade_in_event_loop(move |handle| { - set_ui_callbacks!(handle, + .upgrade_in_event_loop(move |h| { + set_ui_callbacks!(h, AuraPageData(.into()), - proxy_copy.brightness(.into()), - "Keyboard LED brightness successfully set to {}", - "Setting keyboard LED brightness failed" + proxy.brightness(.into()), + "Brightness set to {}", + "Brightness failed" ); - set_ui_callbacks!(handle, - AuraPageData(.into()), - proxy_copy.led_mode(.into()), - "Keyboard LED mode successfully set to {}", - "Setting keyboard LEDmode failed" - ); - - set_ui_callbacks!(handle, - AuraPageData(.into()), - proxy_copy.led_mode_data(.into()), - "Keyboard LED mode set to {:?}", - "Setting keyboard LED mode failed" - ); - - // set_ui_callbacks!(handle, - // AuraPageData(.clone().into()), - // proxy_copy.led_power(.into()), - // "Keyboard LED power successfully set to {:?}", - // "Setting keyboard power failed" - // ); - - handle.invoke_external_colour_change(); - }) - .ok(); - - let handle_copy = handle.clone(); - let proxy_copy = aura.clone(); - handle - .upgrade_in_event_loop(|handle| { - handle - .global::() - .on_cb_led_power(move |power| { - let handle_copy = handle_copy.clone(); - let proxy_copy = aura.clone(); - let power: LaptopAuraPower = power.into(); - tokio::spawn(async move { - show_toast( - "Aura power settings changed".into(), - "Failed to set Aura power settings".into(), - handle_copy, - proxy_copy.set_led_power(power).await, - ); - }); + let p = proxy.clone(); + let w = weak.clone(); + h.global::().on_apply_led_mode_data(move || { + let Some(ui) = w.upgrade() else { return }; + let slint_effect = ui.global::().get_led_mode_data(); + let raw: rog_aura::AuraEffect = slint_effect.into(); + let pp = p.clone(); + let t = w.clone(); + tokio::spawn(async move { + let r = pp.set_led_mode_data(raw).await; + show_toast("LED mode applied".into(), "LED mode failed".into(), t, r); }); + }); + h.invoke_external_colour_change(); }) - .map_err(|e| error!("{e:}")) .ok(); - // Need to update the UI if the mode changes - let handle_copy = handle.clone(); - // spawn required since the while let never exits + let weak_power = handle.clone(); + let proxy_power = aura.clone(); + handle + .upgrade_in_event_loop(|h| { + h.global::().on_cb_led_power(move |power| { + let w = weak_power.clone(); + let p = proxy_power.clone(); + let pw: LaptopAuraPower = power.into(); + tokio::spawn(async move { + show_toast( + "Aura power updated".into(), + "Aura power failed".into(), + w, + p.set_led_power(pw).await, + ); + }); + }); + }) + .map_err(|e| error!("{e}")) + .ok(); + + let stream_handle = handle.clone(); + let aura_stream = aura.clone(); tokio::spawn(async move { - let mut x = proxy_copy.receive_led_mode_data_changed().await; use futures_util::StreamExt; - while let Some(e) = x.next().await { + let mut stream = aura_stream.receive_led_mode_data_changed().await; + while let Some(e) = stream.next().await { if let Ok(out) = e.get().await { - handle_copy - .upgrade_in_event_loop(move |handle| { - handle + let raw: i32 = out.mode.into(); + let data = out.into(); + stream_handle + .upgrade_in_event_loop(move |h| { + h.global::().invoke_update_led_mode_data(data); + let supported: Vec = h .global::() - .invoke_update_led_mode_data(out.into()); - handle.invoke_external_colour_change(); + .get_supported_basic_modes() + .iter() + .collect(); + let idx = supported.iter().position(|&x| x == raw).unwrap_or(0) as i32; + h.global::().set_current_available_mode(idx); + h.invoke_external_colour_change(); }) - .map_err(|e| error!("{e:}")) + .map_err(|e| error!("{e}")) .ok(); } } }); - debug!("Aura setup tasks complete"); + debug!("Aura setup done"); Ok(()) }); } diff --git a/rog-control-center/ui/pages/aura.slint b/rog-control-center/ui/pages/aura.slint index f1cd1cd3..43d803ae 100644 --- a/rog-control-center/ui/pages/aura.slint +++ b/rog-control-center/ui/pages/aura.slint @@ -42,10 +42,14 @@ export component PageAura inherits Rectangle { current_value: AuraPageData.available_mode_names[self.current-index]; model <=> AuraPageData.available_mode_names; selected => { - AuraPageData.led_mode_data.mode = AuraPageData.led_mode; - AuraPageData.led_mode_data.mode = AuraPageData.current_available_mode; - self.current_value = AuraPageData.available_mode_names[self.current-index]; - AuraPageData.cb_led_mode(AuraPageData.current_available_mode); + AuraPageData.apply_effect({ + mode: AuraPageData.supported_basic_modes[self.current-index], + zone: AuraPageData.led_mode_data.zone, + colour1: AuraPageData.led_mode_data.colour1, + colour2: AuraPageData.led_mode_data.colour2, + speed: AuraPageData.led_mode_data.speed, + direction: AuraPageData.led_mode_data.direction, + }); } } } @@ -62,47 +66,44 @@ export component PageAura inherits Rectangle { vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; } - HorizontalBox { c1 := ColourSlider { - enabled: AuraPageData.led_mode == 0 || AuraPageData.led_mode == 1 || AuraPageData.led_mode == 4 || AuraPageData.led_mode == 6 || AuraPageData.led_mode == 7 || AuraPageData.led_mode == 8 || AuraPageData.led_mode == 10 || AuraPageData.led_mode == 11 || AuraPageData.led_mode == 12; + enabled: AuraPageData.colour1_enabled; final_colour <=> AuraPageData.color1; colourbox <=> AuraPageData.colorbox1; - set_hex_from_colour(c1) => { - return AuraPageData.cb_hex_from_colour(c1); - } - hex_to_colour(s) => { - return AuraPageData.cb_hex_to_colour(s); - } + set_hex_from_colour(c) => { return AuraPageData.cb_hex_from_colour(c); } + hex_to_colour(s) => { return AuraPageData.cb_hex_to_colour(s); } released => { - AuraPageData.led_mode_data.colour1 = AuraPageData.color1; - AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data); + AuraPageData.apply_effect({ + mode: AuraPageData.led_mode_data.mode, + zone: AuraPageData.led_mode_data.zone, + colour1: AuraPageData.color1, + colour2: AuraPageData.led_mode_data.colour2, + speed: AuraPageData.led_mode_data.speed, + direction: AuraPageData.led_mode_data.direction, + }); } } } } - VerticalBox { - Text { - text: @tr("Colour 2"); - vertical-alignment: TextVerticalAlignment.center; - horizontal-alignment: TextHorizontalAlignment.center; - } - + Text { text: @tr("Colour 2"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; } HorizontalBox { c2 := ColourSlider { - enabled: AuraPageData.led_mode == 1 || AuraPageData.led_mode == 4; + enabled: AuraPageData.colour2_enabled; final_colour <=> AuraPageData.color2; colourbox <=> AuraPageData.colorbox2; - set_hex_from_colour(c1) => { - return AuraPageData.cb_hex_from_colour(c1); - } - hex_to_colour(s) => { - return AuraPageData.cb_hex_to_colour(s); - } + set_hex_from_colour(c) => { return AuraPageData.cb_hex_from_colour(c); } + hex_to_colour(s) => { return AuraPageData.cb_hex_to_colour(s); } released => { - AuraPageData.led_mode_data.colour2 = AuraPageData.color2; - AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data); + AuraPageData.apply_effect({ + mode: AuraPageData.led_mode_data.mode, + zone: AuraPageData.led_mode_data.zone, + colour1: AuraPageData.led_mode_data.colour1, + colour2: AuraPageData.color2, + speed: AuraPageData.led_mode_data.speed, + direction: AuraPageData.led_mode_data.direction, + }); } } } @@ -116,63 +117,63 @@ export component PageAura inherits Rectangle { max-height: 90px; RogItem { VerticalBox { - Text { - text: @tr("Zone"); - vertical-alignment: TextVerticalAlignment.center; - horizontal-alignment: TextHorizontalAlignment.center; - } - + Text { text: @tr("Zone"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; } ComboBox { - // enabled: AuraPageData.led_mode == ; - enabled: false; + enabled: false; current_index <=> AuraPageData.zone; current_value: AuraPageData.zone_names[self.current-index]; model <=> AuraPageData.zone_names; selected => { - AuraPageData.led_mode_data.zone = self.current-index; - AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data); + AuraPageData.apply_effect({ + mode: AuraPageData.led_mode_data.mode, + zone: self.current-index, + colour1: AuraPageData.led_mode_data.colour1, + colour2: AuraPageData.led_mode_data.colour2, + speed: AuraPageData.led_mode_data.speed, + direction: AuraPageData.led_mode_data.direction, + }); } } } } - RogItem { VerticalBox { - Text { - text: @tr("Direction"); - vertical-alignment: TextVerticalAlignment.center; - horizontal-alignment: TextHorizontalAlignment.center; - } - + Text { text: @tr("Direction"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; } ComboBox { - enabled: AuraPageData.led_mode == 3; + enabled: AuraPageData.direction_enabled; current_index <=> AuraPageData.direction; current_value: AuraPageData.direction_names[self.current-index]; model <=> AuraPageData.direction_names; selected => { - AuraPageData.led_mode_data.direction = self.current-index; - AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data); + AuraPageData.apply_effect({ + mode: AuraPageData.led_mode_data.mode, + zone: AuraPageData.led_mode_data.zone, + colour1: AuraPageData.led_mode_data.colour1, + colour2: AuraPageData.led_mode_data.colour2, + speed: AuraPageData.led_mode_data.speed, + direction: self.current-index, + }); } } } } - RogItem { VerticalBox { - Text { - text: @tr("Speed"); - vertical-alignment: TextVerticalAlignment.center; - horizontal-alignment: TextHorizontalAlignment.center; - } - + Text { text: @tr("Speed"); vertical-alignment: TextVerticalAlignment.center; horizontal-alignment: TextHorizontalAlignment.center; } ComboBox { - enabled: AuraPageData.led_mode == 1 || AuraPageData.led_mode == 2 || AuraPageData.led_mode == 3 || AuraPageData.led_mode == 4 || AuraPageData.led_mode == 5 || AuraPageData.led_mode == 6 || AuraPageData.led_mode == 7 || AuraPageData.led_mode == 8; + enabled: AuraPageData.speed_enabled; current_index <=> AuraPageData.speed; current_value: AuraPageData.speed_names[self.current-index]; model <=> AuraPageData.speed_names; selected => { - AuraPageData.led_mode_data.speed = self.current-index; - AuraPageData.cb_led_mode_data(AuraPageData.led_mode_data); + AuraPageData.apply_effect({ + mode: AuraPageData.led_mode_data.mode, + zone: AuraPageData.led_mode_data.zone, + colour1: AuraPageData.led_mode_data.colour1, + colour2: AuraPageData.led_mode_data.colour2, + speed: self.current-index, + direction: AuraPageData.led_mode_data.direction, + }); } } } diff --git a/rog-control-center/ui/types/aura_types.slint b/rog-control-center/ui/types/aura_types.slint index 78df8330..e6d4795f 100644 --- a/rog-control-center/ui/types/aura_types.slint +++ b/rog-control-center/ui/types/aura_types.slint @@ -46,8 +46,10 @@ export struct LaptopAuraPower { states: [AuraPowerState], } +// Modes with colour1: Static,Breathe,Star,Rain,Highlight,Laser,Ripple,Pulse,Comet,Flash (excl. Strobe,Rainbow,Nothing) +// Modes with colour2: Breathe, Star only. +// Speed: Breathe,Strobe,Rainbow,Star,Rain,Highlight,Laser,Ripple. Direction: Rainbow only. export global AuraPageData { - // The ordering must match the rog-aura crate in-out property <[string]> power_zone_names: [ @tr("Aura power zone" => "Logo"), @tr("Aura power zone" => "Keyboard"), @@ -87,15 +89,9 @@ export global AuraPageData { @tr("Basic aura mode" => "Comet"), @tr("Basic aura mode" => "Flash"), ]; - in-out property <[string]> available_mode_names: [ - @tr("Basic aura mode" => "Static"), - @tr("Basic aura mode" => "Breathe"), - @tr("Basic aura mode" => "Strobe"), - ]; + in-out property <[string]> available_mode_names: [ @tr("Basic aura mode" => "Static"), @tr("Basic aura mode" => "Breathe"), @tr("Basic aura mode" => "Strobe") ]; in-out property current_available_mode: 0; in-out property <[int]> supported_basic_modes: [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12]; - in-out property led_mode; - callback cb_led_mode(int); in-out property <[string]> zone_names: [ @tr("Aura zone" => "None"), @tr("Aura zone" => "Key1"), @@ -106,51 +102,57 @@ export global AuraPageData { @tr("Aura zone" => "Lightbar Left"), @tr("Aura zone" => "Lightbar Right"), ]; - in-out property zone; in-out property <[string]> direction_names: [ @tr("Aura direction" => "Right"), @tr("Aura direction" => "Left"), @tr("Aura direction" => "Up"), @tr("Aura direction" => "Down"), ]; - in-out property direction; in-out property <[string]> speed_names: [ @tr("Aura speed" => "Low"), @tr("Aura speed" => "Medium"), @tr("Aura speed" => "High"), ]; - in-out property speed; + in-out property led_mode_data: { mode: 0, zone: 0, colour1: Colors.aquamarine, - colourbox1: Colors.aquamarine, colour2: Colors.hotpink, - colourbox2: Colors.hotpink, speed: 0, direction: 0, }; - callback cb_led_mode_data(AuraEffect); in-out property color1; in-out property colorbox1; in-out property color2; in-out property colorbox2; + + out property colour1_enabled: led_mode_data.mode == 0 || led_mode_data.mode == 1 || led_mode_data.mode == 4 || led_mode_data.mode == 6 || led_mode_data.mode == 7 || led_mode_data.mode == 8 || led_mode_data.mode == 10 || led_mode_data.mode == 11 || led_mode_data.mode == 12; + out property colour2_enabled: led_mode_data.mode == 1 || led_mode_data.mode == 4; + out property speed_enabled: led_mode_data.mode == 1 || led_mode_data.mode == 2 || led_mode_data.mode == 3 || led_mode_data.mode == 4 || led_mode_data.mode == 5 || led_mode_data.mode == 6 || led_mode_data.mode == 7 || led_mode_data.mode == 8; + out property direction_enabled: led_mode_data.mode == 3; + + callback apply_led_mode_data(); + callback apply_effect(AuraEffect); + apply_effect(e) => { led_mode_data = e; apply_led_mode_data(); } + in-out property zone; + in-out property speed; + in-out property direction; + callback update_led_mode_data(AuraEffect); - update_led_mode_data(data) => { - led_mode_data = data; - current_available_mode = data.mode; - zone = data.zone; - speed = data.speed; - direction = data.direction; - color1 = data.colour1; - color2 = data.colour2; - colorbox1 = data.colour1; - colorbox2 = data.colour2; + update_led_mode_data(d) => { + led_mode_data = d; + zone = d.zone; + speed = d.speed; + direction = d.direction; + color1 = d.colour1; + color2 = d.colour2; + colorbox1 = d.colour1; + colorbox2 = d.colour2; } callback cb_hex_from_colour(color) -> string; callback cb_hex_to_colour(string) -> color; in-out property device_type: AuraDevType.Old; - // List of indexes to power_zone_names. Must correspond to rog-aura crate in-out property <[PowerZones]> supported_power_zones: [ PowerZones.Keyboard, PowerZones.Lightbar,