1use crate::clipboard;
2use crate::event;
3use crate::window;
4use crate::{Clipboard, InputMethod};
5
6#[derive(Debug)]
13pub struct Shell<'a, Message> {
14 messages: &'a mut Vec<Message>,
15 event_status: event::Status,
16 redraw_request: window::RedrawRequest,
17 input_method: InputMethod,
18 is_layout_invalid: bool,
19 are_widgets_invalid: bool,
20 clipboard: Clipboard,
21}
22
23impl<'a, Message> Shell<'a, Message> {
24 pub fn new(messages: &'a mut Vec<Message>) -> Self {
26 Self {
27 messages,
28 event_status: event::Status::Ignored,
29 redraw_request: window::RedrawRequest::Wait,
30 is_layout_invalid: false,
31 are_widgets_invalid: false,
32 input_method: InputMethod::Disabled,
33 clipboard: Clipboard {
34 reads: Vec::new(),
35 write: None,
36 },
37 }
38 }
39
40 #[must_use]
42 pub fn is_empty(&self) -> bool {
43 self.messages.is_empty()
44 }
45
46 pub fn publish(&mut self, message: Message) {
48 self.messages.push(message);
49 }
50
51 pub fn capture_event(&mut self) {
56 self.event_status = event::Status::Captured;
57 }
58
59 #[must_use]
61 pub fn event_status(&self) -> event::Status {
62 self.event_status
63 }
64
65 #[must_use]
67 pub fn is_event_captured(&self) -> bool {
68 self.event_status == event::Status::Captured
69 }
70
71 pub fn request_redraw(&mut self) {
73 self.redraw_request = window::RedrawRequest::NextFrame;
74 }
75
76 pub fn request_redraw_at(&mut self, redraw_request: impl Into<window::RedrawRequest>) {
78 self.redraw_request = self.redraw_request.min(redraw_request.into());
79 }
80
81 #[must_use]
83 pub fn redraw_request(&self) -> window::RedrawRequest {
84 self.redraw_request
85 }
86
87 pub fn replace_redraw_request(shell: &mut Self, redraw_request: window::RedrawRequest) {
93 shell.redraw_request = redraw_request;
94 }
95
96 pub fn read_clipboard(&mut self, kind: clipboard::Kind) {
100 self.clipboard.reads.push(kind);
101 }
102
103 pub fn write_clipboard(&mut self, content: clipboard::Content) {
107 self.clipboard.write = Some(content);
108 }
109
110 pub fn clipboard_mut(&mut self) -> &mut Clipboard {
112 &mut self.clipboard
113 }
114
115 pub fn request_input_method<T: AsRef<str>>(&mut self, ime: &InputMethod<T>) {
120 self.input_method.merge(ime);
121 }
122
123 #[must_use]
125 pub fn input_method(&self) -> &InputMethod {
126 &self.input_method
127 }
128
129 #[must_use]
131 pub fn input_method_mut(&mut self) -> &mut InputMethod {
132 &mut self.input_method
133 }
134
135 #[must_use]
137 pub fn is_layout_invalid(&self) -> bool {
138 self.is_layout_invalid
139 }
140
141 pub fn invalidate_layout(&mut self) {
145 self.is_layout_invalid = true;
146 }
147
148 pub fn revalidate_layout(&mut self, f: impl FnOnce()) {
151 if self.is_layout_invalid {
152 self.is_layout_invalid = false;
153
154 f();
155 }
156 }
157
158 #[must_use]
161 pub fn are_widgets_invalid(&self) -> bool {
162 self.are_widgets_invalid
163 }
164
165 pub fn invalidate_widgets(&mut self) {
169 self.are_widgets_invalid = true;
170 }
171
172 pub fn merge<B>(&mut self, mut other: Shell<'_, B>, f: impl Fn(B) -> Message) {
177 self.messages.extend(other.messages.drain(..).map(f));
178
179 self.is_layout_invalid = self.is_layout_invalid || other.is_layout_invalid;
180 self.are_widgets_invalid = self.are_widgets_invalid || other.are_widgets_invalid;
181 self.redraw_request = self.redraw_request.min(other.redraw_request);
182 self.event_status = self.event_status.merge(other.event_status);
183
184 self.input_method.merge(&other.input_method);
185 self.clipboard.merge(&mut other.clipboard);
186 }
187}