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, PartialEq)]
61pub struct Widget <'element, C, M, V> (
62 pub &'element C,
63 pub &'element M,
64 pub &'element V
65) where
66 C : controller::component::Kind,
67 M : model::component::Kind,
68 V : view::component::Kind;
69
70impl <'element, C, M, V> TryFrom <&'element Element>
71 for Widget <'element, C, M, V>
72where
73 C : controller::component::Kind,
74 M : model::component::Kind,
75 V : view::component::Kind
76{
77 type Error = &'element Element;
78 fn try_from (element : &'element Element) -> Result <Self, Self::Error> {
79 let controller = C::try_ref (&element.controller.component).ok_or (element)?;
80 let model = M::try_ref (&element.model.component).ok_or (element)?;
81 let view = V::try_ref (&element.view.component).ok_or (element)?;
82 Ok (Widget::<'element, C, M, V> (controller, model, view))
83 }
84}
85
86impl <'element, C, M, V> Widget <'element, C, M, V> where
87 C : controller::component::Kind,
88 M : model::component::Kind,
89 V : view::component::Kind
90{
91 pub fn try_get (elements: &'element Tree <Element>, node_id : &NodeId)
93 -> Result <Self, &'element Element>
94 {
95 let element = elements.get_element (node_id);
96 Self::try_from (element)
97 }
98}
99
100pub trait BuildElement {
102 fn build_element (self) -> Element;
103}
104
105pub trait BuildActions {
107 fn build_actions (self) -> Vec <(NodeId, Action)>;
108}
109
110pub macro build_and_return_node_id {
113 ($interface:expr, $builder:expr) => {
114 build_and_return_node_id!($interface, $builder, 0)
115 },
116 ($interface:expr, $builder:expr, $nth:expr) => {{
117 let actions = $builder.build_actions();
118 let mut events = $interface.actions (actions);
119 let mut count = 0;
120 loop {
121 match events.next().unwrap() {
122 (_, $crate::interface::model::Event::Create (_, new_id, _)) =>
123 if count == $nth {
124 break new_id
125 } else {
126 count += 1;
127 }
128 _ => {}
129 }
130 }
131 }}
132}
133
134pub macro build_and_get_node_ids {
137 ($interface:expr, $builder:expr, $names:expr) => {{
138 let actions = $builder.build_actions();
139 let events = $interface.actions (actions).collect::<Vec <_>>();
140 let mut names = $names.map (|name| Some (name));
141 let mut ids = $names.map (|_| None);
142 for event in events {
143 match event {
144 (_, $crate::interface::model::Event::Create (_, new_id, _)) => {
145 let name = $interface.get_element (&new_id).name.as_str();
146 if let Some (i) = names.iter().position (|n| n == &Some (name)) {
147 names[i] = None;
148 ids[i] = Some (new_id);
149 }
150 }
151 _ => {}
152 }
153 }
154 ids.map (Option::unwrap)
155 }}
156}