#![cfg(target_vendor = "apple")]
mod app_state;
mod event_loop;
mod monitor;
mod notification_center;
mod view;
mod view_controller;
mod window;
use std::os::raw::c_void;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use winit_core::monitor::{MonitorHandle, VideoMode};
use winit_core::window::{PlatformWindowAttributes, Window};
pub use self::event_loop::{EventLoop, PlatformSpecificEventLoopAttributes};
use self::monitor::MonitorHandle as UIKitMonitorHandle;
use self::window::Window as UIKitWindow;
pub trait WindowExtIOS {
fn set_scale_factor(&self, scale_factor: f64);
fn set_valid_orientations(&self, valid_orientations: ValidOrientations);
fn set_prefers_home_indicator_hidden(&self, hidden: bool);
fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge);
fn set_prefers_status_bar_hidden(&self, hidden: bool);
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle);
fn recognize_pinch_gesture(&self, should_recognize: bool);
fn recognize_pan_gesture(
&self,
should_recognize: bool,
minimum_number_of_touches: u8,
maximum_number_of_touches: u8,
);
fn recognize_doubletap_gesture(&self, should_recognize: bool);
fn recognize_rotation_gesture(&self, should_recognize: bool);
}
impl WindowExtIOS for dyn Window + '_ {
#[inline]
fn set_scale_factor(&self, scale_factor: f64) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.set_scale_factor(scale_factor));
}
#[inline]
fn set_valid_orientations(&self, valid_orientations: ValidOrientations) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.set_valid_orientations(valid_orientations));
}
#[inline]
fn set_prefers_home_indicator_hidden(&self, hidden: bool) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.set_prefers_home_indicator_hidden(hidden));
}
#[inline]
fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| {
w.set_preferred_screen_edges_deferring_system_gestures(edges)
});
}
#[inline]
fn set_prefers_status_bar_hidden(&self, hidden: bool) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.set_prefers_status_bar_hidden(hidden));
}
#[inline]
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.set_preferred_status_bar_style(status_bar_style))
}
#[inline]
fn recognize_pinch_gesture(&self, should_recognize: bool) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.recognize_pinch_gesture(should_recognize));
}
#[inline]
fn recognize_pan_gesture(
&self,
should_recognize: bool,
minimum_number_of_touches: u8,
maximum_number_of_touches: u8,
) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| {
w.recognize_pan_gesture(
should_recognize,
minimum_number_of_touches,
maximum_number_of_touches,
)
});
}
#[inline]
fn recognize_doubletap_gesture(&self, should_recognize: bool) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.recognize_doubletap_gesture(should_recognize));
}
#[inline]
fn recognize_rotation_gesture(&self, should_recognize: bool) {
let window = self.cast_ref::<UIKitWindow>().unwrap();
window.maybe_wait_on_main(move |w| w.recognize_rotation_gesture(should_recognize));
}
}
#[derive(Clone, Debug, Default, PartialEq)]
pub struct WindowAttributesIos {
pub(crate) scale_factor: Option<f64>,
pub(crate) valid_orientations: ValidOrientations,
pub(crate) prefers_home_indicator_hidden: bool,
pub(crate) prefers_status_bar_hidden: bool,
pub(crate) preferred_status_bar_style: StatusBarStyle,
pub(crate) preferred_screen_edges_deferring_system_gestures: ScreenEdge,
}
impl WindowAttributesIos {
pub fn with_scale_factor(mut self, scale_factor: f64) -> Self {
self.scale_factor = Some(scale_factor);
self
}
pub fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> Self {
self.valid_orientations = valid_orientations;
self
}
pub fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> Self {
self.prefers_home_indicator_hidden = hidden;
self
}
pub fn with_preferred_screen_edges_deferring_system_gestures(
mut self,
edges: ScreenEdge,
) -> Self {
self.preferred_screen_edges_deferring_system_gestures = edges;
self
}
pub fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> Self {
self.prefers_status_bar_hidden = hidden;
self
}
pub fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
self.preferred_status_bar_style = status_bar_style;
self
}
}
impl PlatformWindowAttributes for WindowAttributesIos {
fn box_clone(&self) -> Box<dyn PlatformWindowAttributes> {
Box::from(self.clone())
}
}
pub trait MonitorHandleExtIOS {
fn ui_screen(&self) -> *mut c_void;
fn preferred_video_mode(&self) -> VideoMode;
}
impl MonitorHandleExtIOS for MonitorHandle {
#[inline]
fn ui_screen(&self) -> *mut c_void {
let mtm = unsafe { objc2::MainThreadMarker::new_unchecked() };
let monitor = self.cast_ref::<UIKitMonitorHandle>().unwrap();
objc2::rc::Retained::as_ptr(monitor.ui_screen(mtm)) as *mut c_void
}
#[inline]
fn preferred_video_mode(&self) -> VideoMode {
let monitor = self.cast_ref::<UIKitMonitorHandle>().unwrap();
monitor.preferred_video_mode()
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ValidOrientations {
#[default]
LandscapeAndPortrait,
Landscape,
Portrait,
}
bitflags::bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct ScreenEdge: u8 {
const NONE = 0;
const TOP = 1 << 0;
const LEFT = 1 << 1;
const BOTTOM = 1 << 2;
const RIGHT = 1 << 3;
const ALL = ScreenEdge::TOP.bits() | ScreenEdge::LEFT.bits()
| ScreenEdge::BOTTOM.bits() | ScreenEdge::RIGHT.bits();
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum StatusBarStyle {
#[default]
Default,
LightContent,
DarkContent,
}