77 lines
2.7 KiB
Rust
77 lines
2.7 KiB
Rust
//! A wrapper for `NSLayoutConstraint` that's more general in nature. You can think of this as an
|
|
//! escape hatch, if you need it (we use it for things like width and height, which aren't handled
|
|
//! by an axis).
|
|
|
|
use objc::{class, msg_send, sel, sel_impl};
|
|
use objc::runtime::Object;
|
|
use objc_id::ShareId;
|
|
|
|
use crate::foundation::{id, CGFloat};
|
|
|
|
/// A wrapper for `NSLayoutConstraint`. This both acts as a central path through which to activate
|
|
/// constraints, as well as a wrapper for layout constraints that are not axis bound (e.g, width or
|
|
/// height).
|
|
#[derive(Clone, Debug)]
|
|
pub struct LayoutConstraint {
|
|
/// A shared pointer to the underlying view. Provided your view isn't dropped, this will always
|
|
/// be valid.
|
|
pub constraint: ShareId<Object>,
|
|
|
|
/// The offset used in computing this constraint.
|
|
pub offset: f64,
|
|
|
|
/// The multiplier used in computing this constraint.
|
|
pub multiplier: f64,
|
|
|
|
/// The priority used in computing this constraint.
|
|
pub priority: f64,
|
|
}
|
|
|
|
impl LayoutConstraint {
|
|
/// An internal method for wrapping existing constraints.
|
|
pub(crate) fn new(object: id) -> Self {
|
|
LayoutConstraint {
|
|
constraint: unsafe { ShareId::from_ptr(object) },
|
|
offset: 0.0,
|
|
multiplier: 0.0,
|
|
priority: 0.0
|
|
}
|
|
}
|
|
|
|
/// Sets the offset for this constraint.
|
|
pub fn offset<F: Into<f64>>(self, offset: F) -> Self {
|
|
let offset: f64 = offset.into();
|
|
|
|
unsafe {
|
|
let o = offset as CGFloat;
|
|
let _: () = msg_send![&*self.constraint, setConstant:o];
|
|
}
|
|
|
|
LayoutConstraint {
|
|
constraint: self.constraint,
|
|
offset: offset,
|
|
multiplier: self.multiplier,
|
|
priority: self.priority
|
|
}
|
|
}
|
|
|
|
/// Call this with your batch of constraints to activate them.
|
|
// If you're astute, you'll note that, yes... this is kind of hacking around some
|
|
// borrowing rules with how objc_id::Id/objc_id::ShareId works. In this case, to
|
|
// support the way autolayout constraints work over in the cocoa runtime, we need to be
|
|
// able to clone these and pass them around... while also getting certain references to
|
|
// them.
|
|
//
|
|
// I regret nothing, lol. If you have a better solution I'm all ears.
|
|
pub fn activate(constraints: &[LayoutConstraint]) {
|
|
unsafe {
|
|
let ids: Vec<&Object> = constraints.into_iter().map(|constraint| {
|
|
&*constraint.constraint
|
|
}).collect();
|
|
|
|
let constraints: id = msg_send![class!(NSArray), arrayWithObjects:ids.as_ptr() count:ids.len()];
|
|
let _: () = msg_send![class!(NSLayoutConstraint), activateConstraints:constraints];
|
|
}
|
|
}
|
|
}
|