1use iced::{Subscription, event, system, window};
6
7use plushie_widget_sdk::runtime::{KeyEventData, Message};
8
9use crate::App;
10use crate::constants::*;
11
12impl App {
13 fn has_host_or_widget_subscription(&self, kind: &str) -> bool {
23 self.core.has_subscription(kind) || self.registry.has_widget_subscription(kind)
24 }
25
26 pub fn renderer_subscriptions(&self) -> Subscription<Message> {
30 let mut subs = vec![
31 window::close_events().map(Message::WindowClosed),
33 ];
34
35 let has_on_event = self.has_host_or_widget_subscription(SUB_EVENT);
36
37 self.keyboard_subscriptions(has_on_event, &mut subs);
38 self.mouse_subscriptions(has_on_event, &mut subs);
39 self.touch_subscriptions(has_on_event, &mut subs);
40 self.ime_subscriptions(has_on_event, &mut subs);
41 self.window_subscriptions(&mut subs);
42 self.system_subscriptions(&mut subs);
43
44 if has_on_event {
53 subs.push(event::listen_with(|evt, status, window| {
54 let captured = status == iced::event::Status::Captured;
55 match evt {
56 iced::Event::Keyboard(iced::keyboard::Event::KeyPressed {
58 key,
59 modified_key,
60 physical_key,
61 location,
62 modifiers,
63 text,
64 repeat,
65 }) => Some(Message::KeyPressed(
66 KeyEventData {
67 key,
68 modified_key,
69 physical_key,
70 location,
71 modifiers,
72 text: text.map(|s| s.to_string()),
73 repeat,
74 captured,
75 },
76 window,
77 )),
78 iced::Event::Keyboard(iced::keyboard::Event::KeyReleased {
79 key,
80 modified_key,
81 physical_key,
82 location,
83 modifiers,
84 }) => Some(Message::KeyReleased(
85 KeyEventData {
86 key,
87 modified_key,
88 physical_key,
89 location,
90 modifiers,
91 text: None,
92 repeat: false,
93 captured,
94 },
95 window,
96 )),
97 iced::Event::Keyboard(iced::keyboard::Event::ModifiersChanged(mods)) => {
98 Some(Message::ModifiersChanged(mods, window, captured))
99 }
100 iced::Event::Mouse(iced::mouse::Event::CursorMoved { position }) => {
102 Some(Message::CursorMoved(position, window, captured))
103 }
104 iced::Event::Mouse(iced::mouse::Event::CursorEntered) => {
105 Some(Message::CursorEntered(window, captured))
106 }
107 iced::Event::Mouse(iced::mouse::Event::CursorLeft) => {
108 Some(Message::CursorLeft(window, captured))
109 }
110 iced::Event::Mouse(iced::mouse::Event::ButtonPressed(button)) => {
111 Some(Message::MouseButtonPressed(button, window, captured))
112 }
113 iced::Event::Mouse(iced::mouse::Event::ButtonReleased(button)) => {
114 Some(Message::MouseButtonReleased(button, window, captured))
115 }
116 iced::Event::Mouse(iced::mouse::Event::WheelScrolled { delta }) => {
117 Some(Message::WheelScrolled(delta, window, captured))
118 }
119 iced::Event::Touch(iced::touch::Event::FingerPressed { id, position }) => {
121 Some(Message::FingerPressed(id, position, window, captured))
122 }
123 iced::Event::Touch(iced::touch::Event::FingerMoved { id, position }) => {
124 Some(Message::FingerMoved(id, position, window, captured))
125 }
126 iced::Event::Touch(iced::touch::Event::FingerLifted { id, position }) => {
127 Some(Message::FingerLifted(id, position, window, captured))
128 }
129 iced::Event::Touch(iced::touch::Event::FingerLost { id, position }) => {
130 Some(Message::FingerLost(id, position, window, captured))
131 }
132 iced::Event::InputMethod(iced::advanced::input_method::Event::Opened) => {
134 Some(Message::ImeOpened(window, captured))
135 }
136 iced::Event::InputMethod(iced::advanced::input_method::Event::Preedit(
137 text,
138 cursor,
139 )) => Some(Message::ImePreedit(text, cursor, window, captured)),
140 iced::Event::InputMethod(iced::advanced::input_method::Event::Commit(text)) => {
141 Some(Message::ImeCommit(text, window, captured))
142 }
143 iced::Event::InputMethod(iced::advanced::input_method::Event::Closed) => {
144 Some(Message::ImeClosed(window, captured))
145 }
146 _ => None,
148 }
149 }));
150 }
151
152 Subscription::batch(subs)
153 }
154
155 fn keyboard_subscriptions(&self, has_on_event: bool, subs: &mut Vec<Subscription<Message>>) {
156 if !has_on_event && self.has_host_or_widget_subscription(SUB_KEY_PRESS) {
160 subs.push(event::listen_with(|evt, status, window| {
161 if let iced::Event::Keyboard(iced::keyboard::Event::KeyPressed {
162 key,
163 modified_key,
164 physical_key,
165 location,
166 modifiers,
167 text,
168 repeat,
169 }) = evt
170 {
171 Some(Message::KeyPressed(
172 KeyEventData {
173 key,
174 modified_key,
175 physical_key,
176 location,
177 modifiers,
178 text: text.map(|s| s.to_string()),
179 repeat,
180 captured: status == iced::event::Status::Captured,
181 },
182 window,
183 ))
184 } else {
185 None
186 }
187 }));
188 }
189
190 if !has_on_event && self.has_host_or_widget_subscription(SUB_KEY_RELEASE) {
191 subs.push(event::listen_with(|evt, status, window| {
192 if let iced::Event::Keyboard(iced::keyboard::Event::KeyReleased {
193 key,
194 modified_key,
195 physical_key,
196 location,
197 modifiers,
198 }) = evt
199 {
200 Some(Message::KeyReleased(
201 KeyEventData {
202 key,
203 modified_key,
204 physical_key,
205 location,
206 modifiers,
207 text: None,
208 repeat: false,
209 captured: status == iced::event::Status::Captured,
210 },
211 window,
212 ))
213 } else {
214 None
215 }
216 }));
217 }
218
219 if !has_on_event && self.has_host_or_widget_subscription(SUB_MODIFIERS_CHANGED) {
220 subs.push(event::listen_with(|evt, status, window| {
221 if let iced::Event::Keyboard(iced::keyboard::Event::ModifiersChanged(mods)) = evt {
222 Some(Message::ModifiersChanged(
223 mods,
224 window,
225 status == iced::event::Status::Captured,
226 ))
227 } else {
228 None
229 }
230 }));
231 }
232 }
233
234 fn mouse_subscriptions(&self, has_on_event: bool, subs: &mut Vec<Subscription<Message>>) {
235 if !has_on_event && self.has_host_or_widget_subscription(SUB_POINTER_MOVE) {
236 subs.push(event::listen_with(|evt, status, window| {
237 let captured = status == iced::event::Status::Captured;
238 match evt {
239 iced::Event::Mouse(iced::mouse::Event::CursorMoved { position }) => {
240 Some(Message::CursorMoved(position, window, captured))
241 }
242 iced::Event::Mouse(iced::mouse::Event::CursorEntered) => {
243 Some(Message::CursorEntered(window, captured))
244 }
245 iced::Event::Mouse(iced::mouse::Event::CursorLeft) => {
246 Some(Message::CursorLeft(window, captured))
247 }
248 _ => None,
249 }
250 }));
251 }
252
253 if !has_on_event && self.has_host_or_widget_subscription(SUB_POINTER_BUTTON) {
254 subs.push(event::listen_with(|evt, status, window| {
255 let captured = status == iced::event::Status::Captured;
256 match evt {
257 iced::Event::Mouse(iced::mouse::Event::ButtonPressed(button)) => {
258 Some(Message::MouseButtonPressed(button, window, captured))
259 }
260 iced::Event::Mouse(iced::mouse::Event::ButtonReleased(button)) => {
261 Some(Message::MouseButtonReleased(button, window, captured))
262 }
263 _ => None,
264 }
265 }));
266 }
267
268 if !has_on_event && self.has_host_or_widget_subscription(SUB_POINTER_SCROLL) {
269 subs.push(event::listen_with(|evt, status, window| {
270 if let iced::Event::Mouse(iced::mouse::Event::WheelScrolled { delta }) = evt {
271 Some(Message::WheelScrolled(
272 delta,
273 window,
274 status == iced::event::Status::Captured,
275 ))
276 } else {
277 None
278 }
279 }));
280 }
281 }
282
283 fn touch_subscriptions(&self, has_on_event: bool, subs: &mut Vec<Subscription<Message>>) {
284 if !has_on_event && self.has_host_or_widget_subscription(SUB_POINTER_TOUCH) {
285 subs.push(event::listen_with(|evt, status, window| {
286 let captured = status == iced::event::Status::Captured;
287 match evt {
288 iced::Event::Touch(iced::touch::Event::FingerPressed { id, position }) => {
289 Some(Message::FingerPressed(id, position, window, captured))
290 }
291 iced::Event::Touch(iced::touch::Event::FingerMoved { id, position }) => {
292 Some(Message::FingerMoved(id, position, window, captured))
293 }
294 iced::Event::Touch(iced::touch::Event::FingerLifted { id, position }) => {
295 Some(Message::FingerLifted(id, position, window, captured))
296 }
297 iced::Event::Touch(iced::touch::Event::FingerLost { id, position }) => {
298 Some(Message::FingerLost(id, position, window, captured))
299 }
300 _ => None,
301 }
302 }));
303 }
304 }
305
306 fn ime_subscriptions(&self, has_on_event: bool, subs: &mut Vec<Subscription<Message>>) {
307 if !has_on_event && self.has_host_or_widget_subscription(SUB_IME) {
308 subs.push(event::listen_with(|evt, status, window| {
309 let captured = status == iced::event::Status::Captured;
310 match evt {
311 iced::Event::InputMethod(iced::advanced::input_method::Event::Opened) => {
312 Some(Message::ImeOpened(window, captured))
313 }
314 iced::Event::InputMethod(iced::advanced::input_method::Event::Preedit(
315 text,
316 cursor,
317 )) => Some(Message::ImePreedit(text, cursor, window, captured)),
318 iced::Event::InputMethod(iced::advanced::input_method::Event::Commit(text)) => {
319 Some(Message::ImeCommit(text, window, captured))
320 }
321 iced::Event::InputMethod(iced::advanced::input_method::Event::Closed) => {
322 Some(Message::ImeClosed(window, captured))
323 }
324 _ => None,
325 }
326 }));
327 }
328 }
329
330 fn window_subscriptions(&self, subs: &mut Vec<Subscription<Message>>) {
331 if self.has_any_subscription(&[
332 SUB_WINDOW_EVENT,
333 SUB_WINDOW_OPEN,
334 SUB_WINDOW_MOVE,
335 SUB_WINDOW_RESIZE,
336 SUB_WINDOW_FOCUS,
337 SUB_WINDOW_UNFOCUS,
338 SUB_FILE_DROP,
339 ]) {
340 subs.push(window::events().map(|(id, evt)| Message::WindowEvent(id, evt)));
341 }
342
343 if self.has_host_or_widget_subscription(SUB_WINDOW_CLOSE) {
344 subs.push(window::close_requests().map(Message::WindowCloseRequested));
345 }
346
347 if self.has_host_or_widget_subscription(SUB_ANIMATION_FRAME)
353 || self.transition_manager.has_active()
354 {
355 subs.push(window::frames().map(Message::AnimationFrame));
356 }
357 }
358
359 fn system_subscriptions(&self, subs: &mut Vec<Subscription<Message>>) {
360 if self.theme_follows_system
362 || self.windows.any_theme_follows_system()
363 || self.has_host_or_widget_subscription(SUB_THEME_CHANGE)
364 {
365 subs.push(system::theme_changes().map(Message::ThemeChanged));
366 }
367 }
368
369 fn has_any_subscription(&self, keys: &[&str]) -> bool {
372 keys.iter().any(|k| self.has_host_or_widget_subscription(k))
373 }
374}