* Move application delegate to its own file * Move window subclass to window.rs * Split view controller to separate file
103 lines
4 KiB
Rust
103 lines
4 KiB
Rust
use icrate::Foundation::{MainThreadMarker, NSObject, NSObjectProtocol};
|
|
use objc2::{declare_class, mutability, ClassType, DeclaredClass};
|
|
|
|
use super::app_state::{self, EventWrapper};
|
|
use super::uikit::{UIApplication, UIWindow};
|
|
use super::window::WinitUIWindow;
|
|
use crate::{
|
|
event::{Event, WindowEvent},
|
|
window::WindowId as RootWindowId,
|
|
};
|
|
|
|
declare_class!(
|
|
pub struct AppDelegate;
|
|
|
|
unsafe impl ClassType for AppDelegate {
|
|
type Super = NSObject;
|
|
type Mutability = mutability::InteriorMutable;
|
|
const NAME: &'static str = "WinitApplicationDelegate";
|
|
}
|
|
|
|
impl DeclaredClass for AppDelegate {}
|
|
|
|
// UIApplicationDelegate protocol
|
|
unsafe impl AppDelegate {
|
|
#[method(application:didFinishLaunchingWithOptions:)]
|
|
fn did_finish_launching(&self, _application: &UIApplication, _: *mut NSObject) -> bool {
|
|
app_state::did_finish_launching(MainThreadMarker::new().unwrap());
|
|
true
|
|
}
|
|
|
|
#[method(applicationDidBecomeActive:)]
|
|
fn did_become_active(&self, _application: &UIApplication) {
|
|
let mtm = MainThreadMarker::new().unwrap();
|
|
app_state::handle_nonuser_event(mtm, EventWrapper::StaticEvent(Event::Resumed))
|
|
}
|
|
|
|
#[method(applicationWillResignActive:)]
|
|
fn will_resign_active(&self, _application: &UIApplication) {
|
|
let mtm = MainThreadMarker::new().unwrap();
|
|
app_state::handle_nonuser_event(mtm, EventWrapper::StaticEvent(Event::Suspended))
|
|
}
|
|
|
|
#[method(applicationWillEnterForeground:)]
|
|
fn will_enter_foreground(&self, application: &UIApplication) {
|
|
self.send_occluded_event_for_all_windows(application, false);
|
|
}
|
|
|
|
#[method(applicationDidEnterBackground:)]
|
|
fn did_enter_background(&self, application: &UIApplication) {
|
|
self.send_occluded_event_for_all_windows(application, true);
|
|
}
|
|
|
|
#[method(applicationWillTerminate:)]
|
|
fn will_terminate(&self, application: &UIApplication) {
|
|
let mut events = Vec::new();
|
|
for window in application.windows().iter() {
|
|
if window.is_kind_of::<WinitUIWindow>() {
|
|
// SAFETY: We just checked that the window is a `winit` window
|
|
let window = unsafe {
|
|
let ptr: *const UIWindow = window;
|
|
let ptr: *const WinitUIWindow = ptr.cast();
|
|
&*ptr
|
|
};
|
|
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
|
window_id: RootWindowId(window.id()),
|
|
event: WindowEvent::Destroyed,
|
|
}));
|
|
}
|
|
}
|
|
let mtm = MainThreadMarker::new().unwrap();
|
|
app_state::handle_nonuser_events(mtm, events);
|
|
app_state::terminated(mtm);
|
|
}
|
|
|
|
#[method(applicationDidReceiveMemoryWarning:)]
|
|
fn did_receive_memory_warning(&self, _application: &UIApplication) {
|
|
let mtm = MainThreadMarker::new().unwrap();
|
|
app_state::handle_nonuser_event(mtm, EventWrapper::StaticEvent(Event::MemoryWarning))
|
|
}
|
|
}
|
|
);
|
|
|
|
impl AppDelegate {
|
|
fn send_occluded_event_for_all_windows(&self, application: &UIApplication, occluded: bool) {
|
|
let mut events = Vec::new();
|
|
for window in application.windows().iter() {
|
|
if window.is_kind_of::<WinitUIWindow>() {
|
|
// SAFETY: We just checked that the window is a `winit` window
|
|
let window = unsafe {
|
|
let ptr: *const UIWindow = window;
|
|
let ptr: *const WinitUIWindow = ptr.cast();
|
|
&*ptr
|
|
};
|
|
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
|
|
window_id: RootWindowId(window.id()),
|
|
event: WindowEvent::Occluded(occluded),
|
|
}));
|
|
}
|
|
}
|
|
let mtm = MainThreadMarker::new().unwrap();
|
|
app_state::handle_nonuser_events(mtm, events);
|
|
}
|
|
}
|