# DeltaY in MouseWheel Event OSX

On OSX I am using the DeltaY argument in the MouseWheel event to move graphics in a canvas up and down. I note that the rate of movement is not the same as other OS applications such as if i go into iCal and scroll up and down, the graphics displacement for the same mouse wheel (trackpad swipe) is much greater. I have already tried moving my graphics by 2DeltaY and 3DeltaY etc but then I just get a nasty looking juddery scroll due to the 3 pixel jump for every DeltaY.

Any tips?

You could try to organize the 3 pixels jump in a loop of three times 1 pixels, instead of skipping two. The speed would be the same, but cinematics could be smoother.

I see the concept but it would be a nightmare to calculate, bare in mind that the MouseWheel event has inertia, deceleration and acceleration so to get it consistent my loop of 3 x 1 pixel would need to be timed appropriately with the current rate of mouse wheel events i.e. 3 x 1pixel movements between 2 mouse wheel events or at least 2 events with deltaY > 0

What I meant is this : jumps are jittery. Instead of a jump, do deltaY several times in a raw. In effect you get the same displacement, but in smaller increments, resulting in a smoother animation. I just tried and it seems convincing.

```Function MouseWheel(X As Integer, Y As Integer, deltaX as Integer, deltaY as Integer) As Boolean for i as integer = 0 to 4 Xscroll = xscroll+deltax yscroll = yscroll+deltay me.scroll(deltax, deltay) next End Function ```

As far as I can tell, the inertia does not manifest with the regular deltaY value in the MouseWheel event.

See https://forum.xojo.com/3803-mousewheel-scroll-that-feels-native for an interesting discussion about that not long ago.

It definitely does. I can scroll fast, let go and my canvas decelerates.

``````  Dim CorrectX As Single = DeltaX
Dim CorrectY As Single = DeltaY
Dim UsesPixelDeltas As Boolean

#if TargetCocoa
Try
Declare Function objc_getClass Lib "Cocoa.framework" (aClassName As CString) As Ptr
Declare Function sel_registerName Lib "/usr/lib/libobjc.dylib" (Name As CString) As Ptr
Declare Function GetSharedApplication Lib "Cocoa.framework" Selector "sharedApplication" (Target As Ptr) As Ptr
Declare Function GetCurrentEvent Lib "Cocoa.framework" Selector "currentEvent" (Target As Ptr) As Ptr
Declare Function RespondsToSelector Lib "Cocoa.framework" Selector "respondsToSelector:" (Target As Ptr, Sel As Ptr) As Boolean
Declare Function HasPreciseScrollingDeltas Lib "Cocoa.framework" Selector "hasPreciseScrollingDeltas" (Target As Ptr) As Boolean
Declare Function ScrollingDeltaX Lib "Cocoa.framework" Selector "scrollingDeltaX" (Target As Ptr) As Single
Declare Function ScrollingDeltaY Lib "Cocoa.framework" Selector "scrollingDeltaY" (Target As Ptr) As Single

Dim NSApplication As Ptr = objc_getClass("NSApplication")
If NSApplication <> Nil Then
Dim SharedApplication As Ptr = GetSharedApplication(NSApplication)
If SharedApplication <> Nil Then
Dim EventObject As Ptr = GetCurrentEvent(SharedApplication)
If EventObject <> Nil Then
If RespondsToSelector(EventObject,sel_registerName("hasPreciseScrollingDeltas")) Then
UsesPixelDeltas = HasPreciseScrollingDeltas(EventObject)
CorrectX = ScrollingDeltaX(EventObject) * -1
CorrectY = ScrollingDeltaY(EventObject) * -1
End If
End If
End If
End If
Catch Err As RuntimeException
UsesPixelDeltas = False
CorrectX = DeltaX * -1
CorrectY = DeltaY * -1
End Try
#endif

me.Value = me.Value + (CorrectY) - (CorrectX)``````

The example above is what you need.

I believe it’s the same that I got from Thom McGrath: Canvas.MouseWheel and native feeling Delta - macOS - Xojo Programming Forum

There’s also <https://xojo.com/issue/32886>

Do you guys have any ideas on how to control the bounds of this mousewheel declares? When I have tried it looks really bad (flickers and bounces unnaturally).

Thanks!

What do you mean by bounds? MouseWheel is just a delta vector.

If you mean a bounce like Safari does when content is scrolled past the very top or bottom that’s accomplished with an NSScrollView with elasticity true. A ScrollView can do this because it has a document view whose bounds are tracked so it knows where edges are that need to be elastically bounced back.

This doesn’t explain flickering though, or an unnatural bounce. Can you show some code or explain more what you’re doing?

I have nested containers and I did try NSScrollView unsuccessfully.

My code in the mousewheel (which doesn’t give me what I want naturally) is

``````  #Pragma DisableBackgroundTasks
#Pragma DisableBoundsChecking

Dim CorrectX As Single = DeltaX
Dim CorrectY As Single = DeltaY
Dim UsesPixelDeltas As Boolean

Try
Declare Function objc_getClass Lib "Cocoa.framework" (aClassName As CString) As Ptr
Declare Function sel_registerName Lib "/usr/lib/libobjc.dylib" (Name As CString) As Ptr
Declare Function GetSharedApplication Lib "Cocoa.framework" Selector "sharedApplication" (Target As Ptr) As Ptr
Declare Function GetCurrentEvent Lib "Cocoa.framework" Selector "currentEvent" (Target As Ptr) As Ptr
Declare Function RespondsToSelector Lib "Cocoa.framework" Selector "respondsToSelector:" (Target As Ptr, Sel As Ptr) As Boolean
Declare Function HasPreciseScrollingDeltas Lib "Cocoa.framework" Selector "hasPreciseScrollingDeltas" (Target As Ptr) As Boolean
Declare Function ScrollingDeltaX Lib "Cocoa.framework" Selector "scrollingDeltaX" (Target As Ptr) As Single
Declare Function ScrollingDeltaY Lib "Cocoa.framework" Selector "scrollingDeltaY" (Target As Ptr) As Single

