summaryrefslogtreecommitdiffstats
path: root/examples/multi_window
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multi_window')
-rw-r--r--examples/multi_window/Cargo.toml9
-rw-r--r--examples/multi_window/src/main.rs215
2 files changed, 224 insertions, 0 deletions
diff --git a/examples/multi_window/Cargo.toml b/examples/multi_window/Cargo.toml
new file mode 100644
index 00000000..2e222dfb
--- /dev/null
+++ b/examples/multi_window/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "multi_window"
+version = "0.1.0"
+authors = ["Bingus <shankern@protonmail.com>"]
+edition = "2021"
+publish = false
+
+[dependencies]
+iced = { path = "../..", features = ["debug", "multi-window"] }
diff --git a/examples/multi_window/src/main.rs b/examples/multi_window/src/main.rs
new file mode 100644
index 00000000..5a5e70c1
--- /dev/null
+++ b/examples/multi_window/src/main.rs
@@ -0,0 +1,215 @@
+use iced::event;
+use iced::executor;
+use iced::multi_window::{self, Application};
+use iced::widget::{button, column, container, scrollable, text, text_input};
+use iced::window;
+use iced::{
+ Alignment, Command, Element, Length, Point, Settings, Subscription, Theme,
+ Vector,
+};
+
+use std::collections::HashMap;
+
+fn main() -> iced::Result {
+ Example::run(Settings::default())
+}
+
+#[derive(Default)]
+struct Example {
+ windows: HashMap<window::Id, Window>,
+ next_window_pos: window::Position,
+}
+
+#[derive(Debug)]
+struct Window {
+ title: String,
+ scale_input: String,
+ current_scale: f64,
+ theme: Theme,
+ input_id: iced::widget::text_input::Id,
+}
+
+#[derive(Debug, Clone)]
+enum Message {
+ 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 {
+ type Executor = executor::Default;
+ type Message = Message;
+ type Theme = Theme;
+ type Flags = ();
+
+ fn new(_flags: ()) -> (Self, Command<Message>) {
+ (
+ Example {
+ windows: HashMap::from([(window::Id::MAIN, Window::new(1))]),
+ next_window_pos: window::Position::Default,
+ },
+ Command::none(),
+ )
+ }
+
+ fn title(&self, window: window::Id) -> String {
+ self.windows
+ .get(&window)
+ .map(|window| window.title.clone())
+ .unwrap_or("Example".to_string())
+ }
+
+ fn update(&mut self, message: Message) -> Command<Message> {
+ match message {
+ Message::ScaleInputChanged(id, scale) => {
+ let window =
+ self.windows.get_mut(&id).expect("Window not found!");
+ window.scale_input = scale;
+
+ Command::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);
+
+ Command::none()
+ }
+ Message::TitleChanged(id, title) => {
+ let window =
+ self.windows.get_mut(&id).expect("Window not found.");
+
+ window.title = title;
+
+ Command::none()
+ }
+ Message::CloseWindow(id) => window::close(id),
+ Message::WindowClosed(id) => {
+ self.windows.remove(&id);
+ Command::none()
+ }
+ Message::WindowOpened(id, position) => {
+ if let Some(position) = position {
+ self.next_window_pos = window::Position::Specific(
+ position + Vector::new(20.0, 20.0),
+ );
+ }
+
+ if let Some(window) = self.windows.get(&id) {
+ text_input::focus(window.input_id.clone())
+ } else {
+ Command::none()
+ }
+ }
+ Message::NewWindow => {
+ let count = self.windows.len() + 1;
+
+ let (id, spawn_window) = window::spawn(window::Settings {
+ position: self.next_window_pos,
+ exit_on_close_request: count % 2 == 0,
+ ..Default::default()
+ });
+
+ self.windows.insert(id, Window::new(count));
+
+ spawn_window
+ }
+ }
+ }
+
+ fn view(&self, window: window::Id) -> Element<Message> {
+ let content = self.windows.get(&window).unwrap().view(window);
+
+ container(content)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .center_x()
+ .center_y()
+ .into()
+ }
+
+ fn theme(&self, window: window::Id) -> Self::Theme {
+ self.windows.get(&window).unwrap().theme.clone()
+ }
+
+ fn scale_factor(&self, window: window::Id) -> f64 {
+ self.windows
+ .get(&window)
+ .map(|window| window.current_scale)
+ .unwrap_or(1.0)
+ }
+
+ fn subscription(&self) -> Subscription<Self::Message> {
+ event::listen_with(|event, _| {
+ if let iced::Event::Window(id, window_event) = event {
+ match window_event {
+ window::Event::CloseRequested => {
+ Some(Message::CloseWindow(id))
+ }
+ window::Event::Opened { position, .. } => {
+ Some(Message::WindowOpened(id, position))
+ }
+ window::Event::Closed => Some(Message::WindowClosed(id)),
+ _ => None,
+ }
+ } else {
+ None
+ }
+ })
+ }
+}
+
+impl Window {
+ fn new(count: usize) -> Self {
+ Self {
+ title: format!("Window_{}", count),
+ scale_input: "1.0".to_string(),
+ current_scale: 1.0,
+ theme: if count % 2 == 0 {
+ Theme::Light
+ } else {
+ Theme::Dark
+ },
+ input_id: text_input::Id::unique(),
+ }
+ }
+
+ fn view(&self, id: window::Id) -> Element<Message> {
+ let scale_input = column![
+ text("Window scale factor:"),
+ text_input("Window Scale", &self.scale_input)
+ .on_input(move |msg| { Message::ScaleInputChanged(id, msg) })
+ .on_submit(Message::ScaleChanged(
+ id,
+ self.scale_input.to_string()
+ ))
+ ];
+
+ let title_input = column![
+ text("Window title:"),
+ text_input("Window Title", &self.title)
+ .on_input(move |msg| { Message::TitleChanged(id, msg) })
+ .id(self.input_id.clone())
+ ];
+
+ let new_window_button =
+ button(text("New Window")).on_press(Message::NewWindow);
+
+ let content = scrollable(
+ column![scale_input, title_input, new_window_button]
+ .spacing(50)
+ .width(Length::Fill)
+ .align_items(Alignment::Center),
+ );
+
+ container(content).width(200).center_x().into()
+ }
+}