diff options
author | 2024-06-14 03:04:51 +0200 | |
---|---|---|
committer | 2024-06-14 03:05:58 +0200 | |
commit | 88b938440285fdb44c9e5bd572fda5c0f94996ca (patch) | |
tree | 76c645af8cf454a8611fe66f75f0a4931dd99383 /examples/multi_window | |
parent | b21e4567dc32250c90d2ea9c78080cd8bcb66368 (diff) | |
download | iced-88b938440285fdb44c9e5bd572fda5c0f94996ca.tar.gz iced-88b938440285fdb44c9e5bd572fda5c0f94996ca.tar.bz2 iced-88b938440285fdb44c9e5bd572fda5c0f94996ca.zip |
Use `Task` chaining to simplify `multi_window` example
Diffstat (limited to 'examples/multi_window')
-rw-r--r-- | examples/multi_window/src/main.rs | 155 |
1 files changed, 72 insertions, 83 deletions
diff --git a/examples/multi_window/src/main.rs b/examples/multi_window/src/main.rs index e15f8759..fa9adb87 100644 --- a/examples/multi_window/src/main.rs +++ b/examples/multi_window/src/main.rs @@ -1,16 +1,15 @@ -use iced::event; use iced::executor; use iced::multi_window::{self, Application}; use iced::widget::{ - button, center, column, container, scrollable, text, text_input, + button, center, column, container, horizontal_space, scrollable, text, + text_input, }; use iced::window; use iced::{ - Alignment, Element, Length, Point, Settings, Subscription, Task, Theme, - Vector, + Alignment, Element, Length, Settings, Subscription, Task, Theme, Vector, }; -use std::collections::HashMap; +use std::collections::BTreeMap; fn main() -> iced::Result { Example::run(Settings::default()) @@ -18,8 +17,7 @@ fn main() -> iced::Result { #[derive(Default)] struct Example { - windows: HashMap<window::Id, Window>, - next_window_pos: window::Position, + windows: BTreeMap<window::Id, Window>, } #[derive(Debug)] @@ -33,13 +31,12 @@ struct Window { #[derive(Debug, Clone)] enum Message { + OpenWindow, + WindowOpened(window::Id), + WindowClosed(window::Id), ScaleInputChanged(window::Id, String), ScaleChanged(window::Id, String), TitleChanged(window::Id, String), - CloseWindow(window::Id), - WindowOpened(window::Id, Option<Point>), - WindowClosed(window::Id), - NewWindow, } impl multi_window::Application for Example { @@ -51,8 +48,7 @@ impl multi_window::Application for Example { fn new(_flags: ()) -> (Self, Task<Message>) { ( Example { - windows: HashMap::from([(window::Id::MAIN, Window::new(1))]), - next_window_pos: window::Position::Default, + windows: BTreeMap::from([(window::Id::MAIN, Window::new(1))]), }, Task::none(), ) @@ -62,79 +58,89 @@ impl multi_window::Application for Example { self.windows .get(&window) .map(|window| window.title.clone()) - .unwrap_or("Example".to_string()) + .unwrap_or_default() } fn update(&mut self, message: Message) -> Task<Message> { match message { - Message::ScaleInputChanged(id, scale) => { - let window = - self.windows.get_mut(&id).expect("Window not found!"); - window.scale_input = scale; - - Task::none() - } - Message::ScaleChanged(id, scale) => { - let window = - self.windows.get_mut(&id).expect("Window not found!"); - - window.current_scale = scale - .parse::<f64>() - .unwrap_or(window.current_scale) - .clamp(0.5, 5.0); - - Task::none() + Message::OpenWindow => { + let Some(last_window) = self.windows.keys().last() else { + return Task::none(); + }; + + window::fetch_position(*last_window) + .then(|last_position| { + let position = last_position.map_or( + window::Position::Default, + |last_position| { + window::Position::Specific( + last_position + Vector::new(20.0, 20.0), + ) + }, + ); + + window::open(window::Settings { + position, + ..window::Settings::default() + }) + }) + .map(Message::WindowOpened) } - Message::TitleChanged(id, title) => { - let window = - self.windows.get_mut(&id).expect("Window not found."); - - window.title = title; + Message::WindowOpened(id) => { + self.windows.insert(id, Window::new(self.windows.len() + 1)); - Task::none() + if let Some(window) = self.windows.get(&id) { + text_input::focus(window.input_id.clone()) + } else { + Task::none() + } } - Message::CloseWindow(id) => window::close(id), Message::WindowClosed(id) => { self.windows.remove(&id); + Task::none() } - Message::WindowOpened(id, position) => { - if let Some(position) = position { - self.next_window_pos = window::Position::Specific( - position + Vector::new(20.0, 20.0), - ); + Message::ScaleInputChanged(id, scale) => { + if let Some(window) = self.windows.get_mut(&id) { + window.scale_input = scale; } - if let Some(window) = self.windows.get(&id) { - text_input::focus(window.input_id.clone()) - } else { - Task::none() - } + Task::none() } - Message::NewWindow => { - let count = self.windows.len() + 1; - - let (id, spawn_window) = window::open(window::Settings { - position: self.next_window_pos, - exit_on_close_request: count % 2 == 0, - ..Default::default() - }); + Message::ScaleChanged(id, scale) => { + if let Some(window) = self.windows.get_mut(&id) { + window.current_scale = scale + .parse::<f64>() + .unwrap_or(window.current_scale) + .clamp(0.5, 5.0); + } - self.windows.insert(id, Window::new(count)); + Task::none() + } + Message::TitleChanged(id, title) => { + if let Some(window) = self.windows.get_mut(&id) { + window.title = title; + } - spawn_window + Task::none() } } } - fn view(&self, window: window::Id) -> Element<Message> { - let content = self.windows.get(&window).unwrap().view(window); - - center(content).into() + fn view(&self, window_id: window::Id) -> Element<Message> { + if let Some(window) = self.windows.get(&window_id) { + center(window.view(window_id)).into() + } else { + horizontal_space().into() + } } - fn theme(&self, window: window::Id) -> Self::Theme { - self.windows.get(&window).unwrap().theme.clone() + fn theme(&self, window: window::Id) -> Theme { + if let Some(window) = self.windows.get(&window) { + window.theme.clone() + } else { + Theme::default() + } } fn scale_factor(&self, window: window::Id) -> f64 { @@ -145,24 +151,7 @@ impl multi_window::Application for Example { } fn subscription(&self) -> Subscription<Self::Message> { - event::listen_with(|event, _, window| { - if let iced::Event::Window(window_event) = event { - match window_event { - window::Event::CloseRequested => { - Some(Message::CloseWindow(window)) - } - window::Event::Opened { position, .. } => { - Some(Message::WindowOpened(window, position)) - } - window::Event::Closed => { - Some(Message::WindowClosed(window)) - } - _ => None, - } - } else { - None - } - }) + window::closings().map(Message::WindowClosed) } } @@ -200,7 +189,7 @@ impl Window { ]; let new_window_button = - button(text("New Window")).on_press(Message::NewWindow); + button(text("New Window")).on_press(Message::OpenWindow); let content = scrollable( column![scale_input, title_input, new_window_button] |