Dim NSApplication As Ptr = objc_getClass("NSApplication")
If NSApplication <> Nil Then
Dim SharedApplication As Ptr = GetSharedApplication(NSApplication)
If SharedApplication <> Nil Then
Dim EventObject As Ptr = GetCurrentEvent(SharedApplication)
If EventObject <> Nil Then
If RespondsToSelector(EventObject,sel_registerName("hasPreciseScrollingDeltas")) Then
UsesPixelDeltas = HasPreciseScrollingDeltas(EventObject)
CorrectX = ScrollingDeltaX(EventObject) * -1
CorrectY = ScrollingDeltaY(EventObject) * -1
End If
End If
End If
End If
Catch Err As RuntimeException
UsesPixelDeltas = False
CorrectX = DeltaX * -1
CorrectY = DeltaY * -1
End Try

Me.ScrollValX = CorrectX
Me.ScrollValY = CorrectY

ScrollimageTop = ScrollimageTop - ScrollValY
ScrollimageLeft = ScrollimageLeft - ScrollValX

// CONTROL SCROLLING BOUNDS TOP
Dim thisConnectedDevice as Common_Module.ConnectedDevice_Class = Common_Module.ConnectedDeviceClassArray(AristaEAPI_Window.SelectedIndexID)
Dim thisSelectedReport as Integer = thisConnectedDevice.FeatureContainerView_ReportCenter.SelectedReportIndexID_DeviceProfileReport
Dim theReportContainerArray() as DeviceProfileReportContainer = Common_Module.ConnectedDeviceClassArray(AristaEAPI_Window.SelectedIndexID).FeatureContainerView_ReportCenter.DeviceProfileReportContainerArray()
Dim totalNumPages as Integer = theReportContainerArray(thisSelectedReport).CreateReportClass.pageNumStart
Dim thisTopLimit as Integer = (totalNumPages -2) * -1240

// CONTROL SCROLL BOTTOM BOUNDS
If ScrollimageTop <= thisTopLimit Then
ScrollimageTop = thisTopLimit + 1
End If
// CONTROL SCROLL TOP BOUNDS
If ScrollimageTop >= 10 Then
ScrollimageTop = 9
End If

// CONTROL SCROLL LEFT BOUNDS
If ScrollimageLeft >= 10 Then
ScrollimageLeft = 9
End If

// CONTROL SCROLL RIGHT BOUNDS
Dim RightBoundary as Integer = Me.Left + Me.Width
If ScrollimageLeft <= RightBoundary  Then
ScrollimageLeft = 9
End If
Me.Invalidate(False)
``````

I didn’t study at your code, but just used a part of it, and looked what happened:

[code] Dim CorrectX As Single = DeltaX
Dim CorrectY As Single = DeltaY
Dim UsesPixelDeltas As Boolean

Try
Declare Function objc_getClass Lib “Cocoa.framework” (aClassName As CString) As Ptr
Declare Function sel_registerName Lib “/usr/lib/libobjc.dylib” (Name As CString) As Ptr
Declare Function GetSharedApplication Lib “Cocoa.framework” Selector “sharedApplication” (Target As Ptr) As Ptr
Declare Function GetCurrentEvent Lib “Cocoa.framework” Selector “currentEvent” (Target As Ptr) As Ptr
Declare Function RespondsToSelector Lib “Cocoa.framework” Selector “respondsToSelector:” (Target As Ptr, Sel As Ptr) As Boolean
Declare Function HasPreciseScrollingDeltas Lib “Cocoa.framework” Selector “hasPreciseScrollingDeltas” (Target As Ptr) As Boolean
Declare Function ScrollingDeltaX Lib “Cocoa.framework” Selector “scrollingDeltaX” (Target As Ptr) As Single
Declare Function ScrollingDeltaY Lib “Cocoa.framework” Selector “scrollingDeltaY” (Target As Ptr) As Single

``````Dim NSApplication As Ptr = objc_getClass("NSApplication")
If NSApplication <> Nil Then
Dim SharedApplication As Ptr = GetSharedApplication(NSApplication)
If SharedApplication <> Nil Then
Dim EventObject As Ptr = GetCurrentEvent(SharedApplication)
If EventObject <> Nil Then
If RespondsToSelector(EventObject,sel_registerName("hasPreciseScrollingDeltas")) Then
UsesPixelDeltas = HasPreciseScrollingDeltas(EventObject)
CorrectX = ScrollingDeltaX(EventObject) * -1
CorrectY = ScrollingDeltaY(EventObject) * -1
End If
End If
End If
End If
``````

Catch Err As RuntimeException
UsesPixelDeltas = False
CorrectX = DeltaX * -1
CorrectY = DeltaY * -1
End Try

Self.x = Self.x - CorrectX
Self.y = Self.y - CorrectY

Me.Invalidate()

Return True[/code]
In the Paint event of the canvas I did put this:

``  g.DrawPicture(Pic, x, y)``

… and in the Constructor of the windows this code:

``` Super.Constructor() pic = New Picture(100, 100, 32) pic.Graphics.DrawOval(0, 0, pic.Graphics.Width, pic.Graphics.Height)```
The window also has to properties x and y.

Works.