More framework implementation
This commit is contained in:
parent
beb24e985e
commit
ec70ed2c51
1
Linux/Cargo.lock
generated
1
Linux/Cargo.lock
generated
@ -10,6 +10,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"min-rs",
|
"min-rs",
|
||||||
"platform-dirs",
|
"platform-dirs",
|
||||||
|
"regex",
|
||||||
"relm4",
|
"relm4",
|
||||||
"relm4-icons",
|
"relm4-icons",
|
||||||
"rust-i18n",
|
"rust-i18n",
|
||||||
|
@ -8,6 +8,7 @@ build = "build.rs"
|
|||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
log = "0.4.21"
|
log = "0.4.21"
|
||||||
platform-dirs = "0.3.0"
|
platform-dirs = "0.3.0"
|
||||||
|
regex = "1.10.5"
|
||||||
relm4 = "0.8.1"
|
relm4 = "0.8.1"
|
||||||
relm4-icons = "0.8.3"
|
relm4-icons = "0.8.3"
|
||||||
rust-i18n = "3.0.1"
|
rust-i18n = "3.0.1"
|
||||||
|
7
Linux/locales/actions/pipewire.yaml
Normal file
7
Linux/locales/actions/pipewire.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
_version: 2
|
||||||
|
|
||||||
|
actions:
|
||||||
|
pipewire:
|
||||||
|
set_volume:
|
||||||
|
name:
|
||||||
|
en: Set volume
|
6
Linux/locales/devices/emulator.yaml
Normal file
6
Linux/locales/devices/emulator.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
_version: 2
|
||||||
|
|
||||||
|
devices:
|
||||||
|
emulator:
|
||||||
|
name:
|
||||||
|
en: Emulator
|
6
Linux/locales/devices/serial_min.yaml
Normal file
6
Linux/locales/devices/serial_min.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
_version: 2
|
||||||
|
|
||||||
|
devices:
|
||||||
|
serial_min:
|
||||||
|
name:
|
||||||
|
en: Serial device using MIN protocol
|
@ -1,8 +1,32 @@
|
|||||||
pub mod registry;
|
|
||||||
pub mod pipewire;
|
pub mod pipewire;
|
||||||
|
|
||||||
|
use crate::registry::MkRegistry;
|
||||||
|
use crate::registry::RegistryItem;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
pub fn register()
|
|
||||||
|
pub struct MkAction
|
||||||
{
|
{
|
||||||
pipewire::register();
|
pub unique_id: UniqueId
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl RegistryItem for MkAction
|
||||||
|
{
|
||||||
|
fn unique_id(&self) -> UniqueId
|
||||||
|
{
|
||||||
|
self.unique_id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String
|
||||||
|
{
|
||||||
|
t!(format!("actions.{}.name", self.unique_id.as_str()).as_str()).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub fn register(registry: &mut MkRegistry<MkAction>)
|
||||||
|
{
|
||||||
|
pipewire::register(registry);
|
||||||
}
|
}
|
@ -1,10 +1,14 @@
|
|||||||
use super::registry::{MkAction, register_action};
|
use crate::registry::MkRegistry;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
use super::MkAction;
|
||||||
|
|
||||||
pub mod set_volume;
|
pub mod set_volume;
|
||||||
|
|
||||||
|
|
||||||
pub fn register()
|
pub fn register(registry: &mut MkRegistry<MkAction>)
|
||||||
{
|
{
|
||||||
register_action(MkAction::new("Set volume"));
|
registry.register(MkAction
|
||||||
|
{
|
||||||
|
unique_id: UniqueId::new("pipewire.set_volume")
|
||||||
|
});
|
||||||
}
|
}
|
@ -1,26 +0,0 @@
|
|||||||
use log::info;
|
|
||||||
|
|
||||||
|
|
||||||
pub struct MkAction
|
|
||||||
{
|
|
||||||
// TODO prepare for i18n by making this a translation key?
|
|
||||||
name: &'static str
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl MkAction
|
|
||||||
{
|
|
||||||
pub fn new(name: &'static str) -> Self
|
|
||||||
{
|
|
||||||
Self
|
|
||||||
{
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn register_action(action: MkAction)
|
|
||||||
{
|
|
||||||
info!("Registered action: {}", action.name);
|
|
||||||
}
|
|
@ -2,10 +2,11 @@ use std::path::{Path, PathBuf};
|
|||||||
use std::io::{Error, Read, Write};
|
use std::io::{Error, Read, Write};
|
||||||
use platform_dirs::AppDirs;
|
use platform_dirs::AppDirs;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Config
|
pub struct Config
|
||||||
{
|
{
|
||||||
root: PathBuf
|
root: PathBuf,
|
||||||
|
pub device_id: Option<String>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +18,8 @@ impl Config
|
|||||||
|
|
||||||
Self
|
Self
|
||||||
{
|
{
|
||||||
root: appdirs.data_dir
|
root: appdirs.data_dir,
|
||||||
|
device_id: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
//use emulatorwindow::EmulatorWindow;
|
use crate::registry::MkRegistry;
|
||||||
//use relm4::prelude::*;
|
use crate::util::unique_id::UniqueId;
|
||||||
//use relm4::gtk::prelude::GtkApplicationExt;
|
use super::MkDevice;
|
||||||
|
|
||||||
|
|
||||||
use super::registry::{MkDevice, register_device};
|
|
||||||
|
|
||||||
|
|
||||||
pub mod emulatorwindow;
|
pub mod emulatorwindow;
|
||||||
|
|
||||||
|
|
||||||
pub fn register()
|
|
||||||
|
|
||||||
|
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
||||||
{
|
{
|
||||||
register_device(MkDevice::new("Emulator"));
|
registry.register(MkDevice {
|
||||||
|
unique_id: UniqueId::new("emulator")
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
pub mod registry;
|
|
||||||
pub mod emulator;
|
pub mod emulator;
|
||||||
pub mod serial_min;
|
pub mod serial_min;
|
||||||
|
|
||||||
|
|
||||||
pub fn register()
|
use crate::registry::MkRegistry;
|
||||||
|
use crate::registry::RegistryItem;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct MkDevice
|
||||||
{
|
{
|
||||||
emulator::register();
|
pub unique_id: UniqueId
|
||||||
serial_min::register();
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl RegistryItem for MkDevice
|
||||||
|
{
|
||||||
|
fn unique_id(&self) -> UniqueId
|
||||||
|
{
|
||||||
|
self.unique_id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String
|
||||||
|
{
|
||||||
|
t!(format!("devices.{}.name", self.unique_id.as_str()).as_str()).to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
||||||
|
{
|
||||||
|
emulator::register(registry);
|
||||||
|
serial_min::register(registry);
|
||||||
}
|
}
|
@ -1,26 +0,0 @@
|
|||||||
use log::info;
|
|
||||||
|
|
||||||
|
|
||||||
pub struct MkDevice
|
|
||||||
{
|
|
||||||
// TODO prepare for i18n by making this a translation key?
|
|
||||||
name: &'static str
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl MkDevice
|
|
||||||
{
|
|
||||||
pub fn new(name: &'static str) -> Self
|
|
||||||
{
|
|
||||||
Self
|
|
||||||
{
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn register_device(action: MkDevice)
|
|
||||||
{
|
|
||||||
info!("Registered device: {}", action.name);
|
|
||||||
}
|
|
@ -1,7 +1,11 @@
|
|||||||
use super::registry::{MkDevice, register_device};
|
use crate::registry::MkRegistry;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
use super::MkDevice;
|
||||||
|
|
||||||
|
|
||||||
pub fn register()
|
pub fn register(registry: &mut MkRegistry<MkDevice>)
|
||||||
{
|
{
|
||||||
register_device(MkDevice::new("Serial device using MIN protocol"));
|
registry.register(MkDevice {
|
||||||
|
unique_id: UniqueId::new("serial_min")
|
||||||
|
});
|
||||||
}
|
}
|
@ -1,4 +1,7 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
|
use mainwindow::MainWindowViewModel;
|
||||||
|
use orchestrator::Orchestrator;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -7,10 +10,13 @@ extern crate rust_i18n;
|
|||||||
i18n!("locales");
|
i18n!("locales");
|
||||||
|
|
||||||
|
|
||||||
|
pub mod util;
|
||||||
|
pub mod registry;
|
||||||
pub mod devices;
|
pub mod devices;
|
||||||
pub mod actions;
|
pub mod actions;
|
||||||
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
|
pub mod orchestrator;
|
||||||
pub mod mainwindow;
|
pub mod mainwindow;
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
@ -19,20 +25,13 @@ fn main()
|
|||||||
// .format_timestamp(None)
|
// .format_timestamp(None)
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
devices::register();
|
|
||||||
actions::register();
|
|
||||||
|
|
||||||
relm4_icons::initialize_icons();
|
relm4_icons::initialize_icons();
|
||||||
|
|
||||||
load_config();
|
let orchestrator = Rc::new(Orchestrator::new());
|
||||||
|
|
||||||
let app = RelmApp::new("com.github.mvrens.massiveknob");
|
let app = RelmApp::new("com.github.mvrens.massiveknob");
|
||||||
app.run::<mainwindow::MainWindow>(());
|
app.run::<mainwindow::MainWindow>(MainWindowViewModel
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fn load_config()
|
|
||||||
{
|
{
|
||||||
//let config = config::Config::new();
|
orchestrator: Rc::clone(&orchestrator)
|
||||||
//config.get_reader(name)
|
});
|
||||||
}
|
}
|
@ -1,11 +1,31 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use relm4::prelude::*;
|
use relm4::prelude::*;
|
||||||
|
|
||||||
|
use crate::orchestrator::Orchestrator;
|
||||||
|
|
||||||
pub struct MainWindow
|
pub struct MainWindow
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct MainWindowViewModel
|
||||||
|
{
|
||||||
|
pub orchestrator: Rc<Orchestrator>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl std::fmt::Debug for MainWindowViewModel
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
||||||
|
{
|
||||||
|
f.debug_struct("MainWindowViewModel")
|
||||||
|
// Skip orchestrator
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MainWindowMsg
|
pub enum MainWindowMsg
|
||||||
{
|
{
|
||||||
@ -19,7 +39,7 @@ pub struct MainWindowWidgets
|
|||||||
|
|
||||||
impl SimpleComponent for MainWindow
|
impl SimpleComponent for MainWindow
|
||||||
{
|
{
|
||||||
type Init = ();
|
type Init = MainWindowViewModel;
|
||||||
type Input = MainWindowMsg;
|
type Input = MainWindowMsg;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
type Root = gtk::Window;
|
type Root = gtk::Window;
|
||||||
|
53
Linux/src/orchestrator/mod.rs
Normal file
53
Linux/src/orchestrator/mod.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use crate::actions;
|
||||||
|
use crate::actions::MkAction;
|
||||||
|
use crate::config::Config;
|
||||||
|
use crate::devices;
|
||||||
|
use crate::devices::MkDevice;
|
||||||
|
use crate::registry::MkRegistry;
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct Orchestrator
|
||||||
|
{
|
||||||
|
config: Config,
|
||||||
|
|
||||||
|
device_registry: MkRegistry<MkDevice>,
|
||||||
|
action_registry: MkRegistry<MkAction>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Orchestrator
|
||||||
|
{
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
let config = Config::new();
|
||||||
|
//config.get_reader(name)
|
||||||
|
|
||||||
|
let mut device_registry = MkRegistry::new();
|
||||||
|
let mut action_registry = MkRegistry::new();
|
||||||
|
|
||||||
|
devices::register(&mut device_registry);
|
||||||
|
actions::register(&mut action_registry);
|
||||||
|
|
||||||
|
Self
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
device_registry,
|
||||||
|
action_registry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn current_device(&self) -> Option<&MkDevice>
|
||||||
|
{
|
||||||
|
let Some(device_id) = &self.config.device_id else { return None };
|
||||||
|
self.device_registry.by_id(UniqueId::new(device_id.as_str()))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn set_current_device_id(&self, id: &str)
|
||||||
|
{
|
||||||
|
// TODO if changed, unload old device, activate new
|
||||||
|
todo!("Store in config");
|
||||||
|
}
|
||||||
|
}
|
50
Linux/src/registry/mod.rs
Normal file
50
Linux/src/registry/mod.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
use crate::util::unique_id::UniqueId;
|
||||||
|
|
||||||
|
|
||||||
|
pub trait RegistryItem
|
||||||
|
{
|
||||||
|
/// The unique ID of the item. This should remain stable across releases for
|
||||||
|
/// the purpose of storing it in the user's configuration.
|
||||||
|
fn unique_id(&self) -> UniqueId;
|
||||||
|
|
||||||
|
/// The name of the item for display purposes.
|
||||||
|
fn name(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub struct MkRegistry<T> where T: RegistryItem
|
||||||
|
{
|
||||||
|
items: HashMap<String, T>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl<'a, T> MkRegistry<T> where T: RegistryItem
|
||||||
|
{
|
||||||
|
pub fn new() -> Self
|
||||||
|
{
|
||||||
|
Self
|
||||||
|
{
|
||||||
|
items: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn register(&mut self, device: T)
|
||||||
|
{
|
||||||
|
let device_id = device.unique_id();
|
||||||
|
|
||||||
|
info!("Registered device: [{}] {}", device_id.as_str(), device.name());
|
||||||
|
self.items.insert(String::from(device_id.as_str()), device);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn by_id(&self, id: UniqueId) -> Option<&T>
|
||||||
|
{
|
||||||
|
self.items.get(id.as_str())
|
||||||
|
}
|
||||||
|
}
|
1
Linux/src/util/mod.rs
Normal file
1
Linux/src/util/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod unique_id;
|
38
Linux/src/util/unique_id.rs
Normal file
38
Linux/src/util/unique_id.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct UniqueId
|
||||||
|
{
|
||||||
|
inner: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl UniqueId
|
||||||
|
{
|
||||||
|
pub fn new(id: &str) -> Self
|
||||||
|
{
|
||||||
|
assert!(is_valid_unique_id(id), "Id '{id}' has invalid characters");
|
||||||
|
UniqueId { inner: id.to_string() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str
|
||||||
|
{
|
||||||
|
self.inner.as_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn is_valid_unique_id(id: &str) -> bool
|
||||||
|
{
|
||||||
|
let re = Regex::new(r"^[a-zA-Z0-9\.\-_]+$").unwrap();
|
||||||
|
re.is_match(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Clone for UniqueId
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self
|
||||||
|
{
|
||||||
|
Self { inner: self.inner.clone() }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user