gooey/interface/
mod.rs

1//! Interface layer.
2//!
3//! The `Interface` is the primary structure representing the user interface and
4//! contains all the data for the interface including the `Presentation`
5//! instance.
6//!
7//! The internal representation of the interface is a `Tree` of `Element` nodes.
8//! An `Element` is a combination of a `Model` component, a `View` component,
9//! and a `Controller` component. The kinds of components in `Elements` and
10//! their relations with parent/child nodes are contextualized in various
11//! `Widget` definitions.
12//!
13//! `Action` events define the internal language of the `Interface` layer and
14//! result from user `Input` events, or directly submitted from application
15//! code. Each `Action` is directed at a target `Element` node. `Action` events
16//! include creating/destroying/modifying `Element` nodes and their components,
17//! changing focus, or submitting callbacks.
18
19use std::convert::TryFrom;
20use std::sync::{Arc, RwLock};
21use lazy_static::lazy_static;
22use log;
23use derive_more::{From, TryInto};
24
25use crate::prelude::*;
26
27pub mod controller;
28pub mod model;
29pub mod view;
30pub use self::controller::Controller;
31pub use self::model::Model;
32pub use self::view::View;
33
34lazy_static!{
35  /// Pointer position
36  pub static ref POINTER : Arc <RwLock <view::input::Pointer>> =
37    Arc::new (RwLock::new (view::input::Pointer::default()));
38}
39
40/// Parameterized interface represented by a tree of `Element`s
41#[derive(Debug)]
42pub struct Interface <A=application::Default, P=presentation::Headless> where
43  A : Application,
44  P : Presentation
45{
46  pub presentation : P,
47  elements         : Tree <Element>,
48  focused_id       : NodeId,
49  input_buffer     : Option <Vec <view::Input>>,
50  action_buffer    : Option <Vec <(NodeId, Action)>>,
51  display_buffer   : Vec <(NodeId, view::Display)>,
52  event_buffer     : Vec <(NodeId, model::Event)>,
53  _phantom         : std::marker::PhantomData <A>
54}
55
56/// An interface node consisting of one each of `Model`, `View`, and
57/// `Controller` components.
58///
59/// See `Widget`s for construction of contextualzed combinations of different
60/// components.
61#[derive(Clone, Debug)]
62pub struct Element {
63  pub name       : String,
64  pub controller : Controller,
65  pub model      : Model,
66  pub view       : View
67}
68
69/// An interface-level event
70#[derive(From, TryInto)]
71pub enum Action {
72  Create           (Tree <Element>, CreateOrder),
73  ModifyController (Box <dyn FnOnce (&mut Controller)>),
74  ModifyModel      (Box <dyn FnOnce (&mut Model)>),
75  ModifyView       (Box <dyn FnOnce (&mut View)>),
76  /// This will submit produce an event with the Model containing this callback
77  /// ID, but will *not* modify the current Model callback ID.
78  ///
79  /// See the Form widget control `FormSubmitCallback` for a control function
80  /// that submits a model with the currently set callback ID.
81  SubmitCallback   (application::CallbackId),
82  /// Change the view state from Enabled to Focused; it is a debug error if the
83  /// view state is not Enabled.
84  ///
85  /// If `top` is true, node will be moved to the last sibling position
86  /// ("top"), otherwise position relative to siblings will remain unchanged
87  Focus,
88  /// Change `view.state` from Disabled to Enabled; it is a debug error if the
89  /// view state is not Disabled
90  Enable,
91  /// Change the `view.state` from Enabled to Disabled; it is a debug error if
92  /// the view state is not Enabled
93  Disable,
94  /// Destroy the target element and children.
95  ///
96  /// If the node was focused, then focus is shifted to the parent. If it was
97  /// the root node that was focused, then this is always an error since the
98  /// root node is always focused as the common ancestor of all nodes.
99  Destroy,
100  /// Trigger any release buttons that exist in the current input map of the
101  /// controller of the target node.
102  ///
103  /// This can be used when focus is changing and input state should not be
104  /// orphaned.
105  ReleaseButtons
106}
107
108/// Either append or prepend newly created element
109#[derive(Clone, Copy, Debug, Eq, PartialEq)]
110pub enum CreateOrder {
111  Append,
112  Prepend,
113  NthSibling (u32)
114}
115
116impl <A, P> Interface <A, P> where
117  A : Application,
118  P : Presentation
119{
120  pub fn with_root (mut root : Element) -> Self {
121    log::trace!("with_root...");
122    root.focus();
123    let elements       = TreeBuilder::new().with_root (Node::new (root.clone()))
124      .build();
125    let focused_id     = elements.root_node_id().unwrap().clone();
126    let presentation   = P::with_root (root.view, focused_id.clone());
127    let input_buffer   = Some (vec![]);
128    let action_buffer  = Some (vec![]);
129    let display_buffer = vec![];
130    let event_buffer   = vec![];
131    let _phantom       = Default::default();
132    log::trace!("...with_root");
133    Interface {
134      elements, focused_id, presentation,
135      input_buffer, display_buffer, action_buffer, event_buffer,
136      _phantom
137    }
138  }
139
140  /// Handle an application request.
141  ///
142  /// Does not update presentation, must call `display()` to refresh display.
143  #[inline]
144  #[must_use]
145  #[allow(mismatched_lifetime_syntaxes)]
146  pub fn action (&mut self, node_id : &NodeId, action : Action)
147    -> std::vec::Drain <(NodeId, model::Event)>
148  {
149    self.handle_action (action, node_id);
150    self.event_buffer.drain(..)
151  }
152
153  /// Handles a batch of an application requests.
154  ///
155  /// Does not update presentation, must call `display()` to refresh display.
156  #[inline]
157  #[must_use]
158  #[allow(mismatched_lifetime_syntaxes)]
159  pub fn actions (&mut self, actions : Vec <(NodeId, Action)>)
160    -> std::vec::Drain <(NodeId, model::Event)>
161  {
162    for (node_id, action) in actions.into_iter() {
163      self.handle_action (action, &node_id);
164    }
165    self.event_buffer.drain(..)
166  }
167
168  /// Get and handle user input
169  #[must_use]
170  #[allow(mismatched_lifetime_syntaxes)]
171  pub fn update (&mut self) -> std::vec::Drain <(NodeId, model::Event)> {
172    log::trace!("update...");
173    // handle input
174    let mut action_buffer = self.action_buffer.take().unwrap();
175    let mut input_buffer  = self.input_buffer.take().unwrap();
176    debug_assert!(action_buffer.is_empty());
177    debug_assert!(input_buffer.is_empty());
178    self.presentation.get_input (&mut input_buffer);
179    for input in input_buffer.drain(..) {
180      log::trace!("input: {:?}", input);
181      // update global POINTER
182      match &input {
183        view::Input::Pointer (pointer) =>
184          *POINTER.write().unwrap() = pointer.clone(),
185        _ => {}
186      }
187      let focused_id = self.focused_element_id().clone();
188      let focused = self.focused_element();
189      // TODO: possibly allow a node to bubble even if input was handled ?
190      let button_release = match focused.controller.handle_input::<A> (
191        input, &self.elements, &focused_id, &mut action_buffer
192      ) {
193        Ok  (result) => result,
194        Err (mut input) => {
195          // bubble up to ancestors
196          debug_assert!(action_buffer.is_empty());
197          let mut button_release = None;
198          let input_mask = (&input).into();
199          if !focused.controller.bubble_trap.intersects (input_mask) {
200            for ancestor_id in self.elements.ancestor_ids (&focused_id)
201              .unwrap()
202            {
203              let ancestor = self.get_element (&ancestor_id);
204              input = match ancestor.controller.handle_input::<A> (
205                input, &self.elements, &ancestor_id, &mut action_buffer
206              ) {
207                Err (input)  => if ancestor.controller.bubble_trap
208                  .intersects (input_mask)
209                {
210                  break
211                } else {
212                  input
213                }
214                Ok  (result) => {
215                  button_release = result.map (|button_release| button_release);
216                  break
217                }
218              };
219            }
220          }
221          button_release
222        }
223      };
224      // handle actions
225      for (node_id, action) in action_buffer.drain(..) {
226        self.handle_action (action, &node_id);
227      }
228      // TODO: this was originally before handling the actions so that if focus
229      // changes, the release button is inserted into the newly focused node;
230      // however if the button release payload is a remove, we may want that to
231      // be processed by the original node before focus changes
232      if let Some (button_release) = button_release {
233        match button_release {
234          controller::ButtonRelease::Insert (input, controls) =>
235            for (control, node_id) in controls {
236              let element = self.get_element_mut (&node_id);
237              element.controller.release_button_insert (input, control);
238            }
239          controller::ButtonRelease::Remove (input, node_id) => {
240            let element = self.get_element_mut (&node_id);
241            element.controller.release_button_remove (input);
242          }
243        }
244      }
245    }
246    debug_assert!(action_buffer.is_empty());
247    debug_assert!(input_buffer.is_empty());
248    self.action_buffer = Some (action_buffer);
249    self.input_buffer  = Some (input_buffer);
250
251    log::trace!("...update");
252    // return application events
253    self.event_buffer.drain(..)
254  }
255
256  /// Presentation update
257  #[inline]
258  pub fn display (&mut self) {
259    log::trace!("display...");
260    self.presentation
261      .display_view (&self.elements, self.display_buffer.drain(..));
262    log::trace!("...display");
263  }
264
265  #[inline]
266  pub fn elements (&self) -> &Tree <Element> {
267    &self.elements
268  }
269
270  #[inline]
271  pub fn root (&self) -> &Element {
272    self.root_node().data()
273  }
274
275  pub fn root_node (&self) -> &Node <Element> {
276    self.elements.get (self.root_id()).unwrap()
277  }
278
279  #[inline]
280  pub fn root_id (&self) -> &NodeId {
281    self.elements.root_node_id().unwrap()
282  }
283
284  #[inline]
285  pub fn get_element (&self, node_id : &NodeId) -> &Element {
286    self.elements.get_element (node_id)
287  }
288
289  #[inline]
290  pub fn get_element_mut (&mut self, node_id : &NodeId) -> &mut Element {
291    self.elements.get_element_mut (node_id)
292  }
293
294  #[inline]
295  pub fn focused_element_id (&self) -> &NodeId {
296    &self.focused_id
297  }
298
299  #[inline]
300  pub fn focused_element (&self) -> &Element {
301    self.get_element (&self.focused_id)
302  }
303
304  #[inline]
305  pub fn focused_element_mut (&mut self) -> &mut Element {
306    let focused_id = self.focused_id.clone();
307    self.get_element_mut (&focused_id)
308  }
309
310  #[inline]
311  pub fn print_elements_tree (&self) {
312    let mut s = String::new();
313    self.elements.write_formatted (&mut s).unwrap();
314    println!("elements:\n{}", s);
315  }
316
317  #[inline]
318  pub fn log_elements_tree (&self) {
319    let mut s = String::new();
320    self.elements.write_formatted (&mut s).unwrap();
321    log::info!("elements:\n{}", s);
322  }
323
324  #[inline]
325  pub fn print_elements_tree_names (&self) {
326    let mut s = String::new();
327    self.elements.write_formatted_names (&mut s).unwrap();
328    println!("elements:\n{}", s);
329  }
330
331  #[inline]
332  pub fn log_elements_tree_names (&self) {
333    let mut s = String::new();
334    self.elements.write_formatted_names (&mut s).unwrap();
335    log::info!("elements:\n{}", s);
336  }
337
338  /// Create a new element and return the node ID
339  pub fn create_singleton (&mut self,
340    parent_id : &NodeId,
341    element   : Element,
342    order     : CreateOrder
343  ) -> NodeId {
344    match self.action (parent_id, Action::create_singleton (element, order))
345      .next().unwrap()
346    {
347      (_, model::Event::Create (_, new_id, _)) => new_id.clone(),
348      _ => unreachable!()
349    }
350  }
351
352  fn handle_action (&mut self, action : Action, node_id : &NodeId) {
353    use controller::component::{Kind, Selection};
354    log::trace!("handle_action...");
355    log::trace!("action: {:?}", action);
356    match action {
357      Action::Create (elements, order) => {
358        #[cfg(debug_assertions)]
359        for element in
360          elements.traverse_level_order (elements.root_node_id().unwrap())
361            .unwrap()
362        {
363          // check that appearances match the controller state
364          debug_assert_eq!(&element.data().view.appearance,
365            element.data().controller.get_appearance());
366        }
367        self.splice_subtree (
368          &elements, elements.root_node_id().unwrap(), node_id, order);
369      }
370      Action::ModifyController (f) => {
371        let controller = &mut self.get_element_mut (&node_id).controller;
372        f (controller);
373      }
374      Action::ModifyModel (f) => {
375        let model = {
376          let model = &mut self.get_element_mut (&node_id).model;
377          f (model);
378          model.clone()
379        };
380        self.event_buffer.push ((node_id.clone(), model::Event::Update (model)));
381      }
382      Action::ModifyView (f) => {
383        let view = {
384          let view = &mut self.get_element_mut (&node_id).view;
385          f (view);
386          // TODO: reset ephemeral fields (sound triggers)
387          view.clone()
388        };
389        self.display_buffer.push (
390          (node_id.clone(), view::Display::Update (view.into())));
391      }
392      Action::SubmitCallback (callback_id) => {
393        let callback_id = Some (callback_id);
394        let model = Model {
395          callback_id, .. self.get_element (&node_id).model.clone()
396        };
397        self.event_buffer.push ((node_id.clone(), model::Event::Submit (model)));
398      }
399      Action::Focus => {
400        let mut focus_id = Some (node_id.clone());
401        while let Some (id) = focus_id {
402          focus_id = self.change_focus (&id);
403          // handle re-ordering
404          if self.get_element (&id).controller.focus_top {
405            self.elements.make_last_sibling (&id).unwrap();
406            self.display_buffer.push (
407              (id.clone(), view::Display::Update (view::Update::FocusTop)));
408          }
409          let ancestor_ids = self.elements.ancestor_ids (&id).unwrap().cloned()
410            .collect::<Vec <_>>();
411          for ancestor_id in ancestor_ids {
412            if self.get_element (&ancestor_id).controller.focus_top {
413              self.elements.make_last_sibling (&ancestor_id).unwrap();
414              self.display_buffer.push (
415                ( ancestor_id.clone(),
416                  view::Display::Update (view::Update::FocusTop)
417                )
418              );
419            }
420          }
421        }
422      }
423      Action::Enable => {
424        let view = {
425          let element = self.get_element_mut (&node_id);
426          element.controller.state.enable();
427          element.view.appearance = element.controller.get_appearance().clone();
428          element.view.clone()
429        };
430        self.display_buffer.push (
431          (node_id.clone(), view::Display::Update (view.into())));
432      }
433      Action::Disable => {
434        let view = {
435          let element = self.get_element_mut (&node_id);
436          element.controller.state.disable();
437          element.view.appearance = element.controller.get_appearance().clone();
438          element.view.clone()
439        };
440        self.display_buffer.push (
441          (node_id.clone(), view::Display::Update (view.into())));
442      }
443      Action::Destroy => {
444        let parent_id = self.elements.get_parent_id (&node_id).clone();
445        let focused = self.elements.get_element (&node_id).controller.state ==
446          controller::State::Focused;
447        { // widget-specific destroy logic
448          let mut children_ids = self.elements.children_ids (&parent_id)
449            .unwrap();
450          // menu: we want to update the selection here so that the destroyed
451          // node is not refocused below
452          let first_sibling_id = children_ids.next().unwrap().clone();
453          let first_sibling    = self.elements.get_element (&first_sibling_id);
454          if let Ok (Widget (selection, _, _)) = Menu::try_from (first_sibling) {
455            if selection.current.as_ref() == Some (node_id) {
456              let mut select = None;
457              for sibling_id in children_ids {
458                if sibling_id == node_id {
459                  continue
460                }
461                let sibling = self.elements.get_element (&sibling_id);
462                if sibling.controller.state == controller::State::Enabled &&
463                  Frame::try_from (sibling).is_ok()
464                {
465                  select = Some (sibling_id.clone());
466                  break
467                }
468              }
469              let deselect = Box::new (move |controller : &mut Controller|{
470                let selection =
471                  Selection::try_ref_mut (&mut controller.component).unwrap();
472                selection.current = select;
473              });
474              self.handle_action (Action::ModifyController (deselect),
475                &first_sibling_id);
476            }
477          }
478        }
479        if focused {
480          let mut focus_id = Some (parent_id.clone());
481          while let Some (id) = focus_id {
482            focus_id = self.change_focus (&id);
483          }
484        }
485        for node_id in self.elements.traverse_post_order_ids (&node_id)
486          .unwrap()
487        {
488          self.event_buffer.push   ((node_id.clone(), model::Event::Destroy));
489          self.display_buffer.push ((node_id,         view::Display::Destroy));
490        }
491        let _ = self.elements
492          .remove_node (node_id.clone(), tree::RemoveBehavior::DropChildren)
493          .unwrap();
494      }
495      Action::ReleaseButtons => {
496        use controller::controls::Control;
497        let release_buttons =
498          self.elements.get_element_mut (node_id).controller.release_buttons();
499        for control in release_buttons {
500          control.fun::<A::ButtonControls>().0 (
501            &None, &self.elements, node_id,
502            self.action_buffer.as_mut().unwrap()
503          );
504        }
505        let mut action_buffer = self.action_buffer.take().unwrap();
506        for (node_id, action) in action_buffer.drain(..) {
507          self.handle_action (action, &node_id);
508        }
509        self.action_buffer = Some (action_buffer);
510      }
511    }
512    log::trace!("...handle_action");
513  }
514
515  /// Insert node as child of the given node ID
516  fn insert_child (&mut self,
517    parent_id : &NodeId,
518    child     : Node <Element>,
519    order     : CreateOrder
520  ) -> NodeId {
521    let child_model = child.data().model.clone();
522    let child_view  = child.data().view.clone();
523    let child_id    = self.elements.insert (
524      child, tree::InsertBehavior::UnderNode (parent_id)).unwrap();
525    match order {
526      CreateOrder::Append  => {}
527      CreateOrder::Prepend => {
528        let _ = self.elements.make_first_sibling (&child_id).unwrap();
529      }
530      CreateOrder::NthSibling (n) => {
531        let _ = self.elements.make_nth_sibling (&child_id, n as usize).unwrap();
532      }
533    }
534    self.event_buffer.push ((parent_id.clone(),
535      model::Event::Create (child_model, child_id.clone(), order)));
536    self.display_buffer.push ((parent_id.clone(),
537      view::Display::Create (child_view, child_id.clone(), order)));
538    child_id
539  }
540
541  /// Defocus the currently focused node and focuses the target.
542  ///
543  /// Returns a new focus ID if focus should be redirected.
544  fn change_focus (&mut self, target_id : &NodeId) -> Option <NodeId> {
545    use controller::component::{Kind, Selection};
546    log::trace!("change_focus...");
547    let focused_id = self.focused_element_id().clone();
548    let focused_ancestors = self.elements.ancestor_ids (&focused_id).unwrap()
549      .cloned().collect::<Vec <NodeId>>();
550    let target_ancestors = self.elements.ancestor_ids (target_id).unwrap()
551      .cloned().collect::<Vec <NodeId>>();
552    let maybe_common_ancestor_id = {
553      focused_ancestors.iter().rev().zip (target_ancestors.iter().rev())
554        .filter_map (|(a, b)|
555          if a == b {
556            Some (a)
557          } else {
558            None
559          })
560        .cloned().enumerate().last()
561    };
562    let focused_ancestor_of_target = target_ancestors.contains (&focused_id);
563    let target_ancestor_of_focused = focused_ancestors.contains (&target_id);
564    { // defocus currently focused node and ancestors up to common ancestor
565      let mut defocus = |defocus_id| {
566        let view = {
567          // widget-specific defocus logic here
568          let mut actions  = vec![];
569          let focused_node = self.elements.get (&defocus_id).unwrap();
570          // release button if the focused node is a button widget and it was
571          // pressed ('on')
572          if let Some (sub_child_id) = focused_node.children().first() {
573            if let Ok (Widget (switch, _, _)) =
574              Button::try_get (&self.elements, sub_child_id)
575            {
576              if switch.state == switch::State::On && !switch.toggle {
577                button::release (
578                  &None, &self.elements, &defocus_id, &mut actions);
579              }
580            }
581          }
582          for (node_id, action) in actions.into_iter() {
583            self.handle_action (action, &node_id);
584          }
585          let focused = self.elements.get_mut (&defocus_id).unwrap().data_mut();
586          focused.defocus();
587          let view    = focused.view.clone();
588          focused.view.appearance.sound = None;  // sounds are ephemeral events
589          view
590        };
591        self.display_buffer .push ((defocus_id, Display::Update (view.into())));
592      };
593      // do not defocus if focused node is an ancestor of the target
594      if !focused_ancestor_of_target {
595        defocus (focused_id);
596      }
597      if let Some ((_, common_ancestor_id)) = maybe_common_ancestor_id.as_ref() {
598        for ancestor_id in focused_ancestors.into_iter()
599          .take_while (|id| id != common_ancestor_id && id != target_id)
600        {
601          defocus (ancestor_id);
602        }
603      }
604    }
605    let refocus_id = {
606      // focus from common ancestor to target node
607      let mut focus = |focus_id| {
608        // widget-specific focus logic
609        if Frame::try_from (self.get_element (&focus_id)).is_ok() {
610          // update selection if frame is a menu item
611          let parent_id = self.elements.get_parent_id (&focus_id);
612          let first_sibling_id = self.elements.children_ids (&parent_id).unwrap()
613            .next().unwrap().clone();
614          if first_sibling_id != focus_id {
615            let first_sibling = self.elements.get_element (&first_sibling_id);
616            if let Ok (Widget (selection, _, _)) =
617              Menu::try_from (first_sibling)
618            {
619              if selection.current.as_ref() != Some (&focus_id) {
620                let select_id = focus_id.clone();
621                let select = Box::new (move |controller : &mut Controller|{
622                  let selection =
623                    Selection::try_ref_mut (&mut controller.component).unwrap();
624                  selection.current = Some (select_id.clone());
625                });
626                self.handle_action (Action::ModifyController (select),
627                  &first_sibling_id);
628              }
629            }
630          }
631        }
632        let focus = self.get_element_mut (&focus_id);
633        focus.focus();
634        let view = focus.view.clone();
635        focus.view.appearance.sound = None;  // sounds are ephemeral events
636        self.display_buffer.push (
637          (focus_id.clone(), view::Display::Update (view.into())));
638      };
639      let depth = if let Some ((depth, _)) = maybe_common_ancestor_id {
640        depth + 1 + if focused_ancestor_of_target { 1 } else { 0 }
641      } else {
642        1
643      };
644      for ancestor_id in target_ancestors.into_iter().rev().skip (depth) {
645        focus (ancestor_id);
646      }
647      // do not focus if target is ancestor of the currently focused node
648      // (the node should already be focused)
649      if !target_ancestor_of_focused {
650        focus (target_id.clone());
651      }
652      // only call refocus on the last node: intermediate nodes are not
653      // redirected
654      controller::refocus (target_id, self.elements())
655    };
656    self.focused_id = target_id.clone();
657    log::trace!("...change_focus");
658    refocus_id
659  }
660
661  /// See also public `crate::utils::splice_subtree` for operating on subtrees
662  /// before insertion into the interface
663  fn splice_subtree (&mut self,
664    other     : &Tree <Element>,
665    other_id  : &NodeId,
666    parent_id : &NodeId,
667    order     : CreateOrder
668  ) -> NodeId {
669    // TODO: avoid clone here?
670    let subtree_root = Node::new (other.get (&other_id).unwrap().data().clone());
671    let subtree_id   = self.insert_child (parent_id, subtree_root, order);
672    for child_id in other.children_ids (other_id).unwrap() {
673      self.splice_subtree (other, child_id, &subtree_id, CreateOrder::Append);
674    }
675    subtree_id
676  }
677
678  /// This is method is provided to allow initialization of composite
679  /// presentations by first initializing an interface with
680  /// `G::make_interface()`--the graphical backend creates the interface with a
681  /// default initial interface, usually containing a root screen element--and
682  /// then adding a default initialized audio backend.
683  pub (crate) fn swap_presentation <P2 : Presentation> (self,
684    f : impl FnOnce (P) -> P2
685  ) -> Interface <A, P2> {
686    let Interface {
687      elements, focused_id, presentation,
688      input_buffer, display_buffer, action_buffer, event_buffer,
689      _phantom
690    } = self;
691    Interface {
692      presentation: f (presentation),
693      elements, focused_id, input_buffer, display_buffer, action_buffer,
694      event_buffer, _phantom
695    }
696  }
697}
698
699impl Element {
700  /// Create a new element. Note that the view appearance will always be set to
701  /// the current appearance defined by the controller state.
702  pub fn new (
703    name : String, controller : Controller, model : Model, mut view : View
704  ) -> Self {
705    view.appearance = controller.get_appearance().clone();
706    Element { name, controller, view, model }
707  }
708  pub fn focus (&mut self) {
709    self.controller.state.focus();
710    self.controller.update_view_focus (&mut self.view);
711  }
712  pub fn defocus (&mut self) {
713    self.controller.state.defocus();
714    self.controller.update_view_focus (&mut self.view);
715  }
716  pub fn disable (&mut self) {
717    self.controller.state.disable();
718    self.controller.update_view_focus (&mut self.view);
719  }
720}
721
722impl Default for Element {
723  fn default() -> Self {
724    Element::new (
725      "".to_string(), Controller::default(), Model::default(), View::default())
726  }
727}
728
729impl AsRef <Controller> for Element {
730  fn as_ref (&self) -> &Controller {
731    &self.controller
732  }
733}
734
735impl AsRef <Model> for Element {
736  fn as_ref (&self) -> &Model {
737    &self.model
738  }
739}
740
741impl AsRef <View> for Element {
742  fn as_ref (&self) -> &View {
743    &self.view
744  }
745}
746
747impl Action {
748  /// Produces a Create action that creates a singleton subtree containing the
749  /// given Element
750  #[inline]
751  pub fn create_singleton (element : Element, order : CreateOrder) -> Self {
752    let subtree = TreeBuilder::new().with_root (Node::new (element)).build();
753    Action::Create (subtree, order)
754  }
755
756  /// Produces a ModifyView action that sets the given View data.
757  #[inline]
758  pub fn set_view (view : View) -> Self {
759    Action::ModifyView (Box::new (|v| *v = view))
760  }
761
762  /// Produces a ModifyController action that sets the given Controller data.
763  #[inline]
764  pub fn set_controller (controller : Controller) -> Self {
765    Action::ModifyController (Box::new (|c| *c = controller))
766  }
767
768  /// Produces a ModifyModel action that sets the given Model data.
769  #[inline]
770  pub fn set_model (model : Model) -> Self {
771    Action::ModifyModel (Box::new (|m| *m = model))
772  }
773
774  /// Produces a ModifyView action that sets the given component Kind
775  #[inline]
776  pub fn set_view_component <V> (component : V) -> Self where
777    V : view::component::Kind + 'static
778  {
779    Action::ModifyView (Box::new (|v| v.component = component.into()))
780  }
781
782  /// Produces a ModifyView action that updates the current component with the
783  /// given value and panics if the current component is not the same Kind
784  #[inline]
785  pub fn update_view_component <V> (component : V) -> Self where
786    V : view::component::Kind + 'static
787  {
788    Action::ModifyView (Box::new (|v| {
789      let v = V::try_ref_mut (&mut v.component).unwrap();
790      *v = component;
791    }))
792  }
793
794  /// Produces a ModifyController action that sets the given component Kind
795  #[inline]
796  pub fn set_controller_component <V> (component : V) -> Self where
797    V : controller::component::Kind + 'static
798  {
799    Action::ModifyController (Box::new (|c| c.component = component.into()))
800  }
801
802  /// Produces a ModifyController action that updates the current component with the
803  /// given value and panics if the current component is not the same Kind
804  #[inline]
805  pub fn update_controller_component <V> (component : V) -> Self where
806    V : controller::component::Kind + 'static
807  {
808    Action::ModifyController (Box::new (|c| {
809      let c = V::try_ref_mut (&mut c.component).unwrap();
810      *c = component;
811    }))
812  }
813
814  /// Produces a ModifyModel action that sets the given component Kind
815  #[inline]
816  pub fn set_model_component <V> (component : V) -> Self where
817    V : model::component::Kind + 'static
818  {
819    Action::ModifyModel (Box::new (|m| m.component = component.into()))
820  }
821
822  /// Produces a ModifyModel action that updates the current component with the
823  /// given value and panics if the current component is not the same Kind
824  #[inline]
825  pub fn update_model_component <V> (component : V) -> Self where
826    V : model::component::Kind + 'static
827  {
828    Action::ModifyModel (Box::new (|m| {
829      let m = V::try_ref_mut (&mut m.component).unwrap();
830      *m = component;
831    }))
832  }
833}
834
835impl std::fmt::Debug for Action {
836  fn fmt (&self, f : &mut std::fmt::Formatter) -> Result <(), std::fmt::Error> {
837    match self {
838      Action::Create (subtree, order)        =>
839        write!(f, "Create({:?}, {:?})", subtree, order),
840      Action::ModifyController (closure)     =>
841        write!(f, "ModifyController({:p})", &closure),
842      Action::ModifyModel      (closure)     =>
843        write!(f, "ModifyModel({:p})", &closure),
844      Action::ModifyView       (closure)     =>
845        write!(f, "ModifyView({:p})", &closure),
846      Action::SubmitCallback   (callback_id) =>
847        write!(f, "SubmitCallback({:?})", callback_id),
848      Action::Focus   => write!(f, "Focus"),
849      Action::Enable  => write!(f, "Enable"),
850      Action::Disable => write!(f, "Disable"),
851      Action::Destroy => write!(f, "Destroy"),
852      Action::ReleaseButtons => write!(f, "ReleaseButtons")
853    }
854  }
855}
856
857impl Default for CreateOrder {
858  fn default() -> Self {
859    CreateOrder::Append
860  }
861}