1use freya_core::prelude::*;
2use torin::prelude::*;
3
4#[derive(Debug, Default, PartialEq, Clone, Copy)]
5pub enum TileStatus {
6 #[default]
7 Idle,
8 Hovering,
9}
10
11#[derive(Clone, PartialEq)]
12pub struct Tile {
13 children: Vec<Element>,
14 leading: Option<Element>,
15 on_select: Option<EventHandler<()>>,
16 key: DiffKey,
17}
18
19impl KeyExt for Tile {
20 fn write_key(&mut self) -> &mut DiffKey {
21 &mut self.key
22 }
23}
24
25impl Default for Tile {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl ChildrenExt for Tile {
32 fn get_children(&mut self) -> &mut Vec<Element> {
33 &mut self.children
34 }
35}
36
37impl Tile {
38 pub fn new() -> Self {
39 Self {
40 children: Vec::new(),
41 leading: None,
42 on_select: None,
43 key: DiffKey::None,
44 }
45 }
46
47 pub fn leading(mut self, leading: impl Into<Element>) -> Self {
48 self.leading = Some(leading.into());
49 self
50 }
51
52 pub fn on_select(mut self, on_select: impl FnMut(()) + 'static) -> Self {
53 self.on_select = Some(EventHandler::new(on_select));
54 self
55 }
56
57 pub fn key(mut self, key: impl Into<DiffKey>) -> Self {
58 self.key = key.into();
59 self
60 }
61}
62
63impl Render for Tile {
64 fn render(&self) -> impl IntoElement {
65 let mut status = use_state(|| TileStatus::Idle);
66
67 let on_press = {
68 let on_select = self.on_select.clone();
69 move |e: Event<PressEventData>| {
70 if let Some(on_select) = &on_select {
71 e.stop_propagation();
72 on_select.call(());
73 }
74 }
75 };
76
77 let on_pointer_enter = {
78 move |_| {
79 *status.write() = TileStatus::Hovering;
80 }
81 };
82
83 let on_pointer_leave = {
84 move |_| {
85 *status.write() = TileStatus::Idle;
86 }
87 };
88
89 rect()
90 .direction(Direction::Horizontal)
91 .padding(8.)
92 .spacing(8.)
93 .cross_align(Alignment::center())
94 .on_press(on_press)
95 .on_pointer_enter(on_pointer_enter)
96 .on_pointer_leave(on_pointer_leave)
97 .maybe_child(
98 self.leading
99 .clone()
100 .map(|leading| rect().padding(Gaps::new_all(4.0)).child(leading)),
101 )
102 .children(self.children.clone())
103 }
104
105 fn render_key(&self) -> DiffKey {
106 self.key.clone().or(self.default_key())
107 }
108}