1 #![cfg(target_os = "ios")] 2 3 use std::os::raw::c_void; 4 5 use crate::{ 6 event_loop::EventLoop, 7 monitor::{MonitorHandle, VideoMode}, 8 window::{Window, WindowBuilder}, 9 }; 10 11 /// Additional methods on [`EventLoop`] that are specific to iOS. 12 pub trait EventLoopExtIOS { 13 /// Returns the [`Idiom`] (phone/tablet/tv/etc) for the current device. idiom(&self) -> Idiom14 fn idiom(&self) -> Idiom; 15 } 16 17 impl<T: 'static> EventLoopExtIOS for EventLoop<T> { idiom(&self) -> Idiom18 fn idiom(&self) -> Idiom { 19 self.event_loop.idiom() 20 } 21 } 22 23 /// Additional methods on [`Window`] that are specific to iOS. 24 pub trait WindowExtIOS { 25 /// Returns a pointer to the [`UIWindow`] that is used by this window. 26 /// 27 /// The pointer will become invalid when the [`Window`] is destroyed. 28 /// 29 /// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc ui_window(&self) -> *mut c_void30 fn ui_window(&self) -> *mut c_void; 31 32 /// Returns a pointer to the [`UIViewController`] that is used by this window. 33 /// 34 /// The pointer will become invalid when the [`Window`] is destroyed. 35 /// 36 /// [`UIViewController`]: https://developer.apple.com/documentation/uikit/uiviewcontroller?language=objc ui_view_controller(&self) -> *mut c_void37 fn ui_view_controller(&self) -> *mut c_void; 38 39 /// Returns a pointer to the [`UIView`] that is used by this window. 40 /// 41 /// The pointer will become invalid when the [`Window`] is destroyed. 42 /// 43 /// [`UIView`]: https://developer.apple.com/documentation/uikit/uiview?language=objc ui_view(&self) -> *mut c_void44 fn ui_view(&self) -> *mut c_void; 45 46 /// Sets the [`contentScaleFactor`] of the underlying [`UIWindow`] to `scale_factor`. 47 /// 48 /// The default value is device dependent, and it's recommended GLES or Metal applications set 49 /// this to [`MonitorHandle::scale_factor()`]. 50 /// 51 /// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc 52 /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc set_scale_factor(&self, scale_factor: f64)53 fn set_scale_factor(&self, scale_factor: f64); 54 55 /// Sets the valid orientations for the [`Window`]. 56 /// 57 /// The default value is [`ValidOrientations::LandscapeAndPortrait`]. 58 /// 59 /// This changes the value returned by 60 /// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc), 61 /// and then calls 62 /// [`-[UIViewController attemptRotationToDeviceOrientation]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621400-attemptrotationtodeviceorientati?language=objc). set_valid_orientations(&self, valid_orientations: ValidOrientations)63 fn set_valid_orientations(&self, valid_orientations: ValidOrientations); 64 65 /// Sets whether the [`Window`] prefers the home indicator hidden. 66 /// 67 /// The default is to prefer showing the home indicator. 68 /// 69 /// This changes the value returned by 70 /// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc), 71 /// and then calls 72 /// [`-[UIViewController setNeedsUpdateOfHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887509-setneedsupdateofhomeindicatoraut?language=objc). 73 /// 74 /// This only has an effect on iOS 11.0+. set_prefers_home_indicator_hidden(&self, hidden: bool)75 fn set_prefers_home_indicator_hidden(&self, hidden: bool); 76 77 /// Sets the screen edges for which the system gestures will take a lower priority than the 78 /// application's touch handling. 79 /// 80 /// This changes the value returned by 81 /// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc), 82 /// and then calls 83 /// [`-[UIViewController setNeedsUpdateOfScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887507-setneedsupdateofscreenedgesdefer?language=objc). 84 /// 85 /// This only has an effect on iOS 11.0+. set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge)86 fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge); 87 88 /// Sets whether the [`Window`] prefers the status bar hidden. 89 /// 90 /// The default is to prefer showing the status bar. 91 /// 92 /// This changes the value returned by 93 /// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc), 94 /// and then calls 95 /// [`-[UIViewController setNeedsStatusBarAppearanceUpdate]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621354-setneedsstatusbarappearanceupdat?language=objc). set_prefers_status_bar_hidden(&self, hidden: bool)96 fn set_prefers_status_bar_hidden(&self, hidden: bool); 97 } 98 99 impl WindowExtIOS for Window { 100 #[inline] ui_window(&self) -> *mut c_void101 fn ui_window(&self) -> *mut c_void { 102 self.window.ui_window() as _ 103 } 104 105 #[inline] ui_view_controller(&self) -> *mut c_void106 fn ui_view_controller(&self) -> *mut c_void { 107 self.window.ui_view_controller() as _ 108 } 109 110 #[inline] ui_view(&self) -> *mut c_void111 fn ui_view(&self) -> *mut c_void { 112 self.window.ui_view() as _ 113 } 114 115 #[inline] set_scale_factor(&self, scale_factor: f64)116 fn set_scale_factor(&self, scale_factor: f64) { 117 self.window.set_scale_factor(scale_factor) 118 } 119 120 #[inline] set_valid_orientations(&self, valid_orientations: ValidOrientations)121 fn set_valid_orientations(&self, valid_orientations: ValidOrientations) { 122 self.window.set_valid_orientations(valid_orientations) 123 } 124 125 #[inline] set_prefers_home_indicator_hidden(&self, hidden: bool)126 fn set_prefers_home_indicator_hidden(&self, hidden: bool) { 127 self.window.set_prefers_home_indicator_hidden(hidden) 128 } 129 130 #[inline] set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge)131 fn set_preferred_screen_edges_deferring_system_gestures(&self, edges: ScreenEdge) { 132 self.window 133 .set_preferred_screen_edges_deferring_system_gestures(edges) 134 } 135 136 #[inline] set_prefers_status_bar_hidden(&self, hidden: bool)137 fn set_prefers_status_bar_hidden(&self, hidden: bool) { 138 self.window.set_prefers_status_bar_hidden(hidden) 139 } 140 } 141 142 /// Additional methods on [`WindowBuilder`] that are specific to iOS. 143 pub trait WindowBuilderExtIOS { 144 /// Sets the root view class used by the [`Window`], otherwise a barebones [`UIView`] is provided. 145 /// 146 /// An instance of the class will be initialized by calling [`-[UIView initWithFrame:]`](https://developer.apple.com/documentation/uikit/uiview/1622488-initwithframe?language=objc). 147 /// 148 /// [`UIView`]: https://developer.apple.com/documentation/uikit/uiview?language=objc with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder149 fn with_root_view_class(self, root_view_class: *const c_void) -> WindowBuilder; 150 151 /// Sets the [`contentScaleFactor`] of the underlying [`UIWindow`] to `scale_factor`. 152 /// 153 /// The default value is device dependent, and it's recommended GLES or Metal applications set 154 /// this to [`MonitorHandle::scale_factor()`]. 155 /// 156 /// [`UIWindow`]: https://developer.apple.com/documentation/uikit/uiwindow?language=objc 157 /// [`contentScaleFactor`]: https://developer.apple.com/documentation/uikit/uiview/1622657-contentscalefactor?language=objc with_scale_factor(self, scale_factor: f64) -> WindowBuilder158 fn with_scale_factor(self, scale_factor: f64) -> WindowBuilder; 159 160 /// Sets the valid orientations for the [`Window`]. 161 /// 162 /// The default value is [`ValidOrientations::LandscapeAndPortrait`]. 163 /// 164 /// This sets the initial value returned by 165 /// [`-[UIViewController supportedInterfaceOrientations]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc). with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder166 fn with_valid_orientations(self, valid_orientations: ValidOrientations) -> WindowBuilder; 167 168 /// Sets whether the [`Window`] prefers the home indicator hidden. 169 /// 170 /// The default is to prefer showing the home indicator. 171 /// 172 /// This sets the initial value returned by 173 /// [`-[UIViewController prefersHomeIndicatorAutoHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887510-prefershomeindicatorautohidden?language=objc). 174 /// 175 /// This only has an effect on iOS 11.0+. with_prefers_home_indicator_hidden(self, hidden: bool) -> WindowBuilder176 fn with_prefers_home_indicator_hidden(self, hidden: bool) -> WindowBuilder; 177 178 /// Sets the screen edges for which the system gestures will take a lower priority than the 179 /// application's touch handling. 180 /// 181 /// This sets the initial value returned by 182 /// [`-[UIViewController preferredScreenEdgesDeferringSystemGestures]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/2887512-preferredscreenedgesdeferringsys?language=objc). 183 /// 184 /// This only has an effect on iOS 11.0+. with_preferred_screen_edges_deferring_system_gestures( self, edges: ScreenEdge, ) -> WindowBuilder185 fn with_preferred_screen_edges_deferring_system_gestures( 186 self, 187 edges: ScreenEdge, 188 ) -> WindowBuilder; 189 190 /// Sets whether the [`Window`] prefers the status bar hidden. 191 /// 192 /// The default is to prefer showing the status bar. 193 /// 194 /// This sets the initial value returned by 195 /// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc). with_prefers_status_bar_hidden(self, hidden: bool) -> WindowBuilder196 fn with_prefers_status_bar_hidden(self, hidden: bool) -> WindowBuilder; 197 } 198 199 impl WindowBuilderExtIOS for WindowBuilder { 200 #[inline] with_root_view_class(mut self, root_view_class: *const c_void) -> WindowBuilder201 fn with_root_view_class(mut self, root_view_class: *const c_void) -> WindowBuilder { 202 self.platform_specific.root_view_class = unsafe { &*(root_view_class as *const _) }; 203 self 204 } 205 206 #[inline] with_scale_factor(mut self, scale_factor: f64) -> WindowBuilder207 fn with_scale_factor(mut self, scale_factor: f64) -> WindowBuilder { 208 self.platform_specific.scale_factor = Some(scale_factor); 209 self 210 } 211 212 #[inline] with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> WindowBuilder213 fn with_valid_orientations(mut self, valid_orientations: ValidOrientations) -> WindowBuilder { 214 self.platform_specific.valid_orientations = valid_orientations; 215 self 216 } 217 218 #[inline] with_prefers_home_indicator_hidden(mut self, hidden: bool) -> WindowBuilder219 fn with_prefers_home_indicator_hidden(mut self, hidden: bool) -> WindowBuilder { 220 self.platform_specific.prefers_home_indicator_hidden = hidden; 221 self 222 } 223 224 #[inline] with_preferred_screen_edges_deferring_system_gestures( mut self, edges: ScreenEdge, ) -> WindowBuilder225 fn with_preferred_screen_edges_deferring_system_gestures( 226 mut self, 227 edges: ScreenEdge, 228 ) -> WindowBuilder { 229 self.platform_specific 230 .preferred_screen_edges_deferring_system_gestures = edges; 231 self 232 } 233 234 #[inline] with_prefers_status_bar_hidden(mut self, hidden: bool) -> WindowBuilder235 fn with_prefers_status_bar_hidden(mut self, hidden: bool) -> WindowBuilder { 236 self.platform_specific.prefers_status_bar_hidden = hidden; 237 self 238 } 239 } 240 241 /// Additional methods on [`MonitorHandle`] that are specific to iOS. 242 pub trait MonitorHandleExtIOS { 243 /// Returns a pointer to the [`UIScreen`] that is used by this monitor. 244 /// 245 /// [`UIScreen`]: https://developer.apple.com/documentation/uikit/uiscreen?language=objc ui_screen(&self) -> *mut c_void246 fn ui_screen(&self) -> *mut c_void; 247 248 /// Returns the preferred [`VideoMode`] for this monitor. 249 /// 250 /// This translates to a call to [`-[UIScreen preferredMode]`](https://developer.apple.com/documentation/uikit/uiscreen/1617823-preferredmode?language=objc). preferred_video_mode(&self) -> VideoMode251 fn preferred_video_mode(&self) -> VideoMode; 252 } 253 254 impl MonitorHandleExtIOS for MonitorHandle { 255 #[inline] ui_screen(&self) -> *mut c_void256 fn ui_screen(&self) -> *mut c_void { 257 self.inner.ui_screen() as _ 258 } 259 260 #[inline] preferred_video_mode(&self) -> VideoMode261 fn preferred_video_mode(&self) -> VideoMode { 262 self.inner.preferred_video_mode() 263 } 264 } 265 266 /// Valid orientations for a particular [`Window`]. 267 #[derive(Clone, Copy, Debug)] 268 pub enum ValidOrientations { 269 /// Excludes `PortraitUpsideDown` on iphone 270 LandscapeAndPortrait, 271 272 Landscape, 273 274 /// Excludes `PortraitUpsideDown` on iphone 275 Portrait, 276 } 277 278 impl Default for ValidOrientations { 279 #[inline] default() -> ValidOrientations280 fn default() -> ValidOrientations { 281 ValidOrientations::LandscapeAndPortrait 282 } 283 } 284 285 /// The device [idiom]. 286 /// 287 /// [idiom]: https://developer.apple.com/documentation/uikit/uidevice/1620037-userinterfaceidiom?language=objc 288 #[derive(Clone, Copy, Debug, PartialEq, Eq)] 289 pub enum Idiom { 290 Unspecified, 291 292 /// iPhone and iPod touch. 293 Phone, 294 295 /// iPad. 296 Pad, 297 298 /// tvOS and Apple TV. 299 TV, 300 CarPlay, 301 } 302 303 bitflags! { 304 /// The [edges] of a screen. 305 /// 306 /// [edges]: https://developer.apple.com/documentation/uikit/uirectedge?language=objc 307 #[derive(Default)] 308 pub struct ScreenEdge: u8 { 309 const NONE = 0; 310 const TOP = 1 << 0; 311 const LEFT = 1 << 1; 312 const BOTTOM = 1 << 2; 313 const RIGHT = 1 << 3; 314 const ALL = ScreenEdge::TOP.bits | ScreenEdge::LEFT.bits 315 | ScreenEdge::BOTTOM.bits | ScreenEdge::RIGHT.bits; 316 } 317 } 318