1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! Types describing rendered components.

use std::{ops::Deref, sync::Arc};

use crate::{
  components::{Component, Empty},
  event::{KeyEvent, MouseEvent},
  terminal::{Frame, Rect},
};

/// An opaque type holding a struct that implements [`Element`].
///
/// [`Element`]: trait.Element.html
#[derive(Clone)]
pub struct Any(Arc<dyn Element + Send + Sync>);

impl Any {
  pub fn new<C: Element + 'static + Send + Sync>(element: C) -> Self {
    Self(Arc::new(element))
  }
}

impl Default for Any {
  fn default() -> Self {
    Empty {}.into()
  }
}

impl Deref for Any {
  type Target = Arc<dyn Element + Send + Sync>;

  fn deref(&self) -> &Self::Target {
    &self.0
  }
}

impl<C: Component + 'static> From<C> for Any {
  fn from(component: C) -> Self {
    component.render()
  }
}

/// A rendered component.
///
/// Once a [`Component`] is rendered, it now can be drawn (through [`draw`]) or it
/// can handle a key event (through [`on_key`]).
///
/// # Drawing
/// Intuitive internally uses [tui] in order to draw to the terminal. The [`Rect`]
/// and [`Frame`] structures are re-exports from [tui].
///
/// # Handling Keys
/// Typically, structures that implement `Element` do not have any [`State`].
/// Usually, an `Element` will contain an `on_key` field which has captured any
/// state that could be mutated, and then the `Element` will delegate key events
/// to its `on_key` field. See the [`Section` source] for an example of this.
///
/// [`Component`]: ../components/trait.Component.html
/// [`draw`]: #method.draw
/// [`Frame`]: https://docs.rs/tui/latest/tui/terminal/struct.Frame.html
/// [`on_key`]: #method.on_key
/// [`Rect`]: https://docs.rs/tui/latest/tui/layout/struct.Rect.html
/// [`Section` source]: ../../src/intuitive/components/section.rs.html
/// [`State`]: ../state/struct.State.html
/// [tui]: https://docs.rs/tui/latest/tui/
pub trait Element {
  fn draw(&self, _rect: Rect, _frame: &mut Frame) {}
  fn on_key(&self, _event: KeyEvent) {}
  fn on_mouse(&self, _rect: Rect, _event: MouseEvent) {}
}