/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! A UI using the macos cocoa API. //! //! This UI contains some edge cases that aren't implemented, for instance: //! * there are a few cases where specific hierarchies are handled differently (e.g. a Button //! containing Label), etc. //! * not all controls handle all Property variants (e.g. Checkbox doesn't handle ReadOnly, Text //! doesn't handle Binding, etc). //! //! The rendering ignores `ElementStyle::margin` entirely, because //! * `NSView` doesn't support margins (so working them into constraints would be a bit annoying), //! and //! * `NSView.layoutMarginsGuide` results in a layout almost identical to what the margins (at the //! time of this writing) in the UI layouts are achieving. //! //! In a few cases, init or creation functions are called which _could_ return nil and are wrapped //! in their type wrapper (as those functions return `instancetype`/`id`). We consider this safe //! enough because it won't cause unsoundness (they are only passed to objc functions which can //! take nil arguments) and the failure case is very unlikely. #![allow(non_upper_case_globals)] use self::objc::*; use super::model::{self, Alignment, Application, Element, TypedElement}; use crate::data::Property; use cocoa::{ INSApplication, INSBox, INSButton, INSColor, INSControl, INSFont, INSLayoutAnchor, INSLayoutConstraint, INSLayoutDimension, INSLayoutGuide, INSMenu, INSMenuItem, INSMutableParagraphStyle, INSObject, INSProcessInfo, INSProgressIndicator, INSRunLoop, INSScrollView, INSStackView, INSText, INSTextContainer, INSTextField, INSTextView, INSView, INSWindow, NSArray_NSArrayCreation, NSAttributedString_NSExtendedAttributedString, NSDictionary_NSDictionaryCreation, NSRunLoop_NSRunLoopConveniences, NSStackView_NSStackViewGravityAreas, NSString_NSStringExtensionMethods, NSTextField_NSTextFieldConvenience, NSView_NSConstraintBasedLayoutInstallingConstraints, NSView_NSConstraintBasedLayoutLayering, NSView_NSSafeAreas, PNSObject, }; use once_cell::sync::Lazy; /// https://developer.apple.com/documentation/foundation/1497293-string_encodings/nsutf8stringencoding?language=objc const NSUTF8StringEncoding: cocoa::NSStringEncoding = 4; /// Constant from NSCell.h const NSControlStateValueOn: cocoa::NSControlStateValue = 1; /// Constant from NSLayoutConstraint.h const NSLayoutPriorityDefaultHigh: cocoa::NSLayoutPriority = 750.0; mod objc; /// A MacOS Cocoa UI implementation. #[derive(Default)] pub struct UI; impl UI { pub fn run_loop(&self, app: Application) { let nsapp = unsafe { cocoa::NSApplication::sharedApplication() }; Objc::::register(); Objc::