mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Add rog-control-center to the workspace
This commit is contained in:
77
rog-control-center/src/widgets/anime_page.rs
Normal file
77
rog-control-center/src/widgets/anime_page.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use egui::RichText;
|
||||
|
||||
use crate::RogApp;
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn anime_page(&mut self, ctx: &egui::Context) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("AniMe Matrix Settings");
|
||||
ui.label("Options are incomplete. Awake + Boot should work");
|
||||
|
||||
let Self {
|
||||
states,
|
||||
asus_dbus: dbus,
|
||||
..
|
||||
} = self;
|
||||
|
||||
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("Brightness").size(h));
|
||||
});
|
||||
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));
|
||||
});
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui
|
||||
.add(egui::Slider::new(&mut states.anime.bright, 0..=254))
|
||||
.changed()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(&mut states.anime.boot, "Enable").changed() {
|
||||
dbus.proxies()
|
||||
.anime()
|
||||
.set_boot_on_off(states.anime.boot)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(&mut states.anime.awake, "Enable").changed() {
|
||||
dbus.proxies()
|
||||
.anime()
|
||||
.set_on_off(states.anime.awake)
|
||||
.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;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
455
rog-control-center/src/widgets/aura_page.rs
Normal file
455
rog-control-center/src/widgets/aura_page.rs
Normal file
@@ -0,0 +1,455 @@
|
||||
use egui::{RichText, Ui};
|
||||
use rog_aura::{
|
||||
usb::{AuraDev1866, AuraDev19b6, AuraDevice, AuraPowerDev},
|
||||
AuraModeNum, AuraZone, Colour, Speed,
|
||||
};
|
||||
use rog_dbus::RogDbusClientBlocking;
|
||||
use rog_supported::SupportedFunctions;
|
||||
|
||||
use crate::{
|
||||
page_states::{AuraState, PageDataStates},
|
||||
RogApp,
|
||||
};
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn aura_page(&mut self, ctx: &egui::Context) {
|
||||
let Self {
|
||||
supported,
|
||||
states,
|
||||
asus_dbus: dbus,
|
||||
..
|
||||
} = self;
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
Self::aura_power(supported, states, dbus, ui);
|
||||
ui.separator();
|
||||
Self::aura_modes(supported, states, dbus, ui);
|
||||
});
|
||||
}
|
||||
|
||||
fn aura_power(
|
||||
supported: &SupportedFunctions,
|
||||
states: &mut PageDataStates,
|
||||
dbus: &mut RogDbusClientBlocking,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
match supported.keyboard_led.prod_id {
|
||||
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
||||
Self::aura_power1(supported, states, dbus, ui)
|
||||
}
|
||||
AuraDevice::X19B6 => Self::aura_power2(supported, states, dbus, ui),
|
||||
AuraDevice::Unknown => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn aura_power1(
|
||||
supported: &SupportedFunctions,
|
||||
states: &mut PageDataStates,
|
||||
dbus: &mut RogDbusClientBlocking,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
let enabled_states = &mut states.aura.enabled;
|
||||
|
||||
ui.heading("Aura go brrrrr! (incomplete)");
|
||||
ui.separator();
|
||||
|
||||
let boot = &mut enabled_states.x1866.contains(&AuraDev1866::Boot);
|
||||
let sleep = &mut enabled_states.x1866.contains(&AuraDev1866::Sleep);
|
||||
let keyboard = &mut enabled_states.x1866.contains(&AuraDev1866::Keyboard);
|
||||
let lightbar = &mut enabled_states.x1866.contains(&AuraDev1866::Lightbar);
|
||||
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));
|
||||
});
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(boot, "Enable").changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.toggle_value(keyboard, "Keyboard").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if !supported.keyboard_led.multizone_led_mode.is_empty() {
|
||||
if ui.toggle_value(lightbar, "Lightbar").changed() {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(sleep, "Enable").changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if changed {
|
||||
let mut enabled = Vec::new();
|
||||
let mut disabled = Vec::new();
|
||||
|
||||
let mut modify = |b: bool, a: AuraDev1866| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.x1866.contains(&a) {
|
||||
enabled_states.x1866.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.x1866.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.x1866.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.x1866.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
modify(*boot, AuraDev1866::Boot);
|
||||
modify(*sleep, AuraDev1866::Sleep);
|
||||
modify(*keyboard, AuraDev1866::Keyboard);
|
||||
if !supported.keyboard_led.multizone_led_mode.is_empty() {
|
||||
modify(*lightbar, AuraDev1866::Lightbar);
|
||||
}
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDev1866>| {
|
||||
let options = AuraPowerDev {
|
||||
x1866: data,
|
||||
x19b6: vec![],
|
||||
};
|
||||
// build data to send
|
||||
dbus.proxies()
|
||||
.led()
|
||||
.set_leds_power(options, enable)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(true, enabled);
|
||||
send(false, disabled);
|
||||
}
|
||||
}
|
||||
|
||||
fn aura_power2(
|
||||
supported: &SupportedFunctions,
|
||||
states: &mut PageDataStates,
|
||||
dbus: &mut RogDbusClientBlocking,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
let enabled_states = &mut states.aura.enabled;
|
||||
|
||||
ui.heading("Lights go brrrrr! (incomplete)");
|
||||
ui.separator();
|
||||
|
||||
let has_logo = supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::Logo);
|
||||
let has_lightbar = supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::BarLeft)
|
||||
|| supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::BarRight);
|
||||
|
||||
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootBar);
|
||||
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootLogo);
|
||||
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootKeyb);
|
||||
|
||||
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeBar);
|
||||
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeLogo);
|
||||
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeKeyb);
|
||||
|
||||
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepBar);
|
||||
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepLogo);
|
||||
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepKeyb);
|
||||
|
||||
let mut changed = false;
|
||||
|
||||
let mut item = |keyboard: &mut bool, logo: &mut bool, lightbar: &mut bool, ui: &mut Ui| {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
if ui.checkbox(keyboard, "Keyboard").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if has_logo && ui.checkbox(logo, "Logo").changed() {
|
||||
changed = true;
|
||||
}
|
||||
if has_lightbar && ui.checkbox(lightbar, "Lightbar").changed() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
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));
|
||||
});
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
item(boot_keyb, boot_logo, boot_bar, ui);
|
||||
item(awake_keyb, awake_logo, awake_bar, ui);
|
||||
item(sleep_keyb, sleep_logo, sleep_bar, ui);
|
||||
});
|
||||
});
|
||||
|
||||
if changed {
|
||||
let mut enabled = Vec::new();
|
||||
let mut disabled = Vec::new();
|
||||
|
||||
let mut modify = |b: bool, a: AuraDev19b6| {
|
||||
if b {
|
||||
enabled.push(a);
|
||||
if !enabled_states.x19b6.contains(&a) {
|
||||
enabled_states.x19b6.push(a);
|
||||
}
|
||||
} else {
|
||||
disabled.push(a);
|
||||
// This would be so much better as a hashset
|
||||
if enabled_states.x19b6.contains(&a) {
|
||||
let mut idx = 0;
|
||||
for (i, n) in enabled_states.x19b6.iter().enumerate() {
|
||||
if *n == a {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enabled_states.x1866.remove(idx);
|
||||
}
|
||||
}
|
||||
};
|
||||
modify(*boot_keyb, AuraDev19b6::BootKeyb);
|
||||
modify(*sleep_keyb, AuraDev19b6::SleepKeyb);
|
||||
modify(*awake_keyb, AuraDev19b6::AwakeKeyb);
|
||||
if supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::Logo)
|
||||
{
|
||||
modify(*boot_logo, AuraDev19b6::BootLogo);
|
||||
modify(*sleep_logo, AuraDev19b6::SleepLogo);
|
||||
modify(*awake_logo, AuraDev19b6::AwakeLogo);
|
||||
}
|
||||
if supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::BarLeft)
|
||||
{
|
||||
modify(*boot_bar, AuraDev19b6::BootBar);
|
||||
modify(*sleep_bar, AuraDev19b6::SleepBar);
|
||||
modify(*awake_bar, AuraDev19b6::AwakeBar);
|
||||
}
|
||||
|
||||
let mut send = |enable: bool, data: Vec<AuraDev19b6>| {
|
||||
let options = AuraPowerDev {
|
||||
x1866: vec![],
|
||||
x19b6: data,
|
||||
};
|
||||
// build data to send
|
||||
dbus.proxies()
|
||||
.led()
|
||||
.set_leds_power(options, enable)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
send(true, enabled);
|
||||
send(false, disabled);
|
||||
}
|
||||
}
|
||||
|
||||
fn aura_modes(
|
||||
supported: &SupportedFunctions,
|
||||
states: &mut PageDataStates,
|
||||
dbus: &mut RogDbusClientBlocking,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
let mut changed = false;
|
||||
let mut selected = states.aura.current_mode;
|
||||
|
||||
let has_keyzones = supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::Key2);
|
||||
let has_logo = supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::Logo);
|
||||
let has_lightbar = supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::BarLeft)
|
||||
|| supported
|
||||
.keyboard_led
|
||||
.multizone_led_mode
|
||||
.contains(&AuraZone::BarRight);
|
||||
|
||||
ui.heading("Aura modes");
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Need some sort of mapping to enable options only if
|
||||
// they actually work.
|
||||
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| {
|
||||
ui.selectable_value(&mut effect.speed, a, format!("{:?}", a));
|
||||
};
|
||||
let mut dir_button = |a: rog_aura::Direction, ui: &mut Ui| {
|
||||
ui.selectable_value(&mut effect.direction, a, format!("{:?}", a));
|
||||
};
|
||||
|
||||
let mut c1: [f32; 3] = effect.colour1.into();
|
||||
let mut c2: [f32; 3] = effect.colour2.into();
|
||||
|
||||
ui.separator();
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.vertical(|ui| {
|
||||
let h = 16.0;
|
||||
ui.set_row_height(22.0);
|
||||
if has_keyzones || has_lightbar || has_logo {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Zone").size(h));
|
||||
});
|
||||
}
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Colour 1").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Colour 2").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Speed").size(h));
|
||||
});
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.label(RichText::new("Direction").size(h));
|
||||
});
|
||||
});
|
||||
ui.vertical(|ui| {
|
||||
ui.set_row_height(22.0);
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
egui::color_picker::color_edit_button_rgb(ui, &mut c1);
|
||||
egui::color_picker::color_edit_button_rgb(ui, &mut c2);
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
speed_button(Speed::Low, ui);
|
||||
speed_button(Speed::Med, ui);
|
||||
speed_button(Speed::High, ui);
|
||||
});
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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() {
|
||||
let notif = states.aura.was_notified.clone();
|
||||
states.aura.modes = AuraState::new(notif, supported, dbus).modes;
|
||||
}
|
||||
|
||||
if ui.add(egui::Button::new("Apply")).clicked() {
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
|
||||
// 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(egui::Button::new("Cancel")).clicked() {
|
||||
// let notif = states.aura.was_notified.clone();
|
||||
// states.aura.modes = AuraState::new(notif, supported, dbus).modes;
|
||||
// }
|
||||
|
||||
// if ui.add(egui::Button::new("Apply")).clicked() {
|
||||
// changed = true;
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
if changed {
|
||||
states.aura.current_mode = selected;
|
||||
|
||||
dbus.proxies()
|
||||
.led()
|
||||
.set_led_mode(states.aura.modes.get(&selected).unwrap())
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
199
rog-control-center/src/widgets/fan_curve_page.rs
Normal file
199
rog-control-center/src/widgets/fan_curve_page.rs
Normal file
@@ -0,0 +1,199 @@
|
||||
use crate::{
|
||||
page_states::{FanCurvesState, ProfilesState},
|
||||
RogApp,
|
||||
};
|
||||
use egui::{plot::Points, Ui};
|
||||
use rog_dbus::RogDbusClientBlocking;
|
||||
use rog_profiles::{FanCurvePU, Profile};
|
||||
use rog_supported::SupportedFunctions;
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn fan_curve_page(&mut self, ctx: &egui::Context) {
|
||||
let Self {
|
||||
supported,
|
||||
states,
|
||||
asus_dbus: dbus,
|
||||
..
|
||||
} = self;
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.heading("Custom fan curves");
|
||||
ui.label("A fan curve is only active when the related profile is active and the curve is enabled");
|
||||
Self::fan_curve(
|
||||
supported,
|
||||
&mut states.profiles,
|
||||
&mut states.fan_curves,
|
||||
dbus, &mut states.error,
|
||||
ui,
|
||||
);
|
||||
|
||||
Self::fan_graphs(&mut states.profiles, &mut states.fan_curves, dbus, &mut states.error, ui);
|
||||
});
|
||||
}
|
||||
|
||||
fn fan_curve(
|
||||
supported: &SupportedFunctions,
|
||||
profiles: &mut ProfilesState,
|
||||
curves: &mut FanCurvesState,
|
||||
dbus: &RogDbusClientBlocking,
|
||||
do_error: &mut Option<String>,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
ui.separator();
|
||||
ui.label("Enabled fan-curves");
|
||||
|
||||
let mut changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
let mut item = |p: Profile, _curves: &mut FanCurvesState, mut checked: bool| {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(&mut checked, format!("{:?}", p)))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_fan_curve_enabled(p, checked)
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
|
||||
#[cfg(feature = "mocking")]
|
||||
if !checked {
|
||||
_curves.enabled.remove(&p);
|
||||
} else {
|
||||
_curves.enabled.insert(p);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
for f in profiles.list.iter() {
|
||||
item(*f, curves, curves.enabled.contains(f));
|
||||
}
|
||||
});
|
||||
|
||||
if changed {
|
||||
// Need to update app data if change made
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
{
|
||||
let notif = curves.was_notified.clone();
|
||||
*curves = FanCurvesState::new(notif, supported, dbus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fan_graphs(
|
||||
profiles: &mut ProfilesState,
|
||||
curves: &mut FanCurvesState,
|
||||
dbus: &RogDbusClientBlocking,
|
||||
do_error: &mut Option<String>,
|
||||
ui: &mut Ui,
|
||||
) {
|
||||
ui.separator();
|
||||
|
||||
let mut item = |p: Profile, ui: &mut Ui| {
|
||||
ui.selectable_value(&mut curves.show_curve, p, format!("{p:?}"));
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for a in curves.curves.iter() {
|
||||
item(*a.0, ui);
|
||||
}
|
||||
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::CPU,
|
||||
format!("{:?}", FanCurvePU::CPU),
|
||||
);
|
||||
ui.selectable_value(
|
||||
&mut curves.show_graph,
|
||||
FanCurvePU::GPU,
|
||||
format!("{:?}", FanCurvePU::GPU),
|
||||
);
|
||||
});
|
||||
|
||||
let curve = curves.curves.get_mut(&curves.show_curve).unwrap();
|
||||
|
||||
use egui::plot::{Line, Plot, PlotPoints};
|
||||
|
||||
let data = if curves.show_graph == FanCurvePU::CPU {
|
||||
&mut curve.cpu
|
||||
} else {
|
||||
&mut curve.gpu
|
||||
};
|
||||
|
||||
let points = 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]
|
||||
});
|
||||
|
||||
let line = Line::new(PlotPoints::from_iter(points.clone())).width(2.0);
|
||||
let points = Points::new(PlotPoints::from_iter(points)).radius(3.0);
|
||||
|
||||
Plot::new("my_plot")
|
||||
.view_aspect(2.0)
|
||||
// .center_x_axis(true)
|
||||
// .center_y_axis(true)
|
||||
.include_x(0.0)
|
||||
.include_x(110.0)
|
||||
.include_y(0.0)
|
||||
.include_y(110.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 = 255;
|
||||
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)
|
||||
});
|
||||
|
||||
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {
|
||||
if ui.add(egui::Button::new("Apply Fan-curve")).clicked() {
|
||||
#[cfg(not(feature = "mocking"))]
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_fan_curve(profiles.current, data.clone())
|
||||
.map_err(|err| {
|
||||
*do_error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
#[cfg(feature = "mocking")]
|
||||
dbg!("Applied");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
13
rog-control-center/src/widgets/mod.rs
Normal file
13
rog-control-center/src/widgets/mod.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
mod anime_page;
|
||||
mod aura_page;
|
||||
mod fan_curve_page;
|
||||
mod side_panel;
|
||||
mod system_page;
|
||||
mod top_bar;
|
||||
|
||||
pub use anime_page::*;
|
||||
pub use aura_page::*;
|
||||
pub use fan_curve_page::*;
|
||||
pub use side_panel::*;
|
||||
pub use system_page::*;
|
||||
pub use top_bar::*;
|
||||
62
rog-control-center/src/widgets/side_panel.rs
Normal file
62
rog-control-center/src/widgets/side_panel.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use crate::{Page, RogApp};
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn side_panel(&mut self, ctx: &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.platform_profile.fan_curves || cfg!(feature = "mocking") {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::FanCurves, "Fan Curves")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::FanCurves;
|
||||
}
|
||||
}
|
||||
|
||||
if !self.supported.keyboard_led.stock_led_modes.is_empty()
|
||||
|| cfg!(feature = "mocking")
|
||||
{
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::AuraEffects, "Keyboard Aura")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::AuraEffects;
|
||||
}
|
||||
}
|
||||
|
||||
if self.supported.anime_ctrl.0 || cfg!(feature = "mocking") {
|
||||
ui.separator();
|
||||
if ui
|
||||
.selectable_value(page, Page::AnimeMatrix, "AniMe Matrix")
|
||||
.clicked()
|
||||
{
|
||||
*page = Page::AnimeMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
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/rog-gui");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
117
rog-control-center/src/widgets/system_page.rs
Normal file
117
rog-control-center/src/widgets/system_page.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use crate::{page_states::PageDataStates, RogApp};
|
||||
use egui::Ui;
|
||||
use rog_dbus::RogDbusClientBlocking;
|
||||
use rog_profiles::Profile;
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn system_page(&mut self, ctx: &egui::Context) {
|
||||
let Self {
|
||||
supported,
|
||||
states,
|
||||
asus_dbus: dbus,
|
||||
..
|
||||
} = self;
|
||||
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
// The central panel the region left after adding TopPanel's and SidePanel's
|
||||
|
||||
ui.heading("Experimental application for asusd");
|
||||
ui.horizontal(|ui| {
|
||||
egui::global_dark_light_mode_buttons(ui);
|
||||
egui::warn_if_debug_build(ui);
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
|
||||
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||
ui.heading("Charge control");
|
||||
let slider = egui::Slider::new(&mut states.charge_limit, 20..=100)
|
||||
.text("Limit")
|
||||
.step_by(1.0);
|
||||
if ui.add(slider).drag_released() {
|
||||
dbus.proxies()
|
||||
.charge()
|
||||
.set_limit(states.charge_limit as u8)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
ui.heading("Bios options");
|
||||
|
||||
if supported.rog_bios_ctrl.post_sound {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(
|
||||
&mut states.bios.post_sound,
|
||||
"POST sound",
|
||||
))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.rog_bios()
|
||||
.set_post_boot_sound(states.bios.post_sound)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if supported.rog_bios_ctrl.dedicated_gfx {
|
||||
if ui
|
||||
.add(egui::Checkbox::new(
|
||||
&mut states.bios.dedicated_gfx,
|
||||
"G-Sync Dedicated GPU mode",
|
||||
))
|
||||
.changed()
|
||||
{
|
||||
dbus.proxies()
|
||||
.rog_bios()
|
||||
.set_dedicated_graphic_mode(states.bios.dedicated_gfx)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
|
||||
if supported.platform_profile.platform_profile {
|
||||
Self::platform_profile(states, dbus, ui);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn platform_profile(states: &mut PageDataStates, dbus: &RogDbusClientBlocking, ui: &mut Ui) {
|
||||
ui.separator();
|
||||
ui.heading("Platform profile");
|
||||
|
||||
let mut changed = false;
|
||||
let mut item = |p: Profile, ui: &mut Ui| {
|
||||
if ui
|
||||
.selectable_value(&mut states.profiles.current, p, format!("{p:?}"))
|
||||
.clicked()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
};
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
for a in states.profiles.list.iter() {
|
||||
item(*a, ui);
|
||||
}
|
||||
});
|
||||
|
||||
if changed {
|
||||
dbus.proxies()
|
||||
.profile()
|
||||
.set_active_profile(states.profiles.current)
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
};
|
||||
}
|
||||
}
|
||||
53
rog-control-center/src/widgets/top_bar.rs
Normal file
53
rog-control-center/src/widgets/top_bar.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use crate::RogApp;
|
||||
|
||||
impl<'a> RogApp<'a> {
|
||||
pub fn top_bar(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
|
||||
let Self { states, config, .. } = self;
|
||||
|
||||
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.menu_button("File", |ui| {
|
||||
if ui.button("Quit").clicked() {
|
||||
frame.quit();
|
||||
}
|
||||
});
|
||||
ui.menu_button("Settings", |ui| {
|
||||
let (mut in_bg, mut hidden) =
|
||||
{ (config.run_in_background, config.startup_in_background) };
|
||||
if ui.checkbox(&mut in_bg, "Run in Background").clicked() {
|
||||
config.run_in_background = in_bg;
|
||||
config
|
||||
.save()
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
if ui.checkbox(&mut hidden, "Startup Hidden").clicked() {
|
||||
config.startup_in_background = in_bg;
|
||||
config
|
||||
.save()
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
if ui
|
||||
.checkbox(&mut config.enable_notifications, "Enable Notifications")
|
||||
.clicked()
|
||||
{
|
||||
config.enable_notifications = in_bg;
|
||||
// TODO: set an atomicbool used in the notif thread
|
||||
config
|
||||
.save()
|
||||
.map_err(|err| {
|
||||
states.error = Some(err.to_string());
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user