1use std::convert::TryFrom;
20use std::sync::{Arc, LazyLock, RwLock};
21use log;
22use derive_more::{From, TryInto};
23
24use crate::prelude::*;
25
26pub mod controller;
27pub mod model;
28pub mod view;
29pub use self::controller::Controller;
30pub use self::model::Model;
31pub use self::view::View;
32
33pub static POINTER : LazyLock <Arc <RwLock <input::Pointer>>> = LazyLock::new (||
35 Arc::new (RwLock::new (input::Pointer::default())));
36
37#[derive(Debug)]
39pub struct Interface <A=application::Default, P=presentation::Headless> where
40 A : Application,
41 P : Presentation
42{
43 pub presentation : P,
44 elements : Tree <Element>,
45 focused_id : NodeId,
46 input_buffer : Option <Vec <Input>>,
47 action_buffer : Option <Vec <(NodeId, Action)>>,
48 display_buffer : Vec <(NodeId, Display)>,
49 event_buffer : Vec <(NodeId, Event)>,
50 _phantom : std::marker::PhantomData <A>
51}
52
53#[derive(Clone, Debug)]
59pub struct Element {
60 pub name : String,
61 pub controller : Controller,
62 pub model : Model,
63 pub view : View
64}
65
66#[derive(From, TryInto)]
68pub enum Action {
69 Create (Tree <Element>, CreateOrder),
70 ModifyController (Box <dyn FnOnce (&mut Controller)>),
71 ModifyModel (Box <dyn FnOnce (&mut Model)>),
72 ModifyView (Box <dyn FnOnce (&mut View)>),
73 SubmitCallback (application::CallbackId),
79 Focus,
85 Enable,
88 Disable,
91 Destroy,
97 ReleaseButtons
103}
104
105#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
107pub enum CreateOrder {
108 #[default]
109 Append,
110 Prepend,
111 NthSibling (u32)
112}
113
114impl <A, P> Interface <A, P> where
115 A : Application,
116 P : Presentation
117{
118 pub fn with_root (mut root : Element) -> Self {
119 log::trace!("with_root...");
120 root.focus();
121 let elements = TreeBuilder::new().with_root (Node::new (root.clone()))
122 .build();
123 let focused_id = elements.root_node_id().unwrap().clone();
124 let presentation = P::with_root (root.view, focused_id.clone());
125 let input_buffer = Some (vec![]);
126 let action_buffer = Some (vec![]);
127 let display_buffer = vec![];
128 let event_buffer = vec![];
129 log::trace!("...with_root");
130 Interface {
131 elements, focused_id, presentation,
132 input_buffer, display_buffer, action_buffer, event_buffer,
133 _phantom: std::marker::PhantomData
134 }
135 }
136
137 #[inline]
141 #[must_use]
142 #[expect(mismatched_lifetime_syntaxes)]
143 pub fn action (&mut self, node_id : &NodeId, action : Action)
144 -> std::vec::Drain <(NodeId, Event)>
145 {
146 self.handle_action (action, node_id);
147 self.event_buffer.drain(..)
148 }
149
150 #[inline]
154 #[must_use]
155 #[expect(mismatched_lifetime_syntaxes)]
156 pub fn actions (&mut self, actions : Vec <(NodeId, Action)>)
157 -> std::vec::Drain <(NodeId, Event)>
158 {
159 for (node_id, action) in actions.into_iter() {
160 self.handle_action (action, &node_id);
161 }
162 self.event_buffer.drain(..)
163 }
164
165 #[must_use]
167 #[expect(mismatched_lifetime_syntaxes)]
168 pub fn update (&mut self) -> std::vec::Drain <(NodeId, Event)> {
169 log::trace!("update...");
170 let mut action_buffer = self.action_buffer.take().unwrap();
172 let mut input_buffer = self.input_buffer.take().unwrap();
173 debug_assert!(action_buffer.is_empty());
174 debug_assert!(input_buffer.is_empty());
175 self.presentation.get_input (&mut input_buffer);
176 #[expect(clippy::iter_with_drain)]
177 for input in input_buffer.drain(..) {
178 log::trace!("input: {input:?}");
179 if let Input::Pointer (pointer) = &input {
181 *POINTER.write().unwrap() = pointer.clone()
182 }
183 let focused_id = self.focused_element_id().clone();
184 let focused = self.focused_element();
185 let button_release = match focused.controller.handle_input::<A> (
187 input, &self.elements, &focused_id, &mut action_buffer
188 ) {
189 Ok (result) => result,
190 Err (mut input) => {
191 debug_assert!(action_buffer.is_empty());
193 let mut button_release = None;
194 let input_mask = (&input).into();
195 if !focused.controller.bubble_trap.intersects (input_mask) {
196 for ancestor_id in self.elements.ancestor_ids (&focused_id).unwrap() {
197 let ancestor = self.get_element (ancestor_id);
198 input = match ancestor.controller.handle_input::<A> (
199 input, &self.elements, ancestor_id, &mut action_buffer
200 ) {
201 Err (input) =>
202 if ancestor.controller.bubble_trap.intersects (input_mask) {
203 break
204 } else {
205 input
206 }
207 Ok (result) => {
208 button_release = result;
209 break
210 }
211 };
212 }
213 }
214 button_release
215 }
216 };
217 for (node_id, action) in action_buffer.drain(..) {
219 self.handle_action (action, &node_id);
220 }
221 if let Some (button_release) = button_release {
226 match button_release {
227 ButtonRelease::Insert (input, controls) =>
228 for (control, node_id) in controls {
229 let element = self.get_element_mut (&node_id);
230 element.controller.release_button_insert (input, control);
231 }
232 ButtonRelease::Remove (input, node_id) => {
233 let element = self.get_element_mut (&node_id);
234 element.controller.release_button_remove (input);
235 }
236 }
237 }
238 }
239 debug_assert!(action_buffer.is_empty());
240 debug_assert!(input_buffer.is_empty());
241 self.action_buffer = Some (action_buffer);
242 self.input_buffer = Some (input_buffer);
243
244 log::trace!("...update");
245 self.event_buffer.drain(..)
247 }
248
249 #[inline]
251 pub fn display (&mut self) {
252 log::trace!("display...");
253 self.presentation
254 .display_view (&self.elements, self.display_buffer.drain(..));
255 log::trace!("...display");
256 }
257
258 #[inline]
259 pub const fn elements (&self) -> &Tree <Element> {
260 &self.elements
261 }
262
263 #[inline]
264 pub fn root (&self) -> &Element {
265 self.root_node().data()
266 }
267
268 pub fn root_node (&self) -> &Node <Element> {
269 self.elements.get (self.root_id()).unwrap()
270 }
271
272 #[inline]
273 pub fn root_id (&self) -> &NodeId {
274 self.elements.root_node_id().unwrap()
275 }
276
277 #[inline]
278 pub fn get_element (&self, node_id : &NodeId) -> &Element {
279 self.elements.get_element (node_id)
280 }
281
282 #[inline]
283 pub fn get_element_mut (&mut self, node_id : &NodeId) -> &mut Element {
284 self.elements.get_element_mut (node_id)
285 }
286
287 #[inline]
288 pub const fn focused_element_id (&self) -> &NodeId {
289 &self.focused_id
290 }
291
292 #[inline]
293 pub fn focused_element (&self) -> &Element {
294 self.get_element (&self.focused_id)
295 }
296
297 #[inline]
298 pub fn focused_element_mut (&mut self) -> &mut Element {
299 let focused_id = self.focused_id.clone();
300 self.get_element_mut (&focused_id)
301 }
302
303 #[inline]
304 pub fn print_elements_tree (&self) {
305 let mut s = String::new();
306 self.elements.write_formatted (&mut s).unwrap();
307 println!("elements:\n{s}");
308 }
309
310 #[inline]
311 pub fn log_elements_tree (&self) {
312 let mut s = String::new();
313 self.elements.write_formatted (&mut s).unwrap();
314 log::info!("elements:\n{s}");
315 }
316
317 #[inline]
318 pub fn print_elements_tree_names (&self) {
319 let mut s = String::new();
320 self.elements.write_formatted_names (&mut s).unwrap();
321 println!("elements:\n{s}");
322 }
323
324 #[inline]
325 pub fn log_elements_tree_names (&self) {
326 let mut s = String::new();
327 self.elements.write_formatted_names (&mut s).unwrap();
328 log::info!("elements:\n{s}");
329 }
330
331 pub fn create_singleton (&mut self,
333 parent_id : &NodeId,
334 element : Element,
335 order : CreateOrder
336 ) -> NodeId {
337 match self.action (parent_id, Action::create_singleton (element, order))
338 .next().unwrap()
339 {
340 (_, Event::Create (_, new_id, _)) => new_id,
341 _ => unreachable!()
342 }
343 }
344
345 fn handle_action (&mut self, action : Action, node_id : &NodeId) {
346 use controller::component::{Kind, Selection};
347 log::trace!("handle_action...");
348 log::trace!("action: {action:?}");
349 match action {
350 Action::Create (elements, order) => {
351 #[cfg(debug_assertions)]
352 for element in
353 elements.traverse_level_order (elements.root_node_id().unwrap())
354 .unwrap()
355 {
356 debug_assert_eq!(&element.data().view.appearance,
358 element.data().controller.get_appearance());
359 }
360 self.splice_subtree (
361 &elements, elements.root_node_id().unwrap(), node_id, order);
362 }
363 Action::ModifyController (f) => {
364 let controller = &mut self.get_element_mut (node_id).controller;
365 f (controller);
366 }
367 Action::ModifyModel (f) => {
368 let model = {
369 let model = &mut self.get_element_mut (node_id).model;
370 f (model);
371 model.clone()
372 };
373 self.event_buffer.push ((node_id.clone(), Event::Update (model)));
374 }
375 Action::ModifyView (f) => {
376 let view = {
377 let view = &mut self.get_element_mut (node_id).view;
378 f (view);
379 view.clone()
381 };
382 self.display_buffer.push (
383 (node_id.clone(), Display::Update (view.into())));
384 }
385 Action::SubmitCallback (callback_id) => {
386 let callback_id = Some (callback_id);
387 let model = Model {
388 callback_id, .. self.get_element (node_id).model.clone()
389 };
390 self.event_buffer.push ((node_id.clone(), Event::Submit (model)));
391 }
392 Action::Focus => {
393 let mut focus_id = Some (node_id.clone());
394 while let Some (id) = focus_id {
395 focus_id = self.change_focus (&id);
396 if self.get_element (&id).controller.focus_top {
398 self.elements.make_last_sibling (&id).unwrap();
399 self.display_buffer.push (
400 (id.clone(), Display::Update (Update::FocusTop)));
401 }
402 let ancestor_ids = self.elements.ancestor_ids (&id).unwrap().cloned()
403 .collect::<Vec <_>>();
404 for ancestor_id in ancestor_ids {
405 if self.get_element (&ancestor_id).controller.focus_top {
406 self.elements.make_last_sibling (&ancestor_id).unwrap();
407 self.display_buffer.push (
408 ( ancestor_id.clone(),
409 Display::Update (Update::FocusTop)
410 )
411 );
412 }
413 }
414 }
415 }
416 Action::Enable => {
417 let view = {
418 let element = self.get_element_mut (node_id);
419 element.controller.state.enable();
420 element.view.appearance = element.controller.get_appearance().clone();
421 element.view.clone()
422 };
423 self.display_buffer.push (
424 (node_id.clone(), Display::Update (view.into())));
425 }
426 Action::Disable => {
427 let view = {
428 let element = self.get_element_mut (node_id);
429 element.controller.state.disable();
430 element.view.appearance = element.controller.get_appearance().clone();
431 element.view.clone()
432 };
433 self.display_buffer.push (
434 (node_id.clone(), Display::Update (view.into())));
435 }
436 Action::Destroy => {
437 let parent_id = self.elements.get_parent_id (node_id).clone();
438 let focused = self.elements.get_element (node_id).controller.state ==
439 State::Focused;
440 { let mut children_ids = self.elements.children_ids (&parent_id).unwrap();
442 let first_sibling_id = children_ids.next().unwrap().clone();
445 let first_sibling = self.elements.get_element (&first_sibling_id);
446 if let Ok (Widget (selection, _, _)) = Menu::try_from (first_sibling)
447 && selection.current.as_ref() == Some (node_id)
448 {
449 let mut select = None;
450 for sibling_id in children_ids {
451 if sibling_id == node_id {
452 continue
453 }
454 let sibling = self.elements.get_element (sibling_id);
455 if sibling.controller.state == State::Enabled
456 && Frame::try_from (sibling).is_ok()
457 {
458 select = Some (sibling_id.clone());
459 break
460 }
461 }
462 let deselect = Box::new (move |controller : &mut Controller|{
463 let selection = Selection::try_ref_mut (&mut controller.component)
464 .unwrap();
465 selection.current = select;
466 });
467 self.handle_action (Action::ModifyController (deselect), &first_sibling_id);
468 }
469 }
470 if focused {
471 let mut focus_id = Some (parent_id);
472 while let Some (id) = focus_id {
473 focus_id = self.change_focus (&id);
474 }
475 }
476 for node_id in self.elements.traverse_post_order_ids (node_id).unwrap() {
477 self.event_buffer.push ((node_id.clone(), Event::Destroy));
478 self.display_buffer.push ((node_id, Display::Destroy));
479 }
480 let _ = self.elements
481 .remove_node (node_id.clone(), tree::RemoveBehavior::DropChildren).unwrap();
482 }
483 Action::ReleaseButtons => {
484 use controller::controls::Control;
485 let release_buttons =
486 self.elements.get_element_mut (node_id).controller.release_buttons();
487 for control in release_buttons {
488 control.fun::<A::ButtonControls>().0 (
489 &None, &self.elements, node_id, self.action_buffer.as_mut().unwrap());
490 }
491 let mut action_buffer = self.action_buffer.take().unwrap();
492 #[expect(clippy::iter_with_drain)]
493 for (node_id, action) in action_buffer.drain(..) {
494 self.handle_action (action, &node_id);
495 }
496 self.action_buffer = Some (action_buffer);
497 }
498 }
499 log::trace!("...handle_action");
500 }
501
502 fn insert_child (&mut self,
504 parent_id : &NodeId,
505 child : Node <Element>,
506 order : CreateOrder
507 ) -> NodeId {
508 let child_model = child.data().model.clone();
509 let child_view = child.data().view.clone();
510 let child_id = self.elements.insert (
511 child, tree::InsertBehavior::UnderNode (parent_id)).unwrap();
512 match order {
513 CreateOrder::Append => {}
514 CreateOrder::Prepend => {
515 let _ = self.elements.make_first_sibling (&child_id).unwrap();
516 }
517 CreateOrder::NthSibling (n) =>
518 self.elements.make_nth_sibling (&child_id, n as usize).unwrap()
519 }
520 self.event_buffer.push ((parent_id.clone(),
521 Event::Create (child_model, child_id.clone(), order)));
522 self.display_buffer.push ((parent_id.clone(),
523 Display::Create (child_view, child_id.clone(), order)));
524 child_id
525 }
526
527 fn change_focus (&mut self, target_id : &NodeId) -> Option <NodeId> {
531 use controller::component::{Kind, Selection};
532 log::trace!("change_focus...");
533 let focused_id = self.focused_element_id().clone();
534 let focused_ancestors = self.elements.ancestor_ids (&focused_id).unwrap()
535 .cloned().collect::<Vec <NodeId>>();
536 let target_ancestors = self.elements.ancestor_ids (target_id).unwrap()
537 .cloned().collect::<Vec <NodeId>>();
538 let maybe_common_ancestor_id = {
539 focused_ancestors.iter().rev().zip (target_ancestors.iter().rev())
540 .filter_map (|(a, b)|
541 if a == b {
542 Some (a)
543 } else {
544 None
545 })
546 .cloned().enumerate().last()
547 };
548 let focused_ancestor_of_target = target_ancestors.contains (&focused_id);
549 let target_ancestor_of_focused = focused_ancestors.contains (target_id);
550 { let mut defocus = |defocus_id| {
552 let view = {
553 let mut actions = vec![];
555 let focused_node = self.elements.get (&defocus_id).unwrap();
556 if let Some (sub_child_id) = focused_node.children().first() &&
559 let Ok (Widget (switch, _, _)) =
560 Button::try_get (&self.elements, sub_child_id)
561 && switch.state == switch::State::On && !switch.toggle
562 {
563 button::release (&None, &self.elements, &defocus_id, &mut actions);
564 }
565 for (node_id, action) in actions.into_iter() {
566 self.handle_action (action, &node_id);
567 }
568 let focused = self.elements.get_mut (&defocus_id).unwrap().data_mut();
569 focused.defocus();
570 let view = focused.view.clone();
571 focused.view.appearance.sound = None; view
573 };
574 self.display_buffer .push ((defocus_id, Display::Update (view.into())));
575 };
576 if !focused_ancestor_of_target {
578 defocus (focused_id);
579 }
580 if let Some ((_, common_ancestor_id)) = maybe_common_ancestor_id.as_ref() {
581 for ancestor_id in focused_ancestors.into_iter()
582 .take_while (|id| id != common_ancestor_id && id != target_id)
583 {
584 defocus (ancestor_id);
585 }
586 }
587 }
588 let refocus_id = {
589 let mut focus = |focus_id| {
591 if Frame::try_from (self.get_element (&focus_id)).is_ok() {
593 let parent_id = self.elements.get_parent_id (&focus_id);
595 let first_sibling_id =
596 self.elements.children_ids (parent_id).unwrap().next().unwrap().clone();
597 if first_sibling_id != focus_id {
598 let first_sibling = self.elements.get_element (&first_sibling_id);
599 if let Ok (Widget (selection, _, _)) = Menu::try_from (first_sibling)
600 && selection.current.as_ref() != Some (&focus_id)
601 {
602 let select_id = focus_id.clone();
603 let select = Box::new (move |controller : &mut Controller|{
604 let selection = Selection::try_ref_mut (&mut controller.component)
605 .unwrap();
606 selection.current = Some (select_id.clone());
607 });
608 self.handle_action (Action::ModifyController (select), &first_sibling_id);
609 }
610 }
611 }
612 let focus = self.get_element_mut (&focus_id);
613 focus.focus();
614 let view = focus.view.clone();
615 focus.view.appearance.sound = None; self.display_buffer
617 .push ((focus_id.clone(), Display::Update (view.into())));
618 };
619 let depth = if let Some ((depth, _)) = maybe_common_ancestor_id {
620 depth + 1 + usize::from (focused_ancestor_of_target)
621 } else {
622 1
623 };
624 for ancestor_id in target_ancestors.into_iter().rev().skip (depth) {
625 focus (ancestor_id);
626 }
627 if !target_ancestor_of_focused {
630 focus (target_id.clone());
631 }
632 refocus (target_id, self.elements())
635 };
636 self.focused_id = target_id.clone();
637 log::trace!("...change_focus");
638 refocus_id
639 }
640
641 fn splice_subtree (&mut self,
644 other : &Tree <Element>,
645 other_id : &NodeId,
646 parent_id : &NodeId,
647 order : CreateOrder
648 ) -> NodeId {
649 let subtree_root = Node::new (other.get (other_id).unwrap().data().clone());
651 let subtree_id = self.insert_child (parent_id, subtree_root, order);
652 for child_id in other.children_ids (other_id).unwrap() {
653 self.splice_subtree (other, child_id, &subtree_id, CreateOrder::Append);
654 }
655 subtree_id
656 }
657
658 pub (crate) fn swap_presentation <P2 : Presentation> (self, f : impl FnOnce (P) -> P2)
663 -> Interface <A, P2>
664 {
665 let Interface {
666 elements, focused_id, presentation, input_buffer, display_buffer, action_buffer,
667 event_buffer, _phantom
668 } = self;
669 #[expect(clippy::used_underscore_binding)]
670 Interface {
671 presentation: f (presentation),
672 elements, focused_id, input_buffer, display_buffer, action_buffer, event_buffer,
673 _phantom
674 }
675 }
676}
677
678impl Element {
679 pub fn new (
682 name : String, controller : Controller, model : Model, mut view : View
683 ) -> Self {
684 view.appearance = controller.get_appearance().clone();
685 Element { name, controller, view, model }
686 }
687 pub fn focus (&mut self) {
688 self.controller.state.focus();
689 self.controller.update_view_focus (&mut self.view);
690 }
691 pub fn defocus (&mut self) {
692 self.controller.state.defocus();
693 self.controller.update_view_focus (&mut self.view);
694 }
695 pub fn disable (&mut self) {
696 self.controller.state.disable();
697 self.controller.update_view_focus (&mut self.view);
698 }
699}
700
701impl Default for Element {
702 fn default() -> Self {
703 Element::new (
704 "".to_string(), Controller::default(), Model::default(), View::default())
705 }
706}
707
708impl AsRef <Controller> for Element {
709 fn as_ref (&self) -> &Controller {
710 &self.controller
711 }
712}
713
714impl AsRef <Model> for Element {
715 fn as_ref (&self) -> &Model {
716 &self.model
717 }
718}
719
720impl AsRef <View> for Element {
721 fn as_ref (&self) -> &View {
722 &self.view
723 }
724}
725
726impl Action {
727 #[inline]
730 pub fn create_singleton (element : Element, order : CreateOrder) -> Self {
731 let subtree = TreeBuilder::new().with_root (Node::new (element)).build();
732 Action::Create (subtree, order)
733 }
734
735 #[inline]
737 pub fn set_view (view : View) -> Self {
738 Action::ModifyView (Box::new (|v| *v = view))
739 }
740
741 #[inline]
743 pub fn set_controller (controller : Controller) -> Self {
744 Action::ModifyController (Box::new (|c| *c = controller))
745 }
746
747 #[inline]
749 pub fn set_model (model : Model) -> Self {
750 Action::ModifyModel (Box::new (|m| *m = model))
751 }
752
753 #[inline]
755 pub fn set_view_component <V> (component : V) -> Self where
756 V : view::component::Kind + 'static
757 {
758 Action::ModifyView (Box::new (|v| v.component = component.into()))
759 }
760
761 #[inline]
764 pub fn update_view_component <V> (component : V) -> Self where
765 V : view::component::Kind + 'static
766 {
767 Action::ModifyView (Box::new (|v| {
768 let v = V::try_ref_mut (&mut v.component).unwrap();
769 *v = component;
770 }))
771 }
772
773 #[inline]
775 pub fn set_controller_component <C> (component : C) -> Self where
776 C : ControllerKind + 'static
777 {
778 Action::ModifyController (Box::new (|c| c.component = component.into()))
779 }
780
781 #[inline]
784 pub fn update_controller_component <C> (component : C) -> Self where
785 C : ControllerKind + 'static
786 {
787 Action::ModifyController (Box::new (|c| {
788 let c = C::try_ref_mut (&mut c.component).unwrap();
789 *c = component;
790 }))
791 }
792
793 #[inline]
795 pub fn set_model_component <M> (component : M) -> Self where
796 M : model::component::Kind + 'static
797 {
798 Action::ModifyModel (Box::new (|m| m.component = component.into()))
799 }
800
801 #[inline]
804 pub fn update_model_component <M> (component : M) -> Self where
805 M : model::component::Kind + 'static
806 {
807 Action::ModifyModel (Box::new (|m| {
808 let m = M::try_ref_mut (&mut m.component).unwrap();
809 *m = component;
810 }))
811 }
812}
813
814impl std::fmt::Debug for Action {
815 fn fmt (&self, f : &mut std::fmt::Formatter) -> Result <(), std::fmt::Error> {
816 match self {
817 Action::Create (subtree, order) =>
818 write!(f, "Create({subtree:?}, {order:?})"),
819 Action::ModifyController (closure) =>
820 write!(f, "ModifyController({:p})", &closure),
821 Action::ModifyModel (closure) =>
822 write!(f, "ModifyModel({:p})", &closure),
823 Action::ModifyView (closure) =>
824 write!(f, "ModifyView({:p})", &closure),
825 Action::SubmitCallback (callback_id) =>
826 write!(f, "SubmitCallback({callback_id:?})"),
827 Action::Focus => write!(f, "Focus"),
828 Action::Enable => write!(f, "Enable"),
829 Action::Disable => write!(f, "Disable"),
830 Action::Destroy => write!(f, "Destroy"),
831 Action::ReleaseButtons => write!(f, "ReleaseButtons")
832 }
833 }
834}
835