Dear all,
I am using the code below to animate DesktopWindow movement.
Is there any way to control the speed of the animation?
Thanks in advance
Luciano
Public Sub WindowResizeAnimated(inWindow as DesktopWindow, width as Integer, height as Integer, Direction as string)
#if TargetCocoa
Declare Function NSClassFromString Lib "Cocoa" (aClassName As CFStringRef) As Ptr
Declare Function NSSelectorFromString Lib "Cocoa" (aSelectorName As CFStringRef) As Ptr
Declare Function RespondsToSelector Lib "Cocoa" Selector "respondsToSelector:" (NSWindow As Ptr, aSelector As Ptr) As Boolean
Declare Function Frame Lib "Cocoa" Selector "frame" (NSWindow As Ptr) As NSRect
Declare Sub SetFrameDisplayAnimate Lib "Cocoa" Selector "setFrame:display:animate:" (NSWindow As Ptr, inNSRect As NSRect, Display As Boolean, Animate As Boolean)
DIM FrameSelector As Ptr = NSSelectorFromString("frame")
DIM SetFrameDisplayAnimateSelector As Ptr = NSSelectorFromString("setFrame:display:animate:")
if (RespondsToSelector(inWindow.Handle, FrameSelector)) AND (RespondsToSelector(inWindow.Handle, SetFrameDisplayAnimateSelector)) then
DIM deltaWidth As CGFloat = width - inWindow.Width
DIM deltaHeight As CGFloat = height - inWindow.Height
DIM frameRect As NSRect = Frame(inWindow.Handle)
frameRect.h = frameRect.h + deltaHeight
frameRect.w = frameRect.w + deltaWidth
Select case Direction
case "BottomLeft"
//
case "BottomRight"
frameRect.X= frameRect.X - deltaWidth // keep the initial coordnate
case "TopLeft"
frameRect.Y = frameRect.Y - deltaHeight
case "TopRight"
frameRect.Y = frameRect.Y - deltaHeight
frameRect.X= frameRect.X - deltaWidth // keep the initial coordnate
end Select
SetFrameDisplayAnimate inWindow.Handle, frameRect, TRUE, TRUE
end if
#else
me.Width = width
me.Height = height
#endif
// add this as structure
'Private Structure NSRect
'x as Double
'y as Double
'w as Double
'h as Double
'End Structure
End Sub
Since the way you use this function is by subclassing in Swift/Objc, that’s a question for @Sam_Rowlands who is the expert on Mac declares. Sam’s timezone is very different, so it may be a while before he comments.
Unfortunately, this isn’t even available in MBS, but if @Christian_Schmitz were to add a way to do so, I would consider it a selling point.
So what you’re asking for is “tricky” in that the method Tim pointed you to is a method that a subclass is supposed to override. It can be done, but it’s going to take a little work to do.
Ok, so I’ve made a project because it takes a few pieces to make it work. I also took the liberty of changing your Direction parameter into an Enum to prevent you from sending a bad value and changed it to an extension method…because I couldn’t help myself.
It stores the duration in a dictionary using the window’s handle as the key and then removes the value when it’s requested so the callback can be handled completely automatically.
The AnimationDuration callback method receives both the window’s handle as well as the rectangle that it’s resizing to so you could make an intelligent decision about how long it should actually take, like if the sizes were identical for instance.
Be careful with the duration that you use. macOS considers your app unresponsive during the resize so on my machine here, a value of 5 shows the spinning cursor right at the end.
Thanks for jumping in to solve this. I must say, I’d never have thought to do it the way you did it.
Somewhere in my AppKit is the code for OWCallbackExpress, this avoids the need for the dictionary as a lookup because it injects properties directly into the XOJWindow class. When testing on my old Intel Mac, the lookup time dropped from 30 microseconds to 1.