mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Groundwork for 'advanced' aura modes Add single zone + Doom light flash Fix mocking for ROGCC Better prepare & change to mapping of keyboard layouts to models and functions Refactor and begin using new key layout stuff Enable first arg to rogcc to set layout in mocking feature mode Complete refactor of key layouts, and to RON serde
180 lines
6.6 KiB
Rust
180 lines
6.6 KiB
Rust
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::supported::SupportedFunctions;
|
|
|
|
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>>,
|
|
pub supported: SupportedFunctions,
|
|
// 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>,
|
|
}
|
|
|
|
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 = dbus.proxies().supported().supported_functions()?;
|
|
|
|
// 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,
|
|
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: &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;
|
|
}
|
|
}
|
|
|
|
let page = self.page;
|
|
|
|
self.top_bar(ctx, frame);
|
|
self.side_panel(ctx);
|
|
|
|
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() {
|
|
if page == Page::System {
|
|
self.system_page(&mut states, ctx);
|
|
} else if page == Page::AuraEffects {
|
|
self.aura_page(&mut states, ctx);
|
|
// TODO: Anime page is not complete
|
|
// } else if page == Page::AnimeMatrix {
|
|
// self.anime_page(ctx);
|
|
} else if page == Page::FanCurves {
|
|
self.fan_curve_page(&mut states, ctx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|