mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
165 lines
5.8 KiB
Rust
165 lines
5.8 KiB
Rust
use std::{
|
|
f64::consts::PI,
|
|
sync::{
|
|
atomic::{AtomicBool, AtomicU8, Ordering},
|
|
Arc, Mutex,
|
|
},
|
|
time::{Duration, Instant},
|
|
};
|
|
|
|
use egui::{Button, RichText};
|
|
use rog_platform::supported::SupportedFunctions;
|
|
|
|
use crate::{
|
|
config::Config, error::Result, system_state::SystemState, 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();
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|