Allow closing the window from user code

This commit is contained in:
Richard 2022-07-26 16:46:12 -03:00 committed by bungoboingo
parent 3d901d5f1f
commit 35331d0a41
4 changed files with 76 additions and 23 deletions

View file

@ -50,6 +50,7 @@ enum WindowMessage {
Close(pane_grid::Pane), Close(pane_grid::Pane),
CloseFocused, CloseFocused,
SelectedWindow(pane_grid::Pane, SelectableWindow), SelectedWindow(pane_grid::Pane, SelectableWindow),
CloseWindow,
} }
impl Application for Example { impl Application for Example {
@ -128,6 +129,9 @@ impl Application for Example {
let window = self.windows.get_mut(&id).unwrap(); let window = self.windows.get_mut(&id).unwrap();
window.focus = Some(pane); window.focus = Some(pane);
} }
WindowMessage::CloseWindow => {
let _ = self.windows.remove(&id);
}
WindowMessage::Resized(pane_grid::ResizeEvent { split, ratio }) => { WindowMessage::Resized(pane_grid::ResizeEvent { split, ratio }) => {
let window = self.windows.get_mut(&id).unwrap(); let window = self.windows.get_mut(&id).unwrap();
window.panes.resize(&split, ratio); window.panes.resize(&split, ratio);
@ -145,8 +149,6 @@ impl Application for Example {
if let Some((pane, _)) = result { if let Some((pane, _)) = result {
window.focus = Some(pane); window.focus = Some(pane);
} }
self.panes_created += 1;
} }
} }
WindowMessage::ToggleMoving(pane) => { WindowMessage::ToggleMoving(pane) => {
@ -260,6 +262,9 @@ impl Application for Example {
WindowMessage::TitleChanged, WindowMessage::TitleChanged,
), ),
button(text("Apply")).style(theme::Button::Primary), button(text("Apply")).style(theme::Button::Primary),
button(text("Close"))
.on_press(WindowMessage::CloseWindow)
.style(theme::Button::Destructive),
] ]
.spacing(5) .spacing(5)
.align_items(Alignment::Center); .align_items(Alignment::Center);

View file

@ -1,7 +1,7 @@
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
/// TODO(derezzedex) /// TODO(derezzedex)
pub struct Id(u64); pub struct Id(u64);

View file

@ -39,6 +39,8 @@ pub enum Event<Message> {
// (maybe we should also allow users to listen/react to those internal messages?) // (maybe we should also allow users to listen/react to those internal messages?)
NewWindow(window::Id, settings::Window), NewWindow(window::Id, settings::Window),
/// TODO(derezzedex) /// TODO(derezzedex)
CloseWindow(window::Id),
/// TODO(derezzedex)
WindowCreated(window::Id, winit::window::Window), WindowCreated(window::Id, winit::window::Window),
} }
@ -549,6 +551,27 @@ async fn run_instance<A, E, C>(
let _ = window_ids.insert(window.id(), id); let _ = window_ids.insert(window.id(), id);
let _ = windows.insert(id, window); let _ = windows.insert(id, window);
} }
Event::CloseWindow(id) => {
// TODO(derezzedex): log errors
if let Some(window) = windows.get(&id) {
if window_ids.remove(&window.id()).is_none() {
println!("Failed to remove from `window_ids`!");
}
}
if states.remove(&id).is_none() {
println!("Failed to remove from `states`!")
}
if interfaces.remove(&id).is_none() {
println!("Failed to remove from `interfaces`!");
}
if windows.remove(&id).is_none() {
println!("Failed to remove from `windows`!")
}
if windows.is_empty() {
break 'main;
}
}
Event::NewWindow(_, _) => unreachable!(), Event::NewWindow(_, _) => unreachable!(),
}, },
event::Event::RedrawRequested(id) => { event::Event::RedrawRequested(id) => {
@ -651,29 +674,43 @@ async fn run_instance<A, E, C>(
window_id, window_id,
} => { } => {
// dbg!(window_id); // dbg!(window_id);
let window = window_ids if let Some(window) =
.get(&window_id) window_ids.get(&window_id).and_then(|id| windows.get(id))
.and_then(|id| windows.get(id))
.unwrap();
let window_state = window_ids
.get(&window_id)
.and_then(|id| states.get_mut(id))
.unwrap();
if requests_exit(&window_event, window_state.state.modifiers())
&& exit_on_close_request
{ {
break; if let Some(window_state) = window_ids
} .get(&window_id)
.and_then(|id| states.get_mut(id))
{
if requests_exit(
&window_event,
window_state.state.modifiers(),
) && exit_on_close_request
{
break;
}
window_state.state.update(window, &window_event, &mut debug); window_state.state.update(
window,
&window_event,
&mut debug,
);
if let Some(event) = conversion::window_event( if let Some(event) = conversion::window_event(
&window_event, &window_event,
window_state.state.scale_factor(), window_state.state.scale_factor(),
window_state.state.modifiers(), window_state.state.modifiers(),
) { ) {
events.push((window_ids.get(&window_id).cloned(), event)); events.push((
window_ids.get(&window_id).cloned(),
event,
));
}
} else {
// TODO(derezzedex): log error
}
} else {
// TODO(derezzedex): log error
// println!("{:?}: {:?}", window_id, window_event);
} }
} }
_ => {} _ => {}

View file

@ -189,6 +189,17 @@ where
proxy: &EventLoopProxy<Event<A::Message>>, proxy: &EventLoopProxy<Event<A::Message>>,
) { ) {
let new_windows = application.windows(); let new_windows = application.windows();
// Check for windows to close
for window_id in windows.keys() {
if !new_windows.iter().any(|(id, _)| id == window_id) {
proxy
.send_event(Event::CloseWindow(*window_id))
.expect("Failed to send message");
}
}
// Check for windows to spawn
for (id, settings) in new_windows { for (id, settings) in new_windows {
if !windows.contains_key(&id) { if !windows.contains_key(&id) {
proxy proxy