Rotated CALayer and issues with coordinates (should I convert them manually?)
Hi guys, I've an NSView hierarchy with: - an NSWindow with inside an NSView (called BaseContainerView) (yellow color) - inside BaseContainerView another NSView called HostView (centered) (orange color) - inside HostView.layer a CALayer called subLayer (red color) Now, everything works well when I try convert coordinates through the hierarchy. That's my code: - (void) mouseDownOnBaseContainer:(NSNotification *) notif { NSEvent *theEvent = notif.object; // Location in NSWindow CGPoint locationInWindow = theEvent.locationInWindow; // Location is root NSView (baseContainerView) CGPoint locationInBaseContainer = [baseContainerView convertPoint:locationInWindow fromView:nil]; // Location in sub NSView (hostView) CGPoint locationInHostView = [baseContainerView convertPoint:locationInBaseContainer toView:hostView]; // Location in sub CALayer (child of hostView's layer, subLayer) CGPoint locationInSubLayer = [hostView.layer convertPoint:locationInHostView toLayer:subLayer]; NSLog(@--- CLICK ---); NSLog(@NSWindow: {%0.0f,%0.0f},locationInWindow.x,locationInWindow.y); NSLog(@BaseContainerView: {%0.0f,%0.0f},locationInBaseContainer.x,locationInBaseContainer.y); NSLog(@HostView: {%0.0f,%0.0f},locationInHostView.x,locationInHostView.y); NSLog(@SubLayer: {%0.0f,%0.0f},locationInSubLayer.x,locationInSubLayer.y); } If I try to rotate my hostView.layer (CALayer) using the function below I get wrong coordinates when I try to click at the same (rotated) point (the top,left coordinate of hostView) - (IBAction)btn_rotateHostView:(id)sender { isMovingToLandscape = !isMovingToLandscape; CALayer *hostViewLayer = hostView.layer; hostViewLayer.anchorPoint = CGPointMake(0.5f, 0.5f); // 0.5,0.5 made the center of the object hostViewLayer.frame = CGRectMake((NSWidth(baseContainerView.frame) - NSWidth(hostViewLayer.frame)) / 2.0f, (NSHeight(baseContainerView.frame) - NSHeight(hostViewLayer.frame)) / 2.0f, hostViewLayer.frame.size.width, hostViewLayer.frame.size.height); [CATransaction begin]; CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @transform]; CATransform3D rotateTransform = CATransform3DMakeRotation (DEGREES_TO_RADIANS (-90), 0, 0, 1); CATransform3D restoreTransform = CATransform3DIdentity; animation.fromValue = [NSValue valueWithCATransform3D: (isMovingToLandscape ? restoreTransform : rotateTransform)]; animation.toValue = [NSValue valueWithCATransform3D: (isMovingToLandscape ? rotateTransform : restoreTransform)]; animation.duration = 1.25; animation.cumulative = NO; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; [hostViewLayer addAnimation:animation forKey:@transform]; [CATransaction commit]; } This is a visual feeback: http://i.imgur.com/LYywXXL.png While here i've uploaded source code https://dl.dropboxusercontent.com/u/103260/TestinLayer.zip Should I convert coordinates manually? Or convertPoint: methods take in place rotation transform? I should expect 4,5 at the same logical point (top-left of rotated hostView) Any idea? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Rotated CALayer and issues with coordinates (should I convert them manually?)
On Apr 27, 2013, at 2:48 AM, Daniele Margutti m...@danielemargutti.com wrote: If I try to rotate my hostView.layer (CALayer) using the function below I get wrong coordinates when I try to click at the same (rotated) point (the top,left coordinate of hostView) Point conversion happens via the model layer, not the presentation layer. By rotating the layer the way you've done, you've only changed the presentation layer, rather than the model, and thus the hit testing fails. Instead just set the layer's transform. If you want to customize the duration then use the +[CATransaction setAnimationDuration:]. No need to get into explicit animation and the many pitfalls that typically accompany it. - (IBAction)btn_rotateHostView:(id)sender { isMovingToLandscape = !isMovingToLandscape; CALayer *hostViewLayer = hostView.layer; hostViewLayer.anchorPoint = CGPointMake(0.5f, 0.5f); // 0.5,0.5 made the center of the object hostViewLayer.frame = CGRectMake((NSWidth(baseContainerView.frame) - NSWidth(hostViewLayer.frame)) / 2.0f, (NSHeight(baseContainerView.frame) - NSHeight(hostViewLayer.frame)) / 2.0f, hostViewLayer.frame.size.width, hostViewLayer.frame.size.height); [CATransaction begin]; CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath: @transform]; CATransform3D rotateTransform = CATransform3DMakeRotation (DEGREES_TO_RADIANS (-90), 0, 0, 1); CATransform3D restoreTransform = CATransform3DIdentity; animation.fromValue = [NSValue valueWithCATransform3D: (isMovingToLandscape ? restoreTransform : rotateTransform)]; animation.toValue = [NSValue valueWithCATransform3D: (isMovingToLandscape ? rotateTransform : restoreTransform)]; animation.duration = 1.25; animation.cumulative = NO; animation.removedOnCompletion = NO; animation.fillMode = kCAFillModeForwards; [hostViewLayer addAnimation:animation forKey:@transform]; [CATransaction commit]; } This is a visual feeback: http://i.imgur.com/LYywXXL.png While here i've uploaded source code https://dl.dropboxusercontent.com/u/103260/TestinLayer.zip Should I convert coordinates manually? Or convertPoint: methods take in place rotation transform? I should expect 4,5 at the same logical point (top-left of rotated hostView) Any idea? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/david.duncan%40apple.com This email sent to david.dun...@apple.com -- David Duncan ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Rotated CALayer and issues with coordinates (should I convert them manually?)
On Apr 29, 2013, at 9:33 AM, David Duncan david.dun...@apple.com wrote: On Apr 27, 2013, at 2:48 AM, Daniele Margutti m...@danielemargutti.com wrote: If I try to rotate my hostView.layer (CALayer) using the function below I get wrong coordinates when I try to click at the same (rotated) point (the top,left coordinate of hostView) Point conversion happens via the model layer, not the presentation layer. By rotating the layer the way you've done, you've only changed the presentation layer, rather than the model, and thus the hit testing fails. Instead just set the layer's transform. If you want to customize the duration then use the +[CATransaction setAnimationDuration:]. No need to get into explicit animation and the many pitfalls that typically accompany it. Hi David, thank you for your response; I've also tried to use: [CATransaction begin]; [CATransaction setAnimationDuration:4.0]; hostViewLayer.affineTransform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90)); [CATransaction commit]; and using: hostViewLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(-90),0,0,1); (while animation is not played) coordinates still at the old position (portrait) of the layer. What am I wong? ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com
Re: Rotated CALayer and issues with coordinates (should I convert them manually?)
On Apr 29, 2013, at 10:18 AM, Daniele Margutti m...@danielemargutti.com wrote: What am I wong? Meanwhile I've discovered an interesting thing. In order to convert coordinates from my baseContainerView to inner hostView I've used CGPoint locationInHostView = [baseContainerView convertPoint:locationInBaseContainer toView:hostView]; It uses NSView geometry to convert coordinates (using convertPoint:toView: of NSView) Instead of using it I've tried to use baseContainer.layer as source and hostView.layer as destination (so using convertPoint:toLayer: method of CALayer). So: CGPoint locationInHostView = [baseContainerView.layer convertPoint:locationInBaseContainer toLayer:hostView.layer]; Using this I can get right coordinates of the rotated CALayer. Now the question is: geometry can differ between NSView and it's CALayer? CALayer seems to be a separated entity of the NSView so when I try to rotate CALayer while the NSView bounds (?) still at the old original position, CALayer bounds are rotated. Should I rotate both NSView and CALayer? What kind of problems can this separation implies? Thanks ___ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com