1use crate::window;
2
3#[derive(Debug)]
10pub struct Shell<'a, Message> {
11 messages: &'a mut Vec<Message>,
12 redraw_request: Option<window::RedrawRequest>,
13 is_layout_invalid: bool,
14 are_widgets_invalid: bool,
15}
16
17impl<'a, Message> Shell<'a, Message> {
18 pub fn new(messages: &'a mut Vec<Message>) -> Self {
20 Self {
21 messages,
22 redraw_request: None,
23 is_layout_invalid: false,
24 are_widgets_invalid: false,
25 }
26 }
27
28 pub fn is_empty(&self) -> bool {
30 self.messages.is_empty()
31 }
32
33 pub fn publish(&mut self, message: Message) {
35 self.messages.push(message);
36 }
37
38 pub fn request_redraw(&mut self, request: window::RedrawRequest) {
40 match self.redraw_request {
41 None => {
42 self.redraw_request = Some(request);
43 }
44 Some(current) if request < current => {
45 self.redraw_request = Some(request);
46 }
47 _ => {}
48 }
49 }
50
51 pub fn redraw_request(&self) -> Option<window::RedrawRequest> {
53 self.redraw_request
54 }
55
56 pub fn is_layout_invalid(&self) -> bool {
58 self.is_layout_invalid
59 }
60
61 pub fn invalidate_layout(&mut self) {
65 self.is_layout_invalid = true;
66 }
67
68 pub fn revalidate_layout(&mut self, f: impl FnOnce()) {
71 if self.is_layout_invalid {
72 self.is_layout_invalid = false;
73
74 f();
75 }
76 }
77
78 pub fn are_widgets_invalid(&self) -> bool {
81 self.are_widgets_invalid
82 }
83
84 pub fn invalidate_widgets(&mut self) {
88 self.are_widgets_invalid = true;
89 }
90
91 pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
96 self.messages.extend(other.messages.drain(..).map(f));
97
98 if let Some(at) = other.redraw_request {
99 self.request_redraw(at);
100 }
101
102 self.is_layout_invalid =
103 self.is_layout_invalid || other.is_layout_invalid;
104
105 self.are_widgets_invalid =
106 self.are_widgets_invalid || other.are_widgets_invalid;
107 }
108}