1use crate::InputMethod;
2use crate::event;
3use crate::window;
4
5#[derive(Debug)]
12pub struct Shell<'a, Message> {
13 messages: &'a mut Vec<Message>,
14 event_status: event::Status,
15 redraw_request: window::RedrawRequest,
16 input_method: InputMethod,
17 is_layout_invalid: bool,
18 are_widgets_invalid: bool,
19}
20
21impl<'a, Message> Shell<'a, Message> {
22 pub fn new(messages: &'a mut Vec<Message>) -> Self {
24 Self {
25 messages,
26 event_status: event::Status::Ignored,
27 redraw_request: window::RedrawRequest::Wait,
28 is_layout_invalid: false,
29 are_widgets_invalid: false,
30 input_method: InputMethod::Disabled,
31 }
32 }
33
34 #[must_use]
36 pub fn is_empty(&self) -> bool {
37 self.messages.is_empty()
38 }
39
40 pub fn publish(&mut self, message: Message) {
42 self.messages.push(message);
43 }
44
45 pub fn capture_event(&mut self) {
50 self.event_status = event::Status::Captured;
51 }
52
53 #[must_use]
55 pub fn event_status(&self) -> event::Status {
56 self.event_status
57 }
58
59 #[must_use]
61 pub fn is_event_captured(&self) -> bool {
62 self.event_status == event::Status::Captured
63 }
64
65 pub fn request_redraw(&mut self) {
67 self.redraw_request = window::RedrawRequest::NextFrame;
68 }
69
70 pub fn request_redraw_at(&mut self, redraw_request: impl Into<window::RedrawRequest>) {
72 self.redraw_request = self.redraw_request.min(redraw_request.into());
73 }
74
75 #[must_use]
77 pub fn redraw_request(&self) -> window::RedrawRequest {
78 self.redraw_request
79 }
80
81 pub fn replace_redraw_request(shell: &mut Self, redraw_request: window::RedrawRequest) {
87 shell.redraw_request = redraw_request;
88 }
89
90 pub fn request_input_method<T: AsRef<str>>(&mut self, ime: &InputMethod<T>) {
95 self.input_method.merge(ime);
96 }
97
98 #[must_use]
100 pub fn input_method(&self) -> &InputMethod {
101 &self.input_method
102 }
103
104 #[must_use]
106 pub fn input_method_mut(&mut self) -> &mut InputMethod {
107 &mut self.input_method
108 }
109
110 #[must_use]
112 pub fn is_layout_invalid(&self) -> bool {
113 self.is_layout_invalid
114 }
115
116 pub fn invalidate_layout(&mut self) {
120 self.is_layout_invalid = true;
121 }
122
123 pub fn revalidate_layout(&mut self, f: impl FnOnce()) {
126 if self.is_layout_invalid {
127 self.is_layout_invalid = false;
128
129 f();
130 }
131 }
132
133 #[must_use]
136 pub fn are_widgets_invalid(&self) -> bool {
137 self.are_widgets_invalid
138 }
139
140 pub fn invalidate_widgets(&mut self) {
144 self.are_widgets_invalid = true;
145 }
146
147 pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
152 self.messages.extend(other.messages.drain(..).map(f));
153
154 self.is_layout_invalid = self.is_layout_invalid || other.is_layout_invalid;
155
156 self.are_widgets_invalid = self.are_widgets_invalid || other.are_widgets_invalid;
157
158 self.redraw_request = self.redraw_request.min(other.redraw_request);
159 self.event_status = self.event_status.merge(other.event_status);
160 self.input_method.merge(&other.input_method);
161 }
162}