Skip to main content

gooey/interface/controller/controls/
button.rs

1use std::cell::RefCell;
2use serde_plain;
3use smallvec::SmallVec;
4use crate::interface::view::input;
5use crate::tree::NodeId;
6use crate::widget;
7
8use super::{Id, Nil};
9
10impl_control_builtin!{
11  Button <Release> {
12    ActivatePointer          => widget::frame::activate_pointer,
13    ButtonPush               => widget::button::push,
14    ButtonRelease            => widget::button::release,
15    FieldBackspace           => widget::field::backspace,
16    FormSubmitCallback       => widget::form::submit_callback,
17    FrameClose               => widget::frame::close,
18    FrameRefresh             => widget::frame::refresh,
19    FrameToggleOrientation   => widget::frame::toggle_orientation,
20    FrameFreeGrowWidth       => widget::frame::free::grow_width,
21    FrameFreeGrowHeight      => widget::frame::free::grow_height,
22    FrameFreeMoveDown        => widget::frame::free::move_down,
23    FrameFreeMoveLeft        => widget::frame::free::move_left,
24    FrameFreeMoveRight       => widget::frame::free::move_right,
25    FrameFreeMoveUp          => widget::frame::free::move_up,
26    FrameFreeShrinkHeight    => widget::frame::free::shrink_height,
27    FrameFreeShrinkWidth     => widget::frame::free::shrink_width,
28    FrameTiledDecreaseSize   => widget::frame::tiled::decrease_size,
29    FrameTiledIncreaseSize   => widget::frame::tiled::increase_size,
30    MenuNextItem             => widget::menu::next_item,
31    MenuPreviousItem         => widget::menu::previous_item,
32    MenuFirstItem            => widget::menu::first_item,
33    MenuLastItem             => widget::menu::last_item,
34    NumboxDecrease           => widget::numbox::decrease,
35    NumboxIncrease           => widget::numbox::increase,
36    NumboxDecrease10x        => widget::numbox::decrease_10x,
37    NumboxIncrease10x        => widget::numbox::increase_10x,
38    PlaybackLoop             => widget::playback::loop_,
39    PlaybackPlay             => widget::playback::play,
40    PlaybackReady            => widget::playback::ready,
41    TextboxScrollRight       => widget::textbox::scroll_right,
42    TextboxScrollLeft        => widget::textbox::scroll_left,
43    TextboxScrollUp          => widget::textbox::scroll_up,
44    TextboxScrollDown        => widget::textbox::scroll_down,
45    TextboxPageRight         => widget::textbox::page_right,
46    TextboxPageLeft          => widget::textbox::page_left,
47    TextboxPageUp            => widget::textbox::page_up,
48    TextboxPageDown          => widget::textbox::page_down
49  }
50}
51
52impl_control_serdes!{ Button }
53
54/// Argument type for button callbacks
55pub type Release = Option <RefCell <SmallVec <[(Button, NodeId); 1]>>>;
56
57/// Binds a button control to an input button and implements custom serialization format
58#[derive(Clone, Debug, Eq, PartialEq)]
59pub struct Binding <E : Id <Button> = Nil>
60  (pub Control <E>, pub input::Button, pub std::marker::PhantomData <E>);
61
62impl <E : Id <Button>> Binding <E> {
63  pub fn new (control : Control <E>, button : input::Button) -> Self {
64    Binding (control, button, Default::default())
65  }
66}
67impl <E : Id <Button>> From <input::button::Binding <E>> for Binding <E> {
68  fn from (input::button::Binding (button, control, _) : input::button::Binding <E>)
69    -> Self
70  {
71    Binding::new (control, button)
72  }
73}
74impl <E : Id <Button>> From <Binding <E>> for (Control <E>, input::Button) {
75  fn from (Binding (control, button, _) : Binding <E>) -> Self {
76    (control, button)
77  }
78}
79impl <E : Id <Button>> From <(Control <E>, input::Button)> for Binding <E> {
80  fn from ((control, button) : (Control <E>,input::Button)) -> Self {
81    Binding::new (control, button)
82  }
83}
84
85//
86// private
87//
88
89struct BindingVisitor <E : Id <Button> = Nil> (std::marker::PhantomData <E>);
90
91impl <E : Id <Button>> serde::Serialize for Binding <E> {
92  fn serialize <S : serde::Serializer> (&self, serializer : S)
93    -> Result <S::Ok, S::Error>
94  {
95    let control = serde_plain::to_string (&self.0).unwrap();
96    let input   = serde_plain::to_string (&self.1).unwrap();
97    serializer.serialize_str (&format!("{control}: {input}"))
98  }
99}
100
101impl <E : Id <Button>> serde::de::Visitor <'_> for BindingVisitor <E> {
102  type Value = Binding <E>;
103  fn expecting (&self, formatter : &mut std::fmt::Formatter) -> std::fmt::Result {
104    formatter.write_str ("A control: button pair")
105  }
106  fn visit_str <ERR : serde::de::Error> (self, v : &str) -> Result <Self::Value, ERR> {
107    let control = {
108      let s = v.split (':').next().unwrap();
109      serde_plain::from_str::<Control <E>> (s).unwrap()
110    };
111    let button = {
112      let s = v.split (' ').nth (1).unwrap();
113      serde_plain::from_str::<input::Button> (s).unwrap()
114    };
115    Ok (Binding::new (control, button))
116  }
117}
118
119impl <'de, E : Id <Button>> serde::Deserialize <'de> for Binding <E> {
120  fn deserialize <D : serde::Deserializer <'de>> (deserializer : D)
121    -> Result <Self, D::Error>
122  {
123    deserializer.deserialize_str (BindingVisitor (Default::default()))
124  }
125}