ROGCC: rog-aura: Keyboard layout templates and definitions

This also removes shell completitions as these are not maintained.
This commit is contained in:
Luke D. Jones
2022-07-27 15:03:08 +12:00
parent 8f65b7e334
commit e99d8766fc
22 changed files with 1617 additions and 317 deletions

View File

@@ -1,10 +1,13 @@
use rog_aura::layouts::KeyLayout;
use rog_control_center::{
config::Config, get_ipc_file, notify::start_notifications, on_tmp_dir_exists,
page_states::PageDataStates, RogApp, RogDbusClientBlocking, SHOW_GUI,
};
use std::{
fs::{self, OpenOptions},
io::Read,
path::PathBuf,
sync::{
atomic::{AtomicBool, Ordering},
Arc,
@@ -13,6 +16,9 @@ use std::{
time::Duration,
};
const DATA_DIR: &str = "/usr/share/rog-gui/";
const BOARD_NAME: &str = "/sys/class/dmi/id/board_name";
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Startup
let mut config = Config::load()?;
@@ -23,6 +29,31 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
config.save()?;
}
// Find and load a matching layout for laptop
let mut file = OpenOptions::new()
.read(true)
.open(PathBuf::from(BOARD_NAME))
.map_err(|e| {
println!("{BOARD_NAME}, {e}");
e
})?;
let mut board_name = String::new();
file.read_to_string(&mut board_name)?;
let mut layout = KeyLayout::ga401_layout(); // default
let mut path = PathBuf::from(DATA_DIR);
path.push("layouts");
for path in fs::read_dir(path).map_err(|e| {
println!("{DATA_DIR}, {e}");
e
})? {
let tmp = KeyLayout::from_file(&path?.path()).unwrap();
if tmp.matches(board_name.as_str()) {
layout = tmp;
break;
}
}
// Cheap method to alert to notifications rather than spinning a thread for each
// This is quite different when done in a retained mode app
let charge_notified = Arc::new(AtomicBool::new(false));
@@ -37,6 +68,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let (dbus, _) = RogDbusClientBlocking::new()?;
let supported = dbus.proxies().supported().supported_functions().unwrap();
PageDataStates::new(
layout,
notifs_enabled.clone(),
charge_notified.clone(),
bios_notified.clone(),

View File

@@ -7,7 +7,7 @@ use std::{
};
use egui::Vec2;
use rog_aura::{usb::AuraPowerDev, AuraEffect, AuraModeNum};
use rog_aura::{layouts::KeyLayout, usb::AuraPowerDev, AuraEffect, AuraModeNum};
use rog_profiles::{fan_curve_set::FanCurveSet, FanCurvePU, Profile};
use rog_supported::SupportedFunctions;
@@ -226,6 +226,7 @@ impl AnimeState {
#[derive(Debug)]
pub struct PageDataStates {
pub keyboard_layout: KeyLayout,
pub notifs_enabled: Arc<AtomicBool>,
pub was_notified: Arc<AtomicBool>,
/// Because much of the app state here is the same as `RogBiosSupportedFunctions`
@@ -241,6 +242,7 @@ pub struct PageDataStates {
impl PageDataStates {
pub fn new(
keyboard_layout: KeyLayout,
notifs_enabled: Arc<AtomicBool>,
charge_notified: Arc<AtomicBool>,
bios_notified: Arc<AtomicBool>,
@@ -252,6 +254,7 @@ impl PageDataStates {
dbus: &RogDbusClientBlocking,
) -> Result<Self> {
Ok(Self {
keyboard_layout,
notifs_enabled,
was_notified: charge_notified,
charge_limit: dbus.proxies().charge().limit()?,
@@ -308,6 +311,7 @@ impl PageDataStates {
impl Default for PageDataStates {
fn default() -> Self {
Self {
keyboard_layout: KeyLayout::ga401_layout(),
notifs_enabled: Default::default(),
was_notified: Default::default(),
bios: BiosState {

View File

@@ -1,3 +1,6 @@
use egui::{Color32, Vec2};
use rog_aura::keys::KeyShape;
use crate::{widgets::aura_modes_group, RogApp};
impl<'a> RogApp<'a> {
@@ -9,8 +12,85 @@ impl<'a> RogApp<'a> {
..
} = self;
let c = states
.aura
.modes
.get(&states.aura.current_mode)
.unwrap()
.colour1;
let colour = Color32::from_rgb(c.0, c.1, c.2);
// TODO: animation of colour changes/periods/blending
egui::CentralPanel::default().show(ctx, |ui| {
aura_modes_group(supported, states, dbus, ui);
ui.spacing_mut().item_spacing = egui::vec2(0.0, 0.0);
for row in states.keyboard_layout.rows() {
ui.horizontal(|ui| {
for key in row.row() {
// your boat
let shape = KeyShape::from(key);
if shape.is_blank() || shape.is_spacer() {
blank(ui, shape);
} else if shape.is_group() {
let label = format!("{key:?}");
key_group(ui, colour, shape.ux(), shape.uy()).on_hover_text(label);
} else {
let label = format!("{key:?}");
key_shape(ui, colour, shape).on_hover_text(label);
}
}
});
}
});
}
}
fn key_shape(ui: &mut egui::Ui, colour: Color32, shape: KeyShape) -> egui::Response {
let desired_size =
ui.spacing().interact_size.y * egui::vec2(2.0 * shape.ux(), 2.0 * shape.uy());
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) {
let visuals = ui.style().interact_selectable(&response, true);
let rect = rect.expand(visuals.expansion);
ui.painter().rect(rect, 0.1, colour, visuals.fg_stroke);
}
response
}
fn key_group(ui: &mut egui::Ui, colour: Color32, ux: f32, uy: f32) -> egui::Response {
let desired_size = ui.spacing().interact_size.y * egui::vec2(2.0 * ux, 2.0 * uy);
let (mut rect, mut response) = ui.allocate_exact_size(desired_size, egui::Sense::click());
rect = rect.shrink2(Vec2::new(3.0, 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) {
let visuals = ui.style().interact_selectable(&response, true);
let rect = rect.expand(visuals.expansion);
let mut stroke = visuals.fg_stroke;
stroke.color = visuals.bg_fill;
ui.painter().rect(rect, 0.1, colour, stroke);
}
response
}
fn blank(ui: &mut egui::Ui, shape: KeyShape) {
let desired_size =
ui.spacing().interact_size.y * egui::vec2(2.0 * shape.ux(), 2.0 * shape.uy());
ui.allocate_exact_size(desired_size, egui::Sense::click());
}