New struct to simplify tray handling and the device state is now updated more efficiently.

This commit is contained in:
lennard
2023-06-11 14:32:34 +02:00
parent 1caaab5fb3
commit 76427f1381
3 changed files with 89 additions and 50 deletions

View File

@@ -1,10 +1,30 @@
use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip}; use hyper_x_cloud_ii_wireless::Device;
use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip, TrayService, Handle};
pub struct TrayHandler {
handle: Handle<BatteryTray>,
}
impl TrayHandler {
pub fn new() -> Self {
let tray_service = TrayService::new(BatteryTray::new());
let handle = tray_service.handle();
tray_service.spawn();
TrayHandler {
handle,
}
}
pub fn update(&self, device: &Device) {
self.handle.update(|tray: &mut BatteryTray| { tray.update(device); })
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct BatteryTray { pub struct BatteryTray {
battery_level: u8, battery_level: u8,
charging: bool, charging: bool,
device_found: bool, status_message: Option<String>,
} }
impl BatteryTray { impl BatteryTray {
@@ -12,18 +32,21 @@ impl BatteryTray {
BatteryTray { BatteryTray {
battery_level: 0, battery_level: 0,
charging: false, charging: false,
device_found: false, status_message: Some("No device found".to_string()),
} }
} }
pub fn update(&mut self, battery_level: u8, charging: bool) { pub fn update(&mut self, device: &Device) {
self.device_found = true; self.battery_level = device.battery_level;
self.battery_level = battery_level; self.charging = device.charging;
self.charging = charging;
} }
pub fn no_device_found(&mut self) { pub fn set_status_message(&mut self, message: &str) {
self.device_found = false; self.status_message = Some(message.to_string());
}
pub fn clear_status_message(&mut self) {
self.status_message = None;
} }
} }
@@ -43,17 +66,20 @@ impl Tray for BatteryTray {
] ]
} }
fn tool_tip(&self) -> ToolTip { fn tool_tip(&self) -> ToolTip {
let description = let status =
if !self.device_found { match &self.status_message {
"No device found".to_string() Some(m) => m,
} else if self.charging { None => "",
};
let state =
if self.charging {
format!("Battery level: {}%\nCharging", self.battery_level) format!("Battery level: {}%\nCharging", self.battery_level)
} else { } else {
format!("Battery level: {}%\nNot charging", self.battery_level) format!("Battery level: {}%\nNot charging", self.battery_level)
}; };
ToolTip { ToolTip {
title: "HyperX Cloud II".to_string(), title: "HyperX Cloud II".to_string(),
description: description, description: format!("{}\n{}", status, state),
icon_name: "".into(), icon_name: "".into(),
icon_pixmap: Vec::new(), icon_pixmap: Vec::new(),
} }

View File

@@ -1,14 +1,14 @@
use hyper_x_cloud_ii_wireless::Device; use hyper_x_cloud_ii_wireless::Device;
fn main() { fn main() {
let device = match Device::new() { let mut device = match Device::new() {
Ok(device) => device, Ok(device) => device,
Err(error) => { Err(error) => {
eprintln!("{error}"); eprintln!("{error}");
std::process::exit(1); std::process::exit(1);
} }
}; };
let (battery_level, charging) = match device.get_battery_level() { let (battery_level, _) = match device.update_battery_level() {
Ok(t) => t, Ok(t) => t,
Err(error) => { Err(error) => {
eprintln!("{error}"); eprintln!("{error}");
@@ -16,9 +16,4 @@ fn main() {
} }
}; };
println!("Battery level: {}%", battery_level); println!("Battery level: {}%", battery_level);
if charging {
println!("Charging");
} else {
println!("Not charging");
}
} }

View File

@@ -1,7 +1,8 @@
use std::time::Duration;
use hyper_x_cloud_ii_wireless::{Device, DeviceError}; use hyper_x_cloud_ii_wireless::{Device, DeviceError};
use ksni::TrayService;
mod battery_tray; mod battery_tray;
use battery_tray::BatteryTray; use battery_tray::TrayHandler;
fn pair_device() -> Device { fn pair_device() -> Device {
loop { loop {
@@ -15,41 +16,58 @@ fn pair_device() -> Device {
} }
} }
fn main() { //TODO: status messages
let service = TrayService::new(BatteryTray::new()); //TODO: use mute state
let handle = service.handle(); //TODO: make trayHandler dynamic
service.spawn();
fn handle_error(error: DeviceError, device: &mut Device, tray_handler: &TrayHandler) {
match error {
DeviceError::HidError(hidapi::HidError::HidApiError { message }) => {
if message == "No such device" {
eprintln!("No device found.");
// handle.update(|tray: &mut BatteryTray| { tray.set_status_message("No device found"); });
*device = pair_device();
} else {
eprintln!("{message}");
}
}
DeviceError::NoDeviceFound() => {
eprintln!("{}", DeviceError::NoDeviceFound());
// handle.update(|tray: &mut BatteryTray| { tray.set_status_message("No device found"); });
}
DeviceError::HeadSetOff() => {
eprintln!("{}", DeviceError::HeadSetOff());
// handle.update(|tray: &mut BatteryTray| { tray.set_status_message(&DeviceError::HeadSetOff().to_string()); });
}
error => {
eprintln!("{error}");
}
}
}
fn main() {
let tray_handler = TrayHandler::new();
let mut device = pair_device(); let mut device = pair_device();
tray_handler.update(&device);
// Run loop // Run loop
loop { loop {
std::thread::sleep(std::time::Duration::from_secs(1)); std::thread::sleep(std::time::Duration::from_secs(1));
let (battery_level, charging) = match device.get_battery_level() { match device.update_battery_level() {
Ok(t) => t, Ok(_) => {
Err(DeviceError::HidError(hidapi::HidError::HidApiError { message })) => { tray_handler.update(&device);
eprintln!("Error: {message}"); },
if message == "No such device" {
handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); });
device = pair_device();
}
continue;
}
Err(DeviceError::NoDeviceFound()) => {
eprintln!("{}", DeviceError::NoDeviceFound());
handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); });
continue;
}
Err(DeviceError::HeadSetOff()) => {
eprintln!("{}", DeviceError::HeadSetOff());
handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); });
continue;
}
Err(error) => { Err(error) => {
eprintln!("{error}"); handle_error(error, &mut device, &tray_handler);
continue;
},
};
match device.wait_for_updates(Duration::from_secs(30)) {
Ok(_) => tray_handler.update(&device),
Err(error) => {
handle_error(error, &mut device, &tray_handler);
continue; continue;
} }
}; }
handle.update(|tray: &mut BatteryTray| { tray.update(battery_level, charging); });
} }
} }