libcosmic/examples/multi-window/src/window.rs

162 lines
4.8 KiB
Rust
Raw Normal View History

2023-12-07 16:46:33 -05:00
use std::collections::HashMap;
use cosmic::{
2023-12-07 17:51:20 -05:00
app::Core,
2023-12-07 16:46:33 -05:00
iced::{self, event, window},
iced_core::{id, Alignment, Length, Point},
2023-12-07 17:51:20 -05:00
iced_widget::{column, container, scrollable, text, text_input},
widget::{button, header_bar},
ApplicationExt, Command,
2023-12-07 16:46:33 -05:00
};
#[derive(Debug, Clone, PartialEq)]
pub enum Message {
CloseWindow(window::Id),
WindowOpened(window::Id, Option<Point>),
WindowClosed(window::Id),
NewWindow,
Input(id::Id, String),
}
pub struct MultiWindow {
core: Core,
windows: HashMap<window::Id, Window>,
}
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<Self::Message>) {
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<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
}
})
}
fn update(
&mut self,
message: Self::Message,
) -> iced::Command<cosmic::app::Message<Self::Message>> {
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,
decorations: false,
2023-12-07 16:46:33 -05:00
..Default::default()
});
self.windows.insert(
id,
Window {
input_id: id::Id::new(format!("window_{}", count)),
input_value: String::new(),
},
);
_ = self.set_window_title(format!("window_{}", count), id);
2023-12-07 16:46:33 -05:00
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<Self::Message> {
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);
2023-12-07 17:51:20 -05:00
let content = scrollable(
column![input, new_window_button]
.spacing(50)
.width(Length::Fill)
.align_items(Alignment::Center),
);
2023-12-07 16:46:33 -05:00
let window_content = container(container(content).width(200).center_x())
.style(cosmic::style::Container::Background)
2023-12-07 16:46:33 -05:00
.width(Length::Fill)
.height(Length::Fill)
.center_x()
.center_y();
if id == window::Id::MAIN {
window_content.into()
} else {
column![header_bar().window_id(id), window_content].into()
}
2023-12-07 16:46:33 -05:00
}
fn view(&self) -> cosmic::prelude::Element<Self::Message> {
self.view_window(window::Id::MAIN)
}
}