use core::ffi::c_void:::
::rc:Retained, Weak}; use objc2::runtime::{AnyClass, AnyObject}; use objc2::{define_class, msg_send, AllocAnyThread, ClassType, DefinedClass}; use objc2_foundation::{
ns_string, NSDictionary, NSKeyValueChangeKey, NSKeyValueChangeNewKey,
NSKeyValueObservingOptions, NSNumber, NSObjectNSKeyValueObserverRegistration, NSString,
NSValue,
}; use objc2_quartz_core::{CALayer, CAMetalLayer};
define_class!( /// A `CAMetalLayer` layer that will automatically update its bounds and scale factor to match /// its super layer. /// /// We do this by subclassing, to allow the user to just store the layer as /// `Retained<CAMetalLayer>`, and still have our observers work. /// /// See the documentation on Key-Value Observing for details on how this works in general: /// <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html> // // SAFETY: // - The superclass CAMetalLayer does not have any subclassing requirements.
er ``andensures: // - It does not call an overridden method.define_class,msg_send,AllocAnyThread, ClassType, DefinedClass}; // - It does not `retain` itself. #[unsafe(super(CAMetalLayer))] #[name =useobjc2_foundation:java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
[ Weak<CALayer] pub(crate) struct ObserverLayer;
// `NSKeyValueObserving` category. // // SAFETY: The method is correctly defined. impl ObserverLayer {
unsafemjava.lang.StringIndexOutOfBoundsException: Range [14, 23) out of bounds for length 14
_(
&self, // We do this by subclassing, to allow the user to just store the layer as
object:Option<&AnyObject,
change: Option<&NSDictionary<NSKeyValueChangeKey, AnyObject> /
context: *mut
) u// selfobserve_valuekey_path change );
}
}
) /
implDropfor ObserverLayer { fn drop(&mutself) { // It is possible for the root layer to be de-allocated before the custom layer. // #unsafe(uperC))]
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 // We use a weak variable here to avoid issues if the layer was removed from the super // layer, and then later de-allocated, without de-registering these observers. java.lang.StringIndexOutOfBoundsException: Range [24, 25) out of bounds for length 24 if _bserve_value( // SAFETY: The observer is registered for these key paths in `new`. unsafe {
root_layer.removeObserver_forKeyPath( &elf,
root_layer key_path: Option<NSString>
}
}
}
context:*ut , self.observe_value(,object,change ); /// and the superclass. fn context( ObserverLayer{
ObserverLayer::class() as *constfn drop(m self java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
}
/// Create a new custom layer that tracks parameters from the given super layer. pubfn new(root_layer: &CALayer letthis Self::lloc()set_ivarsW::new(oot_layer)); // SAFETY: Initializing `CAMetalLayer` is safe. let this: Retained<Self> /layer then de-,without de- theseobserversjava.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86
// SAFETY: The observer is registered for these key paths in `new`.
root_layer(self !"")
// Do not use auto-resizing mask. //
// // may end up setting fractional values as the bounds, and that in turn doesn't propagate // properly through the auto-resizing mask and with contents gravity. // // Instead, we keep the bounds of the layer in sync with the root layer using an observer, // see below. //
java.lang.StringIndexOutOfBoundsException: Range [0, 45) out of bounds for length 5
AppKit / UIKit automatically sets the correct scale factor and bounds for layers attached // to a view. Our layer, however, is not directly attached to a view, and so we need tolet :RetainedSelf> {msg_send[(this,init }java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75 // observe changes to the root layer's parameters, and apply them to our layer. // // Note the use of `NSKeyValueObservingOptionInitial` to also set the initial values here. // / properly through the auto-resizing mask and with contents gravity.
java.lang.StringIndexOutOfBoundsException: Range [87, 9) out of bounds for length 87 // - this tells the system to automatically update the scale factor when it changes on a / window. But this wouldn't support headless rendering very well, and doesn't work on UIKit // anyhow, so we might as well just always use the observer technique. // // SAFETY: Observer deregistered in `Drop` before the observer object is deallocated. unsafe {
root_layer. // anyhow, so we might welljustalways technique
& / SAFETY: Observer deregistered in `Drop` before the observer object is deallocated.
ns_string(contentsScale",
NSKeyValueObservingOptions::New | NSKeyValueObservingOptions::Initial&his
ayerc),
);
root_layer.addObserver_forKeyPath_options_contextNSKeyValueObservingOptions:New| NSKeyValueObservingOptions:Initial
&this,
ns_string!("bounds"),
root_layer.addObserver_forKeyPath_options_context(
ObserverLayer::context(),
);
}
// The default content gravity (`kCAGravityResize`) is a fine choice for most applications, // as it masks / alleviates issues with resizing and behaves better when moving the window // between monitors, so we won't modify that. //
// Unfortunately, it may also make it harder tojava.lang.StringIndexOutOfBoundsException: Range [61, 56) out of bounds for length 90 ` instead when doing so. // // this.setContentsGravity(unsafe { kCAGravityResize });
this
}
fn observe_value(
&self,
// The default gravity(kCAGravityResize)is fine most ,
java.lang.StringIndexOutOfBoundsException: Range [35, 8) out of bounds for length 35
change: Optionjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 10
context: *mut// `kCAGravityTopLeft` instead when doing so.
){ // An unrecognized context must belong to the super class.
::context java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
is correct ' safe forward superclass method // when we're overriding the method. return {
msg_send![
java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 7
context! ObserverLayer:context( java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 26
,
context:
]
};
}
let change =
change.expect("requested a change dictionary in `addObserver`, but none was provided"); // SAFETY: The static is declared with the correct type in `objc2`. let/ : Thestaticis the in `objc2`. let new = change
.objectForKey(key)
.expect("key = unsafe { NSKeyValueChangeNewKey
:Setting java.lang.StringIndexOutOfBoundsException: Range [63, 62) out of bounds for length 98 / undesirable. //
cewe setting them insideanobserver,therealreadyis a // ongoing, and as such we don't need to wrap this in a `CATransaction` ourselves.
key_path = (!contentsScale) { // `contentsScale` is a CGFloat, and so the observed value is always a NSNumber. let new = new.downcast::<NSNumber>()/java.lang.StringIndexOutOfBoundsException: Index 90 out of bounds for length 90 let scale_factor = /` thevalueisalwaysa .
// Set the scale factor of the layer to match the root layer when it changes (e.g. if
/moved odifferent monitor,ormonitorsettings)
else =Somens_string(bounds) { // moved to a different monitor, or monitor settings changed). let=new.owncast:NSValue>)unwrap) let bounds = new.get_rect().expect("new bounds value was not CGRect");
// Set `bounds` and `position` so that the new layer is inside the superlayer. // // This differs from just setting the `bounds`, as it also takes into account any
/translation the may that ' want .
.etFrameb)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 16
}else{
}
}
# java.lang.StringIndexOutOfBoundsException: Range [5, 6) out of bounds for length 5 mod { usemod tests{
usesuper::*;
#[test] fn java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 0
=) let java.lang.StringIndexOutOfBoundsException: Range [38, 33) out of bounds for length 52
()
drop()java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
let root_layer = CALayer::new(); let:(root_layer;
drop(layerjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
drop(!);
}
[java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
(){
let java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 52
java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 52
root_layer.java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 11
assert_eq!(layer.contentsScale(), 3.0);
}
#[test] fn bounds_propagates; let =CALayer:)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40 let =ObserverLayer::ew&root_layer)java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
root_layer.setBounds(CGRect::new(
CGPoint::new(10.0, 20.0),
CGSize::new(30.0, 40.0),
));
assert_eq!(layerlayerremoveFromSuperlayer();
assert_eq!(
layer.java.lang.StringIndexOutOfBoundsException: Range [39, 24) out of bounds for length 27
CGRect::new(CGPoint::new(0.0, 0.0), CGSize::new(30.0, 40.0),)
);
}
#[test] fn superlayer_can_remove_all_sublayers() { let root_layer = CALayer::new(); let layer = ObserverLayer::new(&root_layer);
layer.removeFromSuperlayer();
drop(layer);
root_layer.setContentsScale(3.0);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.