use std::cell::RefCell;
use serde_plain;
use smallvec::SmallVec;
use crate::interface::view::input;
use crate::tree::NodeId;
use crate::widget;
use super::{Id, Nil};
impl_control_builtin!{
Button <Release> {
ActivatePointer => widget::frame::activate_pointer,
ButtonPush => widget::button::push,
ButtonRelease => widget::button::release,
FieldBackspace => widget::field::backspace,
FormSubmitCallback => widget::form::submit_callback,
FrameClose => widget::frame::close,
FrameRefresh => widget::frame::refresh,
FrameToggleOrientation => widget::frame::toggle_orientation,
FrameFreeGrowWidth => widget::frame::free::grow_width,
FrameFreeGrowHeight => widget::frame::free::grow_height,
FrameFreeMoveDown => widget::frame::free::move_down,
FrameFreeMoveLeft => widget::frame::free::move_left,
FrameFreeMoveRight => widget::frame::free::move_right,
FrameFreeMoveUp => widget::frame::free::move_up,
FrameFreeShrinkHeight => widget::frame::free::shrink_height,
FrameFreeShrinkWidth => widget::frame::free::shrink_width,
FrameTiledDecreaseSize => widget::frame::tiled::decrease_size,
FrameTiledIncreaseSize => widget::frame::tiled::increase_size,
MenuNextItem => widget::menu::next_item,
MenuPreviousItem => widget::menu::previous_item,
MenuFirstItem => widget::menu::first_item,
MenuLastItem => widget::menu::last_item,
NumboxDecrease => widget::numbox::decrease,
NumboxIncrease => widget::numbox::increase,
NumboxDecrease10x => widget::numbox::decrease_10x,
NumboxIncrease10x => widget::numbox::increase_10x,
PlaybackLoop => widget::playback::loop_,
PlaybackPlay => widget::playback::play,
PlaybackReady => widget::playback::ready,
TextboxScrollRight => widget::textbox::scroll_right,
TextboxScrollLeft => widget::textbox::scroll_left,
TextboxScrollUp => widget::textbox::scroll_up,
TextboxScrollDown => widget::textbox::scroll_down,
TextboxPageRight => widget::textbox::page_right,
TextboxPageLeft => widget::textbox::page_left,
TextboxPageUp => widget::textbox::page_up,
TextboxPageDown => widget::textbox::page_down
}
}
impl_control_serdes!{ Button }
pub type Release = Option <RefCell <SmallVec <[(Button, NodeId); 1]>>>;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Binding <E : Id <Button> = Nil>
(pub Control <E>, pub input::Button, pub std::marker::PhantomData <E>);
impl <E : Id <Button>> Binding <E> {
pub fn new (control : Control <E>, button : input::Button) -> Self {
Binding (control, button, Default::default())
}
}
impl <E : Id <Button>> From <input::button::Binding <E>> for Binding <E> {
fn from (input::button::Binding (button, control, _) : input::button::Binding <E>)
-> Self
{
Binding::new (control, button)
}
}
impl <E : Id <Button>> From <Binding <E>> for (Control <E>, input::Button) {
fn from (Binding (control, button, _) : Binding <E>) -> Self {
(control, button)
}
}
impl <E : Id <Button>> From <(Control <E>, input::Button)> for Binding <E> {
fn from ((control, button) : (Control <E>,input::Button)) -> Self {
Binding::new (control, button)
}
}
struct BindingVisitor <E : Id <Button> = Nil> (std::marker::PhantomData <E>);
impl <E : Id <Button>> serde::Serialize for Binding <E> {
fn serialize <S : serde::Serializer> (&self, serializer : S)
-> Result <S::Ok, S::Error>
{
let control = serde_plain::to_string (&self.0).unwrap();
let input = serde_plain::to_string (&self.1).unwrap();
serializer.serialize_str (&format!("{control}: {input}"))
}
}
impl <E : Id <Button>> serde::de::Visitor <'_> for BindingVisitor <E> {
type Value = Binding <E>;
fn expecting (&self, formatter : &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str ("A control: button pair")
}
fn visit_str <ERR : serde::de::Error> (self, v : &str) -> Result <Self::Value, ERR> {
let control = {
let s = v.split (':').next().unwrap();
serde_plain::from_str::<Control <E>> (s).unwrap()
};
let button = {
let s = v.split (' ').nth (1).unwrap();
serde_plain::from_str::<input::Button> (s).unwrap()
};
Ok (Binding::new (control, button))
}
}
impl <'de, E : Id <Button>> serde::Deserialize <'de> for Binding <E> {
fn deserialize <D : serde::Deserializer <'de>> (deserializer : D)
-> Result <Self, D::Error>
{
deserializer.deserialize_str (BindingVisitor (Default::default()))
}
}