Introduce ViewContext::on_window_should_close
This is a new callback that can be used to interrupt closing the window when the user has unsaved changes.
This commit is contained in:
@@ -81,6 +81,10 @@ unsafe fn build_classes() {
|
||||
sel!(windowDidResignKey:),
|
||||
window_did_change_key_status as extern "C" fn(&Object, Sel, id),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(windowShouldClose:),
|
||||
window_should_close as extern "C" fn(&Object, Sel, id) -> BOOL,
|
||||
);
|
||||
decl.add_method(sel!(close), close_window as extern "C" fn(&Object, Sel));
|
||||
decl.register()
|
||||
};
|
||||
@@ -167,6 +171,7 @@ struct WindowState {
|
||||
event_callback: Option<Box<dyn FnMut(Event) -> bool>>,
|
||||
activate_callback: Option<Box<dyn FnMut(bool)>>,
|
||||
resize_callback: Option<Box<dyn FnMut()>>,
|
||||
should_close_callback: Option<Box<dyn FnMut() -> bool>>,
|
||||
close_callback: Option<Box<dyn FnOnce()>>,
|
||||
synthetic_drag_counter: usize,
|
||||
executor: Rc<executor::Foreground>,
|
||||
@@ -242,6 +247,7 @@ impl Window {
|
||||
native_window,
|
||||
event_callback: None,
|
||||
resize_callback: None,
|
||||
should_close_callback: None,
|
||||
close_callback: None,
|
||||
activate_callback: None,
|
||||
synthetic_drag_counter: 0,
|
||||
@@ -339,6 +345,10 @@ impl platform::Window for Window {
|
||||
self.0.as_ref().borrow_mut().resize_callback = Some(callback);
|
||||
}
|
||||
|
||||
fn on_should_close(&mut self, callback: Box<dyn FnMut() -> bool>) {
|
||||
self.0.as_ref().borrow_mut().should_close_callback = Some(callback);
|
||||
}
|
||||
|
||||
fn on_close(&mut self, callback: Box<dyn FnOnce()>) {
|
||||
self.0.as_ref().borrow_mut().close_callback = Some(callback);
|
||||
}
|
||||
@@ -674,6 +684,19 @@ extern "C" fn window_did_change_key_status(this: &Object, selector: Sel, _: id)
|
||||
.detach();
|
||||
}
|
||||
|
||||
extern "C" fn window_should_close(this: &Object, _: Sel, _: id) -> BOOL {
|
||||
let window_state = unsafe { get_window_state(this) };
|
||||
let mut window_state_borrow = window_state.as_ref().borrow_mut();
|
||||
if let Some(mut callback) = window_state_borrow.should_close_callback.take() {
|
||||
drop(window_state_borrow);
|
||||
let should_close = callback();
|
||||
window_state.borrow_mut().should_close_callback = Some(callback);
|
||||
should_close as BOOL
|
||||
} else {
|
||||
YES
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn close_window(this: &Object, _: Sel) {
|
||||
unsafe {
|
||||
let close_callback = {
|
||||
|
||||
@@ -37,6 +37,7 @@ pub struct Window {
|
||||
event_handlers: Vec<Box<dyn FnMut(super::Event) -> bool>>,
|
||||
resize_handlers: Vec<Box<dyn FnMut()>>,
|
||||
close_handlers: Vec<Box<dyn FnOnce()>>,
|
||||
should_close_handler: Option<Box<dyn FnMut() -> bool>>,
|
||||
pub(crate) title: Option<String>,
|
||||
pub(crate) edited: bool,
|
||||
pub(crate) pending_prompts: RefCell<VecDeque<oneshot::Sender<usize>>>,
|
||||
@@ -186,9 +187,10 @@ impl Window {
|
||||
fn new(size: Vector2F) -> Self {
|
||||
Self {
|
||||
size,
|
||||
event_handlers: Vec::new(),
|
||||
resize_handlers: Vec::new(),
|
||||
close_handlers: Vec::new(),
|
||||
event_handlers: Default::default(),
|
||||
resize_handlers: Default::default(),
|
||||
close_handlers: Default::default(),
|
||||
should_close_handler: Default::default(),
|
||||
scale_factor: 1.0,
|
||||
current_scene: None,
|
||||
title: None,
|
||||
@@ -264,6 +266,10 @@ impl super::Window for Window {
|
||||
fn set_edited(&mut self, edited: bool) {
|
||||
self.edited = edited;
|
||||
}
|
||||
|
||||
fn on_should_close(&mut self, callback: Box<dyn FnMut() -> bool>) {
|
||||
self.should_close_handler = Some(callback);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn platform() -> Platform {
|
||||
|
||||
Reference in New Issue
Block a user