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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::common::*;
#[derive(Debug, Clone, PartialEq)]
pub enum StackEvent {
SetIndex(i32),
IndexChanged(i32, Entity),
}
pub struct Stack {
current_index: i32,
pages: Vec<Entity>,
on_index_changed: Option<Box<dyn Fn(&mut Self, &mut State, Entity)>>,
}
impl Stack {
pub fn new() -> Self {
Self {
current_index: -1,
pages: Vec::new(),
on_index_changed: None,
}
}
pub fn on_index_changed<F>(mut self, callback: F) -> Self
where F: 'static + Fn(&mut Self, &mut State, Entity)
{
self.on_index_changed = Some(Box::new(callback));
self
}
pub fn get_current_index(&self) -> i32 {
self.current_index
}
pub fn get_num_pages(&self) -> usize {
self.pages.len()
}
pub fn set_current_index(&mut self, state: &mut State, entity: Entity, new_index: i32) {
if new_index != self.current_index {
self.current_index = new_index;
if let Some(current_child) = state.tree.get_child(entity, self.current_index as usize) {
for page in self.pages.iter() {
page.set_display(state, Display::None);
}
current_child.set_display(state, Display::Flex);
}
if let Some(callback) = self.on_index_changed.take() {
(callback)(self, state, entity);
self.on_index_changed = Some(callback);
}
}
}
}
impl Widget for Stack {
type Ret = Entity;
type Data = ();
fn on_build(&mut self, state: &mut State, entity: Entity) -> Self::Ret {
entity.set_element(state, "stack")
}
fn on_event(&mut self, state: &mut State, entity: Entity, event: &mut Event) {
if let Some(window_event) = event.message.downcast() {
match window_event {
WindowEvent::ChildAdded(child) => {
if self.current_index != 0 {
child.set_display(state, Display::None);
}
self.pages.push(*child);
self.set_current_index(state, entity, self.pages.len() as i32 - 1);
}
_=> {}
}
}
if let Some(stack_event) = event.message.downcast() {
match stack_event {
StackEvent::SetIndex(index) => {
self.set_current_index(state, entity, *index)
}
_=> {}
}
}
}
}