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 {
109 ($interface:expr, $builder:expr) => {
110 build_and_return_node_id!($interface, $builder, 0)
111 },
112 ($interface:expr, $builder:expr, $nth:expr) => {{
113 let actions = $builder.build_actions();
114 let mut events = $interface.actions (actions);
115 let mut count = 0;
116 loop {
117 match events.next().unwrap() {
118 (_, $crate::interface::model::Event::Create (_, new_id, _)) =>
119 if count == $nth {
120 break new_id
121 } else {
122 count += 1;
123 }
124 _ => {}
125 }
126 }
127 }}
128}
129
130pub macro build_and_get_node_ids {
132 ($interface:expr, $builder:expr, $names:expr) => {{
133 let actions = $builder.build_actions();
134 let events = $interface.actions (actions).collect::<Vec <_>>();
135 let mut names = $names.map (|name| Some (name));
136 let mut ids = $names.map (|_| None);
137 for event in events {
138 match event {
139 (_, $crate::interface::model::Event::Create (_, new_id, _)) => {
140 let name = $interface.get_element (&new_id).name.as_str();
141 if let Some (i) = names.iter().position (|n| n == &Some (name)) {
142 names[i] = None;
143 ids[i] = Some (new_id);
144 }
145 }
146 _ => {}
147 }
148 }
149 ids.map (Option::unwrap)
150 }}
151}