Clean up AutoLayout wrapper.
- Anchors are now enums, which help in debugging constraint issues. - Enum types that are acceptable for constraint generation are now matched at runtime, and provide better error messages if a constraint can't be satisfied and crashes the app. - `left` and `right` anchors are now supported on all widgets, fixing an oversight from early iterations of the framework. - Reduces `unsafe` usage by a decent amount when setting constraint pointers for widget types.
This commit is contained in:
parent
696907aa73
commit
9446092169
|
@ -38,9 +38,15 @@ pub struct Button {
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -77,14 +83,16 @@ impl Button {
|
||||||
Button {
|
Button {
|
||||||
handler: None,
|
handler: None,
|
||||||
image: None,
|
image: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,16 +44,22 @@ fn allocate_view(registration_fn: fn() -> *const Class) -> id {
|
||||||
pub struct ImageView {
|
pub struct ImageView {
|
||||||
/// A pointer to the Objective-C runtime view controller.
|
/// A pointer to the Objective-C runtime view controller.
|
||||||
pub objc: ShareId<Object>,
|
pub objc: ShareId<Object>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -82,14 +88,16 @@ impl ImageView {
|
||||||
let view = allocate_view(register_image_view_class);
|
let view = allocate_view(register_image_view_class);
|
||||||
|
|
||||||
ImageView {
|
ImageView {
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,16 +89,22 @@ pub struct TextField<T = ()> {
|
||||||
|
|
||||||
/// A pointer to the delegate for this view.
|
/// A pointer to the delegate for this view.
|
||||||
pub delegate: Option<Box<T>>,
|
pub delegate: Option<Box<T>>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -128,14 +134,16 @@ impl TextField {
|
||||||
|
|
||||||
TextField {
|
TextField {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,14 +165,16 @@ impl<T> TextField<T> where T: TextFieldDelegate + 'static {
|
||||||
|
|
||||||
let mut label = TextField {
|
let mut label = TextField {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![label, topAnchor] }),
|
top: LayoutAnchorY::top(label),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![label, leadingAnchor] }),
|
left: LayoutAnchorX::left(label),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![label, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(label),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![label, bottomAnchor] }),
|
right: LayoutAnchorX::right(label),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![label, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(label),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![label, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(label),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![label, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(label),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![label, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(label),
|
||||||
|
center_x: LayoutAnchorX::center(label),
|
||||||
|
center_y: LayoutAnchorY::center(label),
|
||||||
objc: unsafe { ShareId::from_ptr(label) },
|
objc: unsafe { ShareId::from_ptr(label) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,7 +194,9 @@ impl<T> TextField<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
//! A wrapper for `NSLayoutAnchorDimension`, which is typically used to handle `width` and `height`
|
|
||||||
//! values for how a given view should layout.
|
|
||||||
|
|
||||||
use core_graphics::base::CGFloat;
|
use core_graphics::base::CGFloat;
|
||||||
|
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
|
@ -15,82 +12,128 @@ use super::attributes::{LayoutAttribute, LayoutRelation};
|
||||||
/// A wrapper for `NSLayoutAnchor`. You should never be creating this yourself - it's more of a
|
/// A wrapper for `NSLayoutAnchor`. You should never be creating this yourself - it's more of a
|
||||||
/// factory/helper for creating `LayoutConstraint` objects based on your views.
|
/// factory/helper for creating `LayoutConstraint` objects based on your views.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct LayoutAnchorDimension(pub Option<ShareId<Object>>);
|
pub struct LayoutAnchorDimension2(pub Option<ShareId<Object>>);
|
||||||
|
|
||||||
|
/// A wrapper for `NSLayoutAnchorDimension`, which is typically used to handle `width` and `height`
|
||||||
|
/// values for how a given view should layout.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum LayoutAnchorDimension {
|
||||||
|
/// Represents an uninitialized anchor (e.g, for a view that's not created yet).
|
||||||
|
Uninitialized,
|
||||||
|
|
||||||
|
/// Represents a Width anchor.
|
||||||
|
Width(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a Height anchor.
|
||||||
|
Height(ShareId<Object>)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LayoutAnchorDimension {
|
||||||
|
/// Returns an Uninitialized anchor dimension by default.
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Uninitialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LayoutAnchorDimension {
|
impl LayoutAnchorDimension {
|
||||||
/// An internal method for wrapping existing anchors.
|
/// Given a view, returns an anchor for the width anchor.
|
||||||
pub(crate) fn new(object: id) -> Self {
|
pub(crate) fn width(view: id) -> Self {
|
||||||
LayoutAnchorDimension(Some(unsafe {
|
Self::Width(unsafe {
|
||||||
ShareId::from_ptr(object)
|
ShareId::from_ptr(msg_send![view, widthAnchor])
|
||||||
}))
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the height anchor.
|
||||||
|
pub(crate) fn height(view: id) -> Self {
|
||||||
|
Self::Height(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, heightAnchor])
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint equal to a constant value.
|
/// Return a constraint equal to a constant value.
|
||||||
pub fn constraint_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
pub fn constraint_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
||||||
match &self.0 {
|
if let Self::Width(obj) | Self::Height(obj) = self {
|
||||||
Some(from) => LayoutConstraint::new(unsafe {
|
return LayoutConstraint::new(unsafe {
|
||||||
let value = constant as CGFloat;
|
let value = constant as CGFloat;
|
||||||
msg_send![*from, constraintEqualToConstant:value]
|
msg_send![*obj, constraintEqualToConstant:value]
|
||||||
}),
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Attempted to create a constant constraint with an uninitialized anchor.");
|
||||||
|
}
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
/// Return a constraint greater than or equal to a constant value.
|
||||||
|
pub fn constraint_greater_than_or_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
||||||
|
if let Self::Width(obj) | Self::Height(obj) = self {
|
||||||
|
return LayoutConstraint::new(unsafe {
|
||||||
|
let value = constant as CGFloat;
|
||||||
|
msg_send![*obj, constraintGreaterThanOrEqualToConstant:value]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Attempted to create a constraint (>=) with an uninitialized anchor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a constraint greater than or equal to a constant value.
|
||||||
|
pub fn constraint_less_than_or_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
||||||
|
if let Self::Width(obj) | Self::Height(obj) = self {
|
||||||
|
return LayoutConstraint::new(unsafe {
|
||||||
|
let value = constant as CGFloat;
|
||||||
|
msg_send![*obj, constraintLessThanOrEqualToConstant:value]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("Attempted to create a constraint (<=) with an uninitialized anchor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Boilerplate for handling constraint construction and panic'ing with some more helpful
|
||||||
|
/// messages. The goal here is to make AutoLayout slightly easier to debug when things go
|
||||||
|
/// wrong.
|
||||||
|
fn constraint_with<F>(&self, anchor_to: &LayoutAnchorDimension, handler: F) -> LayoutConstraint
|
||||||
|
where
|
||||||
|
F: Fn(&ShareId<Object>, &ShareId<Object>) -> id
|
||||||
|
{
|
||||||
|
match (self, anchor_to) {
|
||||||
|
(Self::Width(from), Self::Width(to)) |
|
||||||
|
(Self::Width(from), Self::Height(to)) |
|
||||||
|
(Self::Height(from), Self::Width(to)) |
|
||||||
|
(Self::Height(from), Self::Height(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Uninitialized, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"from\" and \"to\" dimension anchor.");
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Uninitialized, _) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"from\" dimension anchor.");
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
(_, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"to\" dimension anchor.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint equal to another dimension anchor.
|
/// Return a constraint equal to another dimension anchor.
|
||||||
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint greater than or equal to another dimension anchor.
|
/// Return a constraint greater than or equal to another dimension anchor.
|
||||||
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a constraint greater than or equal to a constant value.
|
|
||||||
pub fn constraint_greater_than_or_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
|
||||||
match &self.0 {
|
|
||||||
Some(from) => LayoutConstraint::new(unsafe {
|
|
||||||
let value = constant as CGFloat;
|
|
||||||
msg_send![*from, constraintGreaterThanOrEqualToConstant:value]
|
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint less than or equal to another dimension anchor.
|
/// Return a constraint less than or equal to another dimension anchor.
|
||||||
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorDimension) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a constraint greater than or equal to a constant value.
|
|
||||||
pub fn constraint_less_than_or_equal_to_constant(&self, constant: f64) -> LayoutConstraint {
|
|
||||||
match &self.0 {
|
|
||||||
Some(from) => LayoutConstraint::new(unsafe {
|
|
||||||
let value = constant as CGFloat;
|
|
||||||
msg_send![*from, constraintLessThanOrEqualToConstant:value]
|
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
//! A wrapper for `NSLayoutAnchorX`, which is typically used to handle values for how a
|
|
||||||
//! given view should layout along the x-axis. Of note: the only thing that can't be protected
|
|
||||||
//! against is mixing/matching incorrect left/leading and right/trailing anchors. Be careful!
|
|
||||||
|
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
use objc_id::ShareId;
|
use objc_id::ShareId;
|
||||||
|
@ -9,49 +5,182 @@ use objc_id::ShareId;
|
||||||
use crate::foundation::id;
|
use crate::foundation::id;
|
||||||
use crate::layout::constraint::LayoutConstraint;
|
use crate::layout::constraint::LayoutConstraint;
|
||||||
|
|
||||||
/// A wrapper for `NSLayoutAnchor`. You should never be creating this yourself - it's more of a
|
/// A wrapper for `NSLayoutAnchorX`, used to handle values for how a given view should
|
||||||
/// factory/helper for creating `LayoutConstraint` objects based on your views.
|
/// layout along the x-axis.
|
||||||
#[derive(Clone, Debug, Default)]
|
///
|
||||||
pub struct LayoutAnchorX(pub Option<ShareId<Object>>);
|
/// Of note: mismatches of incorrect left/leading and right/trailing anchors are detected at
|
||||||
|
/// runtime, and will panic - this is by design, as your UI needs to work. Be careful!
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum LayoutAnchorX {
|
||||||
|
/// Represents an uninitialized anchor (e.g, for a view that's not created yet).
|
||||||
|
Uninitialized,
|
||||||
|
|
||||||
|
/// Represents a leading anchor; side depends on system orientation.
|
||||||
|
Leading(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a left anchor.
|
||||||
|
Left(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a trailing anchor; side depends on system orientation.
|
||||||
|
Trailing(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a right anchor.
|
||||||
|
Right(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a center anchor on the X axis.
|
||||||
|
Center(ShareId<Object>)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LayoutAnchorX {
|
||||||
|
/// Returns an uninitialized anchor by default.
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Uninitialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LayoutAnchorX {
|
impl LayoutAnchorX {
|
||||||
/// An internal method for wrapping existing anchors.
|
/// Given a view, returns an anchor for the leading anchor.
|
||||||
pub(crate) fn new(object: id) -> Self {
|
pub(crate) fn leading(view: id) -> Self {
|
||||||
LayoutAnchorX(Some(unsafe {
|
Self::Leading(unsafe {
|
||||||
ShareId::from_ptr(object)
|
ShareId::from_ptr(msg_send![view, leadingAnchor])
|
||||||
}))
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the left anchor.
|
||||||
|
pub(crate) fn left(view: id) -> Self {
|
||||||
|
Self::Left(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, leftAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the trailing anchor.
|
||||||
|
pub(crate) fn trailing(view: id) -> Self {
|
||||||
|
Self::Trailing(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, trailingAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the right anchor.
|
||||||
|
pub(crate) fn right(view: id) -> Self {
|
||||||
|
Self::Right(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, rightAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the right anchor.
|
||||||
|
pub(crate) fn center(view: id) -> Self {
|
||||||
|
Self::Center(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, centerXAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Boilerplate for handling constraint construction and panic'ing with some more helpful
|
||||||
|
/// messages. The goal here is to make AutoLayout slightly easier to debug when things go
|
||||||
|
/// wrong.
|
||||||
|
fn constraint_with<F>(&self, anchor_to: &LayoutAnchorX, handler: F) -> LayoutConstraint
|
||||||
|
where
|
||||||
|
F: Fn(&ShareId<Object>, &ShareId<Object>) -> id
|
||||||
|
{
|
||||||
|
match (self, anchor_to) {
|
||||||
|
// The anchors that can connect to each other. These blocks could be condensed, but are
|
||||||
|
// kept separate for readability reasons.
|
||||||
|
(Self::Leading(from), Self::Leading(to)) | (Self::Leading(from), Self::Trailing(to)) |
|
||||||
|
(Self::Leading(from), Self::Center(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Trailing(from), Self::Trailing(to)) | (Self::Trailing(from), Self::Leading(to)) |
|
||||||
|
(Self::Trailing(from), Self::Center(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Left(from), Self::Left(to)) | (Self::Left(from), Self::Right(to)) |
|
||||||
|
(Self::Left(from), Self::Center(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Right(from), Self::Right(to)) | (Self::Right(from), Self::Left(to)) |
|
||||||
|
(Self::Right(from), Self::Center(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Center(from), Self::Center(to)) | (Self::Center(from), Self::Leading(to)) |
|
||||||
|
(Self::Center(from), Self::Trailing(to)) | (Self::Center(from), Self::Left(to)) |
|
||||||
|
(Self::Center(from), Self::Right(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
// These anchors explicitly cannot be attached to each other, as it results in
|
||||||
|
// undefined/unexpected layout behavior when a system has differing ltr/rtl setups.
|
||||||
|
(Self::Leading(_), Self::Left(_)) | (Self::Left(_), Self::Leading(_)) => {
|
||||||
|
panic!(r#"
|
||||||
|
Attempted to attach a "leading" constraint to a "left" constraint. This will
|
||||||
|
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
|
||||||
|
|
||||||
|
Use either left/right or leading/trailing.
|
||||||
|
"#);
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Leading(_), Self::Right(_)) | (Self::Right(_), Self::Leading(_)) => {
|
||||||
|
panic!(r#"
|
||||||
|
Attempted to attach a "leading" constraint to a "right" constraint. This will
|
||||||
|
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
|
||||||
|
|
||||||
|
Use either left/right or leading/trailing.
|
||||||
|
"#);
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Trailing(_), Self::Left(_)) | (Self::Left(_), Self::Trailing(_)) => {
|
||||||
|
panic!(r#"
|
||||||
|
Attempted to attach a "trailing" constraint to a "left" constraint. This will
|
||||||
|
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
|
||||||
|
|
||||||
|
Use either left/right or leading/trailing.
|
||||||
|
"#);
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Trailing(_), Self::Right(_)) | (Self::Right(_), Self::Trailing(_)) => {
|
||||||
|
panic!(r#"
|
||||||
|
Attempted to attach a "trailing" constraint to a "right" constraint. This will
|
||||||
|
result in undefined behavior for LTR and RTL system settings, and Cacao blocks this.
|
||||||
|
|
||||||
|
Use either left/right or leading/trailing.
|
||||||
|
"#);
|
||||||
|
},
|
||||||
|
|
||||||
|
// If anything is attempted with an uninitialized anchor, then block it.
|
||||||
|
(Self::Uninitialized, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"from\" and \"to\" X anchor.");
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Uninitialized, _) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"from\" X anchor.");
|
||||||
|
},
|
||||||
|
|
||||||
|
(_, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"to\" X anchor.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint equal to another horizontal anchor.
|
/// Return a constraint equal to another horizontal anchor.
|
||||||
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create horizontal constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint greater than or equal to another horizontal anchor.
|
/// Return a constraint greater than or equal to another horizontal anchor.
|
||||||
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create horizontal constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint less than or equal to another horizontal anchor.
|
/// Return a constraint less than or equal to another horizontal anchor.
|
||||||
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorX) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create horizontal constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,53 @@
|
||||||
//! Various traits related to controllers opting in to autolayout routines and support for view
|
//! Various traits related to controllers opting in to autolayout routines and support for view
|
||||||
//! heirarchies.
|
//! heirarchies.
|
||||||
|
|
||||||
|
use core_graphics::geometry::{CGRect, CGPoint, CGSize};
|
||||||
|
|
||||||
|
use objc::{msg_send, sel, sel_impl};
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
use objc_id::ShareId;
|
use objc_id::ShareId;
|
||||||
|
|
||||||
|
use crate::foundation::{id, YES, NO};
|
||||||
|
use crate::geometry::Rect;
|
||||||
|
|
||||||
/// A trait that view wrappers must conform to. Enables managing the subview tree.
|
/// A trait that view wrappers must conform to. Enables managing the subview tree.
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub trait Layout {
|
pub trait Layout {
|
||||||
/// Returns a reference to the backing Objective-C layer. This is optional, as we try to keep
|
/// Returns a reference to the backing Objective-C layer. This is optional, as we try to keep
|
||||||
/// the general lazy-loading approach Cocoa has. This may change in the future, and in general
|
/// the general lazy-loading approach Cocoa has. This may change in the future, and in general
|
||||||
/// this shouldn't affect your code too much (if at all).
|
/// this shouldn't affect your code too much (if at all).
|
||||||
fn get_backing_node(&self) -> ShareId<Object>;
|
fn get_backing_node(&self) -> ShareId<Object>;
|
||||||
|
|
||||||
/// This trait should implement adding a view to the subview tree for a given view.
|
/// This trait method should implement adding a view to the subview tree for a given view.
|
||||||
fn add_subview<V: Layout>(&self, _view: &V);
|
fn add_subview<V: Layout>(&self, view: &V);
|
||||||
|
|
||||||
|
/// Sets the `frame` for the view this trait is applied to.
|
||||||
|
///
|
||||||
|
/// Note that Cacao, by default, opts into autolayout - you need to call
|
||||||
|
/// `set_translates_autoresizing_mask_into_constraints` to enable frame-based layout calls (or
|
||||||
|
/// use an appropriate initializer for a given view type).
|
||||||
|
fn set_frame<R: Into<CGRect>>(&self, rect: R) {
|
||||||
|
let backing_node = self.get_backing_node();
|
||||||
|
let frame: CGRect = rect.into();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![&*backing_node, setFrame:frame];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets whether the view for this trait should translate autoresizing masks into layout
|
||||||
|
/// constraints.
|
||||||
|
///
|
||||||
|
/// Cacao defaults this to `false`; if you need to set frame-based layout pieces,
|
||||||
|
/// then you should set this to `true` (or use an appropriate initializer that does it for you).
|
||||||
|
fn set_translates_autoresizing_mask_into_constraints(&self, translates: bool) {
|
||||||
|
let backing_node = self.get_backing_node();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let _: () = msg_send![&*backing_node, setTranslatesAutoresizingMaskIntoConstraints:match translates {
|
||||||
|
true => YES,
|
||||||
|
false => NO
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
//! A wrapper for `NSLayoutAnchorX`, which is typically used to handle values for how a
|
|
||||||
//! given view should layout along the x-axis. Of note: the only thing that can't be protected
|
|
||||||
//! against is mixing/matching incorrect left/leading and right/trailing anchors. Be careful!
|
|
||||||
|
|
||||||
use objc::{msg_send, sel, sel_impl};
|
use objc::{msg_send, sel, sel_impl};
|
||||||
use objc::runtime::Object;
|
use objc::runtime::Object;
|
||||||
use objc_id::ShareId;
|
use objc_id::ShareId;
|
||||||
|
@ -9,50 +5,102 @@ use objc_id::ShareId;
|
||||||
use crate::foundation::id;
|
use crate::foundation::id;
|
||||||
use crate::layout::constraint::LayoutConstraint;
|
use crate::layout::constraint::LayoutConstraint;
|
||||||
|
|
||||||
/// A wrapper for `NSLayoutAnchor`. You should never be creating this yourself - it's more of a
|
/// A wrapper for `NSLayoutAnchorY`, used to handle values for how a given view should
|
||||||
/// factory/helper for creating `LayoutConstraint` objects based on your views.
|
/// layout along the y-axis.
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct LayoutAnchorY(pub Option<ShareId<Object>>);
|
pub enum LayoutAnchorY {
|
||||||
|
/// Represents an uninitialized anchor (e.g, for a view that's not created yet).
|
||||||
|
Uninitialized,
|
||||||
|
|
||||||
|
/// Represents a top anchor.
|
||||||
|
Top(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a bottom anchor.
|
||||||
|
Bottom(ShareId<Object>),
|
||||||
|
|
||||||
|
/// Represents a center anchor for the Y axis.
|
||||||
|
Center(ShareId<Object>)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for LayoutAnchorY {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::Uninitialized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LayoutAnchorY {
|
impl LayoutAnchorY {
|
||||||
/// An internal method for wrapping existing constraints.
|
/// Given a view, returns an anchor for the top anchor.
|
||||||
pub(crate) fn new(object: id) -> Self {
|
pub(crate) fn top(view: id) -> Self {
|
||||||
LayoutAnchorY(Some(unsafe {
|
Self::Top(unsafe {
|
||||||
ShareId::from_ptr(object)
|
ShareId::from_ptr(msg_send![view, topAnchor])
|
||||||
}))
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the bottom anchor.
|
||||||
|
pub(crate) fn bottom(view: id) -> Self {
|
||||||
|
Self::Bottom(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, bottomAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a view, returns an anchor for the center Y anchor.
|
||||||
|
pub(crate) fn center(view: id) -> Self {
|
||||||
|
Self::Center(unsafe {
|
||||||
|
ShareId::from_ptr(msg_send![view, centerYAnchor])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Boilerplate for handling constraint construction and panic'ing with some more helpful
|
||||||
|
/// messages. The goal here is to make AutoLayout slightly easier to debug when things go
|
||||||
|
/// wrong.
|
||||||
|
fn constraint_with<F>(&self, anchor_to: &LayoutAnchorY, handler: F) -> LayoutConstraint
|
||||||
|
where
|
||||||
|
F: Fn(&ShareId<Object>, &ShareId<Object>) -> id
|
||||||
|
{
|
||||||
|
match (self, anchor_to) {
|
||||||
|
(Self::Top(from), Self::Top(to)) | (Self::Top(from), Self::Bottom(to)) |
|
||||||
|
(Self::Top(from), Self::Center(to)) |
|
||||||
|
|
||||||
|
(Self::Bottom(from), Self::Bottom(to)) | (Self::Bottom(from), Self::Top(to)) |
|
||||||
|
(Self::Bottom(from), Self::Center(to)) |
|
||||||
|
|
||||||
|
(Self::Center(from), Self::Center(to)) | (Self::Center(from), Self::Top(to)) |
|
||||||
|
(Self::Center(from), Self::Bottom(to)) => {
|
||||||
|
LayoutConstraint::new(handler(from, to))
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Uninitialized, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with uninitialized \"from\" and \"to\" y anchors.");
|
||||||
|
},
|
||||||
|
|
||||||
|
(Self::Uninitialized, _) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"from\" y anchor.");
|
||||||
|
},
|
||||||
|
|
||||||
|
(_, Self::Uninitialized) => {
|
||||||
|
panic!("Attempted to create constraints with an uninitialized \"to\" y anchor.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint equal to another vertical anchor.
|
/// Return a constraint equal to another vertical anchor.
|
||||||
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
pub fn constraint_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintEqualToAnchor:&**to]
|
||||||
let b: id = msg_send![*from, constraintEqualToAnchor:&**to];
|
})
|
||||||
b
|
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create vertical constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint greater than or equal to another vertical anchor.
|
/// Return a constraint greater than or equal to another vertical anchor.
|
||||||
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
pub fn constraint_greater_than_or_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintGreaterThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create vertical constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return a constraint less than or equal to another vertical anchor.
|
/// Return a constraint less than or equal to another vertical anchor.
|
||||||
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
pub fn constraint_less_than_or_equal_to(&self, anchor_to: &LayoutAnchorY) -> LayoutConstraint {
|
||||||
match (&self.0, &anchor_to.0) {
|
self.constraint_with(anchor_to, |from, to| unsafe {
|
||||||
(Some(from), Some(to)) => LayoutConstraint::new(unsafe {
|
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
||||||
msg_send![*from, constraintLessThanOrEqualToAnchor:&**to]
|
})
|
||||||
}),
|
|
||||||
|
|
||||||
_ => { panic!("Attempted to create vertical constraints with an uninitialized anchor!"); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,9 +200,15 @@ pub struct ListView<T = ()> {
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -243,24 +249,27 @@ impl ListView {
|
||||||
};
|
};
|
||||||
|
|
||||||
// For macOS, we need to use the NSScrollView anchor points, not the NSTableView.
|
// For macOS, we need to use the NSScrollView anchor points, not the NSTableView.
|
||||||
|
// @TODO: Fix this with proper mutable access.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let anchor_view = &*scrollview.objc;
|
let anchor_view: id = unsafe { msg_send![&*scrollview.objc, self] };
|
||||||
|
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
let anchor_view = view;
|
let anchor_view: id = view;
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
cell_factory: CellFactory::new(),
|
cell_factory: CellFactory::new(),
|
||||||
menu: PropertyNullable::default(),
|
menu: PropertyNullable::default(),
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![anchor_view, topAnchor] }),
|
top: LayoutAnchorY::top(anchor_view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![anchor_view, leadingAnchor] }),
|
left: LayoutAnchorX::left(anchor_view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![anchor_view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(anchor_view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![anchor_view, bottomAnchor] }),
|
right: LayoutAnchorX::right(anchor_view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![anchor_view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(anchor_view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![anchor_view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(anchor_view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![anchor_view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(anchor_view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![anchor_view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(anchor_view),
|
||||||
|
center_x: LayoutAnchorX::center(anchor_view),
|
||||||
|
center_y: LayoutAnchorY::center(anchor_view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -300,7 +309,7 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
|
||||||
|
|
||||||
// For macOS, we need to use the NSScrollView anchor points, not the NSTableView.
|
// For macOS, we need to use the NSScrollView anchor points, not the NSTableView.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let anchor_view = &*scrollview.objc;
|
let anchor_view: id = unsafe { msg_send![&*scrollview.objc, self] };
|
||||||
|
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
let anchor_view = view;
|
let anchor_view = view;
|
||||||
|
@ -309,14 +318,16 @@ impl<T> ListView<T> where T: ListViewDelegate + 'static {
|
||||||
cell_factory: cell,
|
cell_factory: cell,
|
||||||
menu: PropertyNullable::default(),
|
menu: PropertyNullable::default(),
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![anchor_view, topAnchor] }),
|
top: LayoutAnchorY::top(anchor_view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![anchor_view, leadingAnchor] }),
|
left: LayoutAnchorX::left(anchor_view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![anchor_view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(anchor_view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![anchor_view, bottomAnchor] }),
|
right: LayoutAnchorX::right(anchor_view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![anchor_view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(anchor_view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![anchor_view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(anchor_view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![anchor_view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(anchor_view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![anchor_view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(anchor_view),
|
||||||
|
center_x: LayoutAnchorX::center(anchor_view),
|
||||||
|
center_y: LayoutAnchorY::center(anchor_view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
@ -341,7 +352,9 @@ impl<T> ListView<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
|
@ -92,16 +92,22 @@ pub struct ListViewRow<T = ()> {
|
||||||
|
|
||||||
/// A pointer to the delegate for this view.
|
/// A pointer to the delegate for this view.
|
||||||
pub delegate: Option<Box<T>>,
|
pub delegate: Option<Box<T>>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -131,14 +137,16 @@ impl ListViewRow {
|
||||||
|
|
||||||
ListViewRow {
|
ListViewRow {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,14 +174,16 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
||||||
|
|
||||||
let view = ListViewRow {
|
let view = ListViewRow {
|
||||||
delegate: Some(delegate),
|
delegate: Some(delegate),
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -198,14 +208,16 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
||||||
|
|
||||||
let mut view = ListViewRow {
|
let mut view = ListViewRow {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,7 +238,9 @@ impl<T> ListViewRow<T> where T: ViewDelegate + 'static {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
@ -253,7 +267,9 @@ impl<T> ListViewRow<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
|
@ -35,29 +35,35 @@ pub use enums::ProgressIndicatorStyle;
|
||||||
pub struct ProgressIndicator {
|
pub struct ProgressIndicator {
|
||||||
/// A pointer to the Objective-C Object.
|
/// A pointer to the Objective-C Object.
|
||||||
pub objc: ShareId<Object>,
|
pub objc: ShareId<Object>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C trailing layout constraint.
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C bottom layout constraint.
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C width layout constraint.
|
/// A pointer to the Objective-C runtime width layout constraint.
|
||||||
pub width: LayoutAnchorDimension,
|
pub width: LayoutAnchorDimension,
|
||||||
|
|
||||||
/// A pointer to the Objective-C height layout constraint.
|
/// A pointer to the Objective-C runtime height layout constraint.
|
||||||
pub height: LayoutAnchorDimension,
|
pub height: LayoutAnchorDimension,
|
||||||
|
|
||||||
/// A pointer to the Objective-C center X layout constraint.
|
/// A pointer to the Objective-C runtime center X layout constraint.
|
||||||
pub center_x: LayoutAnchorX,
|
pub center_x: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C center Y layout constraint.
|
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||||
pub center_y: LayoutAnchorY
|
pub center_y: LayoutAnchorY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +89,16 @@ impl ProgressIndicator {
|
||||||
};
|
};
|
||||||
|
|
||||||
ProgressIndicator {
|
ProgressIndicator {
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,16 +94,22 @@ pub struct ScrollView<T = ()> {
|
||||||
|
|
||||||
/// A pointer to the delegate for this view.
|
/// A pointer to the delegate for this view.
|
||||||
pub delegate: Option<Box<T>>,
|
pub delegate: Option<Box<T>>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -133,14 +139,16 @@ impl ScrollView {
|
||||||
|
|
||||||
ScrollView {
|
ScrollView {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,14 +168,16 @@ impl<T> ScrollView<T> where T: ScrollViewDelegate + 'static {
|
||||||
|
|
||||||
let mut view = ScrollView {
|
let mut view = ScrollView {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -187,7 +197,9 @@ impl<T> ScrollView<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
|
@ -28,9 +28,15 @@ pub struct Switch {
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -45,6 +51,7 @@ pub struct Switch {
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime center Y layout constraint.
|
/// A pointer to the Objective-C runtime center Y layout constraint.
|
||||||
pub center_y: LayoutAnchorY
|
pub center_y: LayoutAnchorY
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Switch {
|
impl Switch {
|
||||||
|
@ -62,14 +69,16 @@ impl Switch {
|
||||||
|
|
||||||
Switch {
|
Switch {
|
||||||
handler: None,
|
handler: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,16 +97,22 @@ pub struct Label<T = ()> {
|
||||||
|
|
||||||
/// A pointer to the delegate for this view.
|
/// A pointer to the delegate for this view.
|
||||||
pub delegate: Option<Box<T>>,
|
pub delegate: Option<Box<T>>,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime top layout constraint.
|
/// A pointer to the Objective-C runtime top layout constraint.
|
||||||
pub top: LayoutAnchorY,
|
pub top: LayoutAnchorY,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -136,14 +142,16 @@ impl Label {
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: unsafe { ShareId::from_ptr(view) },
|
objc: unsafe { ShareId::from_ptr(view) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,14 +173,16 @@ impl<T> Label<T> where T: LabelDelegate + 'static {
|
||||||
|
|
||||||
let mut label = Label {
|
let mut label = Label {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![label, topAnchor] }),
|
top: LayoutAnchorY::top(label),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![label, leadingAnchor] }),
|
left: LayoutAnchorX::left(label),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![label, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(label),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![label, bottomAnchor] }),
|
right: LayoutAnchorX::right(label),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![label, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(label),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![label, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(label),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![label, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(label),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![label, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(label),
|
||||||
|
center_x: LayoutAnchorX::center(label),
|
||||||
|
center_y: LayoutAnchorY::center(label),
|
||||||
objc: unsafe { ShareId::from_ptr(label) },
|
objc: unsafe { ShareId::from_ptr(label) },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,7 +202,9 @@ impl<T> Label<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
|
@ -107,9 +107,15 @@ pub struct View<T = ()> {
|
||||||
/// A pointer to the Objective-C runtime leading layout constraint.
|
/// A pointer to the Objective-C runtime leading layout constraint.
|
||||||
pub leading: LayoutAnchorX,
|
pub leading: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime left layout constraint.
|
||||||
|
pub left: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime trailing layout constraint.
|
/// A pointer to the Objective-C runtime trailing layout constraint.
|
||||||
pub trailing: LayoutAnchorX,
|
pub trailing: LayoutAnchorX,
|
||||||
|
|
||||||
|
/// A pointer to the Objective-C runtime right layout constraint.
|
||||||
|
pub right: LayoutAnchorX,
|
||||||
|
|
||||||
/// A pointer to the Objective-C runtime bottom layout constraint.
|
/// A pointer to the Objective-C runtime bottom layout constraint.
|
||||||
pub bottom: LayoutAnchorY,
|
pub bottom: LayoutAnchorY,
|
||||||
|
|
||||||
|
@ -139,14 +145,16 @@ impl View {
|
||||||
|
|
||||||
View {
|
View {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,14 +177,16 @@ impl<T> View<T> where T: ViewDelegate + 'static {
|
||||||
|
|
||||||
let mut view = View {
|
let mut view = View {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: LayoutAnchorY::new(unsafe { msg_send![view, topAnchor] }),
|
top: LayoutAnchorY::top(view),
|
||||||
leading: LayoutAnchorX::new(unsafe { msg_send![view, leadingAnchor] }),
|
left: LayoutAnchorX::left(view),
|
||||||
trailing: LayoutAnchorX::new(unsafe { msg_send![view, trailingAnchor] }),
|
leading: LayoutAnchorX::leading(view),
|
||||||
bottom: LayoutAnchorY::new(unsafe { msg_send![view, bottomAnchor] }),
|
right: LayoutAnchorX::right(view),
|
||||||
width: LayoutAnchorDimension::new(unsafe { msg_send![view, widthAnchor] }),
|
trailing: LayoutAnchorX::trailing(view),
|
||||||
height: LayoutAnchorDimension::new(unsafe { msg_send![view, heightAnchor] }),
|
bottom: LayoutAnchorY::bottom(view),
|
||||||
center_x: LayoutAnchorX::new(unsafe { msg_send![view, centerXAnchor] }),
|
width: LayoutAnchorDimension::width(view),
|
||||||
center_y: LayoutAnchorY::new(unsafe { msg_send![view, centerYAnchor] }),
|
height: LayoutAnchorDimension::height(view),
|
||||||
|
center_x: LayoutAnchorX::center(view),
|
||||||
|
center_y: LayoutAnchorY::center(view),
|
||||||
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
objc: Rc::new(RefCell::new(unsafe { Id::from_ptr(view) })),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -196,7 +206,9 @@ impl<T> View<T> {
|
||||||
delegate: None,
|
delegate: None,
|
||||||
top: self.top.clone(),
|
top: self.top.clone(),
|
||||||
leading: self.leading.clone(),
|
leading: self.leading.clone(),
|
||||||
|
left: self.left.clone(),
|
||||||
trailing: self.trailing.clone(),
|
trailing: self.trailing.clone(),
|
||||||
|
right: self.right.clone(),
|
||||||
bottom: self.bottom.clone(),
|
bottom: self.bottom.clone(),
|
||||||
width: self.width.clone(),
|
width: self.width.clone(),
|
||||||
height: self.height.clone(),
|
height: self.height.clone(),
|
||||||
|
|
Loading…
Reference in a new issue