use std::convert::TryFrom;
use crate::{Tree, TreeHelper};
use crate::interface::{controller, model, view, Action, Element};
use crate::tree::NodeId;
pub mod button;
pub mod field;
pub mod form;
pub mod frame;
pub mod menu;
pub mod numbox;
pub mod picture;
pub mod playback;
pub mod textbox;
pub use self::button::Button;
pub use self::field::Field;
pub use self::form::Form;
pub use self::frame::Frame;
pub use self::menu::Menu;
pub use self::numbox::Numbox;
pub use self::picture::Picture;
pub use self::playback::Playback;
pub use self::textbox::Textbox;
pub mod composite;
pub (crate) macro set_option ($builder:ident, $setter:ident, $option:expr) {
if let Some (inner) = $option {
$builder = $builder.$setter (inner);
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Widget <'element, C, M, V> (
pub &'element C,
pub &'element M,
pub &'element V
) where
C : controller::component::Kind,
M : model::component::Kind,
V : view::component::Kind;
impl <'element, C, M, V> TryFrom <&'element Element> for Widget <'element, C, M, V> where
C : controller::component::Kind,
M : model::component::Kind,
V : view::component::Kind
{
type Error = &'element Element;
fn try_from (element : &'element Element) -> Result <Self, Self::Error> {
let controller = C::try_ref (&element.controller.component).ok_or (element)?;
let model = M::try_ref (&element.model.component).ok_or (element)?;
let view = V::try_ref (&element.view.component).ok_or (element)?;
Ok (Widget::<'element, C, M, V> (controller, model, view))
}
}
impl <'element, C, M, V> Widget <'element, C, M, V> where
C : controller::component::Kind,
M : model::component::Kind,
V : view::component::Kind
{
pub fn try_get (elements: &'element Tree <Element>, node_id : &NodeId)
-> Result <Self, &'element Element>
{
let element = elements.get_element (node_id);
Self::try_from (element)
}
}
pub trait BuildElement {
fn build_element (self) -> Element;
}
pub trait BuildActions {
fn build_actions (self) -> Vec <(NodeId, Action)>;
}
pub macro build_and_return_node_id {
($interface:expr, $builder:expr) => {
build_and_return_node_id!($interface, $builder, 0)
},
($interface:expr, $builder:expr, $nth:expr) => {{
let actions = $builder.build_actions();
let mut events = $interface.actions (actions);
let mut count = 0;
loop {
match events.next().unwrap() {
(_, $crate::interface::model::Event::Create (_, new_id, _)) =>
if count == $nth {
break new_id
} else {
count += 1;
}
_ => {}
}
}
}}
}
pub macro build_and_get_node_ids {
($interface:expr, $builder:expr, $names:expr) => {{
let actions = $builder.build_actions();
let events = $interface.actions (actions).collect::<Vec <_>>();
let mut names = $names.map (|name| Some (name));
let mut ids = $names.map (|_| None);
for event in events {
match event {
(_, $crate::interface::model::Event::Create (_, new_id, _)) => {
let name = $interface.get_element (&new_id).name.as_str();
if let Some (i) = names.iter().position (|n| n == &Some (name)) {
names[i] = None;
ids[i] = Some (new_id);
}
}
_ => {}
}
}
ids.map (Option::unwrap)
}}
}