From 685a0543cdf9f1aed360736b9d0601dbcdef29c5 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Thu, 7 Dec 2023 16:46:33 -0500 Subject: [PATCH] chore: multi-window example --- examples/multi-window/Cargo.toml | 9 ++ examples/multi-window/src/main.rs | 9 ++ examples/multi-window/src/window.rs | 159 ++++++++++++++++++++++++++++ src/app/cosmic.rs | 4 +- 4 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 examples/multi-window/Cargo.toml create mode 100644 examples/multi-window/src/main.rs create mode 100644 examples/multi-window/src/window.rs diff --git a/examples/multi-window/Cargo.toml b/examples/multi-window/Cargo.toml new file mode 100644 index 00000000..97177ce3 --- /dev/null +++ b/examples/multi-window/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "multi-window" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "multi-window"] } diff --git a/examples/multi-window/src/main.rs b/examples/multi-window/src/main.rs new file mode 100644 index 00000000..0a5fc03f --- /dev/null +++ b/examples/multi-window/src/main.rs @@ -0,0 +1,9 @@ +// Copyright 2022 System76 +// SPDX-License-Identifier: MPL-2.0 + +mod window; +pub use window::*; + +pub fn main() -> cosmic::iced::Result { + cosmic::app::run::(Default::default(), ()) +} diff --git a/examples/multi-window/src/window.rs b/examples/multi-window/src/window.rs new file mode 100644 index 00000000..54052a15 --- /dev/null +++ b/examples/multi-window/src/window.rs @@ -0,0 +1,159 @@ +use std::collections::HashMap; + +use cosmic::{ + app::Core, + iced::{self, event, window}, + iced_core::{id, Alignment, Length, Point}, + iced_widget::{column, scrollable, text, text_input}, + widget::{button, container}, + Command, +}; + +#[derive(Debug, Clone, PartialEq)] +pub enum Message { + CloseWindow(window::Id), + WindowOpened(window::Id, Option), + WindowClosed(window::Id), + NewWindow, + Input(id::Id, String), +} +pub struct MultiWindow { + core: Core, + windows: HashMap, +} + +pub struct Window { + input_id: id::Id, + input_value: String, +} + +impl cosmic::Application for MultiWindow { + type Executor = cosmic::executor::Default; + type Flags = (); + type Message = Message; + + const APP_ID: &'static str = "org.cosmic.MultiWindowDemo"; + + fn core(&self) -> &Core { + &self.core + } + + fn core_mut(&mut self) -> &mut Core { + &mut self.core + } + + fn init(core: Core, _input: Self::Flags) -> (Self, cosmic::app::Command) { + let windows = MultiWindow { + windows: HashMap::from([( + window::Id::MAIN, + Window { + input_id: id::Id::new("main"), + input_value: String::new(), + }, + )]), + core, + }; + + (windows, cosmic::app::Command::none()) + } + + fn subscription(&self) -> cosmic::iced_futures::Subscription { + 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 + } + }) + } + + fn update( + &mut self, + message: Self::Message, + ) -> iced::Command> { + match message { + Message::CloseWindow(id) => window::close(id), + Message::WindowClosed(id) => { + self.windows.remove(&id); + Command::none() + } + Message::WindowOpened(id, ..) => { + 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: Default::default(), + exit_on_close_request: count % 2 == 0, + ..Default::default() + }); + + self.windows.insert( + id, + Window { + input_id: id::Id::new(format!("window_{}", count)), + input_value: String::new(), + }, + ); + + spawn_window + } + Message::Input(id, value) => { + if let Some(w) = self.windows.get_mut(&window::Id::MAIN) { + if id == w.input_id { + w.input_value = value; + } + } + + Command::none() + } + } + } + + fn view_window(&self, id: window::Id) -> cosmic::prelude::Element { + let w = self.windows.get(&id).unwrap(); + + let input_id = w.input_id.clone(); + let input = text_input("something", &w.input_value) + .on_input(move |msg| Message::Input(input_id.clone(), msg)) + .id(w.input_id.clone()); + + let new_window_button = button(text("New Window")).on_press(Message::NewWindow); + + let content = scrollable( + column![input, new_window_button] + .spacing(50) + .width(Length::Fill) + .align_items(Alignment::Center), + ); + + container(container(content).width(200).center_x()) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() + } + + fn style( + &self, + ) -> Option<::Style> { + Some(Default::default()) + } + + fn view(&self) -> cosmic::prelude::Element { + self.view_window(window::Id::MAIN) + } +} diff --git a/src/app/cosmic.rs b/src/app/cosmic.rs index 46f5c240..065b3fcf 100644 --- a/src/app/cosmic.rs +++ b/src/app/cosmic.rs @@ -114,7 +114,7 @@ where } #[cfg(feature = "multi-window")] - fn scale_factor(&self, id: window::Id) -> f64 { + fn scale_factor(&self, _id: window::Id) -> f64 { f64::from(self.app.core().scale_factor()) } @@ -203,7 +203,7 @@ where } #[cfg(feature = "multi-window")] - fn theme(&self, id: window::Id) -> Self::Theme { + fn theme(&self, _id: window::Id) -> Self::Theme { crate::theme::active() }