1use std::convert::TryFrom;
14use crate::{Tree, TreeHelper};
15use crate::interface::{controller, model, view, Action, Element};
16use crate::tree::NodeId;
17
18pub mod button;
19pub mod field;
20pub mod form;
21pub mod frame;
22pub mod menu;
23pub mod numbox;
24pub mod picture;
25pub mod playback;
26pub mod textbox;
27pub use self::button::Button;
28pub use self::field::Field;
29pub use self::form::Form;
30pub use self::frame::Frame;
31pub use self::menu::Menu;
32pub use self::numbox::Numbox;
33pub use self::picture::Picture;
34pub use self::playback::Playback;
35pub use self::textbox::Textbox;
36
37pub mod composite;
38
39pub (crate) macro set_option ($builder:ident, $setter:ident, $option:expr) {
50 if let Some (inner) = $option {
51 $builder = $builder.$setter (inner);
52 }
53}
54
55#[derive(Clone, Debug, Eq, PartialEq)]
60pub struct Widget <'element, C, M, V> (
61 pub &'element C,
62 pub &'element M,
63 pub &'element V
64) where
65 C : controller::component::Kind,
66 M : model::component::Kind,
67 V : view::component::Kind;
68
69impl <'element, C, M, V> TryFrom <&'element Element> for Widget <'element, C, M, V> where
70 C : controller::component::Kind,
71 M : model::component::Kind,
72 V : view::component::Kind
73{
74 type Error = &'element Element;
75 fn try_from (element : &'element Element) -> Result <Self, Self::Error> {
76 let controller = C::try_ref (&element.controller.component).ok_or (element)?;
77 let model = M::try_ref (&element.model.component).ok_or (element)?;
78 let view = V::try_ref (&element.view.component).ok_or (element)?;
79 Ok (Widget::<'element, C, M, V> (controller, model, view))
80 }
81}
82
83impl <'element, C, M, V> Widget <'element, C, M, V> where
84 C : controller::component::Kind,
85 M : model::component::Kind,
86 V : view::component::Kind
87{
88 pub fn try_get (elements: &'element Tree <Element>, node_id : &NodeId)
90 -> Result <Self, &'element Element>
91 {
92 let element = elements.get_element (node_id);
93 Self::try_from (element)
94 }
95}
96
97pub trait BuildElement {
99 fn build_element (self) -> Element;
100}
101
102pub trait BuildActions {
104 fn build_actions (self) -> Vec <(NodeId, Action)>;
105}
106
107pub macro build_and_return_node_id {
110 ($interface:expr, $builder:expr) => {
111 build_and_return_node_id!($interface, $builder, 0)
112 },
113 ($interface:expr, $builder:expr, $nth:expr) => {{
114 let actions = $builder.build_actions();
115 let mut events = $interface.actions (actions);
116 let mut count = 0;
117 loop {
118 match events.next().unwrap() {
119 (_, $crate::interface::model::Event::Create (_, new_id, _)) =>
120 if count == $nth {
121 break new_id
122 } else {
123 count += 1;
124 }
125 _ => {}
126 }
127 }
128 }}
129}
130
131pub macro build_and_get_node_ids {
134 ($interface:expr, $builder:expr, $names:expr) => {{
135 let actions = $builder.build_actions();
136 let events = $interface.actions (actions).collect::<Vec <_>>();
137 let mut names = $names.map (|name| Some (name));
138 let mut ids = $names.map (|_| None);
139 for event in events {
140 match event {
141 (_, $crate::interface::model::Event::Create (_, new_id, _)) => {
142 let name = $interface.get_element (&new_id).name.as_str();
143 if let Some (i) = names.iter().position (|n| n == &Some (name)) {
144 names[i] = None;
145 ids[i] = Some (new_id);
146 }
147 }
148 _ => {}
149 }
150 }
151 ids.map (Option::unwrap)
152 }}
153}