Speed of moving window with animation

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

I do not believe for a second that a rapidly firing Timer is more power efficient than the system provided API function.

There is a way to control the animation speed with the native function:

2 Likes

Thanks a lot Tim.
Any hint on how to “declare” this? Maybe I am asking too much …

Luciano

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.

working on that now…

1 Like

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.

https://www.dropbox.com/scl/fi/ygf9mut6a3veh39y8rna8/WindowResizeTiming.xojo_binary_project?rlkey=xe4xt0cnbhk6iahfk6o8rj68k&dl=1

Usage is similar:

myWindow.ResizeAnimated(1280, 1024, Directions.TopLeft, 5)

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.

2 Likes

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.

This is absolutely fantastic !
Thanks a million.

Luciano