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(
72 &mut self,
73 redraw_request: impl Into<window::RedrawRequest>,
74 ) {
75 self.redraw_request = self.redraw_request.min(redraw_request.into());
76 }
77
78 #[must_use]
80 pub fn redraw_request(&self) -> window::RedrawRequest {
81 self.redraw_request
82 }
83
84 pub fn replace_redraw_request(
90 shell: &mut Self,
91 redraw_request: window::RedrawRequest,
92 ) {
93 shell.redraw_request = redraw_request;
94 }
95
96 pub fn request_input_method<T: AsRef<str>>(
101 &mut self,
102 ime: &InputMethod<T>,
103 ) {
104 self.input_method.merge(ime);
105 }
106
107 #[must_use]
109 pub fn input_method(&self) -> &InputMethod {
110 &self.input_method
111 }
112
113 #[must_use]
115 pub fn input_method_mut(&mut self) -> &mut InputMethod {
116 &mut self.input_method
117 }
118
119 #[must_use]
121 pub fn is_layout_invalid(&self) -> bool {
122 self.is_layout_invalid
123 }
124
125 pub fn invalidate_layout(&mut self) {
129 self.is_layout_invalid = true;
130 }
131
132 pub fn revalidate_layout(&mut self, f: impl FnOnce()) {
135 if self.is_layout_invalid {
136 self.is_layout_invalid = false;
137
138 f();
139 }
140 }
141
142 #[must_use]
145 pub fn are_widgets_invalid(&self) -> bool {
146 self.are_widgets_invalid
147 }
148
149 pub fn invalidate_widgets(&mut self) {
153 self.are_widgets_invalid = true;
154 }
155
156 pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
161 self.messages.extend(other.messages.drain(..).map(f));
162
163 self.is_layout_invalid =
164 self.is_layout_invalid || other.is_layout_invalid;
165
166 self.are_widgets_invalid =
167 self.are_widgets_invalid || other.are_widgets_invalid;
168
169 self.redraw_request = self.redraw_request.min(other.redraw_request);
170 self.event_status = self.event_status.merge(other.event_status);
171 self.input_method.merge(&other.input_method);
172 }
173}