summaryrefslogtreecommitdiffstats
path: root/examples/multi_window
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-06-14 03:04:51 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-06-14 03:05:58 +0200
commit88b938440285fdb44c9e5bd572fda5c0f94996ca (patch)
tree76c645af8cf454a8611fe66f75f0a4931dd99383 /examples/multi_window
parentb21e4567dc32250c90d2ea9c78080cd8bcb66368 (diff)
downloadiced-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.rs155
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]