use iced::multi_window::{self, Application}; use iced::widget::{button, column, container, scrollable, text, text_input}; use iced::{ executor, window, Alignment, Command, Element, Length, Settings, Theme, }; use std::collections::HashMap; fn main() -> iced::Result { Example::run(Settings::default()) } #[derive(Default)] struct Example { windows_count: usize, windows: HashMap, } struct Window { id: window::Id, title: String, scale_input: String, current_scale: f64, } #[derive(Debug, Clone)] enum Message { ScaleInputChanged(window::Id, String), ScaleChanged(window::Id, String), TitleChanged(window::Id, String), CloseWindow(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) { ( Example { windows_count: 0, windows: HashMap::from([( window::Id::MAIN, Window::new(window::Id::MAIN), )]), }, 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 { match message { Message::ScaleInputChanged(id, scale) => { let window = self.windows.get_mut(&id).expect("Window not found!"); window.scale_input = scale; } Message::ScaleChanged(id, scale) => { let window = self.windows.get_mut(&id).expect("Window not found!"); window.current_scale = scale .parse::() .unwrap_or(window.current_scale) .clamp(0.5, 5.0); } Message::TitleChanged(id, title) => { let window = self.windows.get_mut(&id).expect("Window not found."); window.title = title; } Message::CloseWindow(id) => { return window::close(id); } Message::NewWindow => { self.windows_count += 1; let id = window::Id::new(self.windows_count); self.windows.insert(id, Window::new(id)); return window::spawn(id, window::Settings::default()); } } Command::none() } fn view(&self, window: window::Id) -> Element { let window = self .windows .get(&window) .map(|window| window.view()) .unwrap(); container(window) .width(Length::Fill) .height(Length::Fill) .center_x() .center_y() .into() } fn scale_factor(&self, window: window::Id) -> f64 { self.windows .get(&window) .map(|window| window.current_scale) .unwrap_or(1.0) } fn close_requested(&self, window: window::Id) -> Self::Message { Message::CloseWindow(window) } } impl Window { fn new(id: window::Id) -> Self { Self { id, title: "Window".to_string(), scale_input: "1.0".to_string(), current_scale: 1.0, } } fn view(&self) -> Element { window_view(self.id, &self.scale_input, &self.title) } } fn window_view<'a>( id: window::Id, scale_input: &'a str, title: &'a str, ) -> Element<'a, Message> { let scale_input = column![ text("Window scale factor:"), text_input("Window Scale", scale_input, move |msg| { Message::ScaleInputChanged(id, msg) }) .on_submit(Message::ScaleChanged(id, scale_input.to_string())) ]; let title_input = column![ text("Window title:"), text_input("Window Title", title, move |msg| { Message::TitleChanged(id, msg) }) ]; 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() }