diff options
Diffstat (limited to 'examples/multi_window')
| -rw-r--r-- | examples/multi_window/Cargo.toml | 9 | ||||
| -rw-r--r-- | examples/multi_window/src/main.rs | 215 | 
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() +    } +} | 
