use derive_builder::Builder;
use sorted_vec::SortedSet;
use serde::{Deserialize, Serialize};
use crate::{interface, Tree};
use crate::tree::NodeId;
#[macro_use] mod macro_def;
pub mod axis;
pub mod button;
pub mod motion;
pub mod pointer;
pub mod system;
pub mod text;
pub mod wheel;
pub use self::axis::Axis;
pub use self::button::Button;
pub use self::motion::Motion;
pub use self::pointer::Pointer;
pub use self::system::System;
pub use self::text::Text;
pub use self::wheel::Wheel;
pub use ControlsBuilder as Builder;
#[derive(Clone, Debug, Default, Builder)]
#[builder(pattern="owned", build_fn(skip), setter(strip_option))]
pub struct Controls {
#[builder(default)]
pub buttons : SortedSet <Button>,
#[builder(default)]
pub any_button : Option <Button>,
#[builder(default)]
pub system : Option <System>,
#[builder(default)]
pub text : Option <Text>,
#[builder(default)]
pub motion : Option <Motion>,
#[builder(default)]
pub pointer : Option <Pointer>
}
pub trait Id <C : Control> : Clone + Eq + PartialEq + Into <Fun <C::Payload>> + Into <C>
+ TryFrom <C, Error = C> + std::fmt::Debug + Serialize + serde::de::DeserializeOwned
{ }
#[derive(Clone)]
#[expect(clippy::type_complexity)]
pub struct Fun <P> (pub fn (
&P,
&Tree <interface::Element>,
&NodeId,
&mut Vec <(NodeId, interface::Action)>
));
pub type ReprType = u16;
pub trait Control : Clone + Sized + From <ReprType> + AsRef <ReprType>
+ std::fmt::Debug
{
type Payload;
type Builtin : Id <Self>;
fn fun <E : Id <Self>> (self) -> Fun <Self::Payload> {
use std::convert::TryFrom;
match Self::Builtin::try_from (self) {
Ok (builtin) => builtin.into(),
Err (control) => match E::try_from (control) {
Ok (extended) => extended.into(),
Err (_control) => unreachable!()
}
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub enum Nil {}
impl <P> From <Nil> for Fun <P> {
fn from (_ : Nil) -> Self {
unreachable!()
}
}
impl <P> std::fmt::Debug for Fun <P> {
fn fmt (&self, f : &mut std::fmt::Formatter) -> Result <(), std::fmt::Error> {
write!(f, "Fun({:p})", &self.0)
}
}
impl ControlsBuilder {
pub const fn new() -> Self {
ControlsBuilder {
buttons: None,
any_button: None,
system: None,
text: None,
motion: None,
pointer: None
}
}
pub fn build (self) -> Controls {
Controls {
buttons: self.buttons.unwrap_or_default(),
any_button: self.any_button.unwrap_or_default(),
system: self.system.unwrap_or_default(),
text: self.text.unwrap_or_default(),
motion: self.motion.unwrap_or_default(),
pointer: self.pointer.unwrap_or_default()
}
}
}