charvista,
thank you for reviewing and expanding my example code.
charvista wrote:ScrollStep is not necessary! Because it is always 1. This is because the logic was not very correct.
You are right! Although ScrollStep is only 1 if the width/height ratio is 1. In my
example ScrollStep is 2.33742332458496

My example isn't wrong but it makes things more difficult as they are. The problem arose
because I used GadgetWidth(0) instead of ImageWidth(0) in the definition of my
ScrollBarGadget...
One hint to improve your example: you commented out the test on #WM_HSCROLL in your
WindowCallback. This generates a lot of unneccessary CPU load because on every message
from your ScrollBarGadgets the image will be redrawn. But you are right that my solution is
not very clean because when positioning the scrollbar knob at the beginning or end the image
will be moved a bit when releasing the knob. For a solution you only need to take a look into
the
code example from Windows API guru srod: he only updates the image position if the
scrollcode doesn't indicate #SB_THUMBPOSITION or #SB_ENDSCROLL. Therefore I have updated
my Windows example:
Code: Select all
EnableExplicit
Procedure WindowCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
Protected ScrollCode.L
If LParam = GadgetID(1)
If Msg = #WM_HSCROLL
ScrollCode = WParam & $FFFF
If ScrollCode <> #SB_THUMBPOSITION And ScrollCode <> #SB_ENDSCROLL
GrabImage(0, 1, GetGadgetState(1), 0, GadgetWidth(0) - 4, ImageHeight(0))
SetGadgetState(0, ImageID(1))
EndIf
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
If LoadImage(0, #PB_Compiler_Home + "/examples/sources/Data/PureBasicLogo.bmp")
OpenWindow(0, 200, 100, 172, 100, "Live tracking", #PB_Window_SystemMenu)
ImageGadget(0, 5, 5, WindowWidth(0) - 9, ImageHeight(0), 0, #PB_Image_Border)
ScrollBarGadget(1, 5, WindowHeight(0) - 20, WindowWidth(0) - 10, 15, 0, ImageWidth(0), WindowWidth(0) - 10)
GrabImage(0, 1, GetGadgetState(1), 0, GadgetWidth(0) - 4, ImageHeight(0))
SetGadgetState(0, ImageID(1))
SetWindowCallback(@WindowCallback(), 0)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
And this is the updated cross-platform example:
Code: Select all
EnableExplicit
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
ProcedureC ScrollBarCallback(*Range.GtkRange, ScrollType.L, NewValue.D, UserData.L)
GrabImage(0, 1, GetGadgetState(1), 0, GadgetWidth(0) - 4, ImageHeight(0))
SetGadgetState(0, ImageID(1))
EndProcedure
CompilerCase #PB_OS_MacOS
ImportC ""
CreateScrollBarControl(WindowRef.L, *BoundsRect, CurrentValue.L, MinimumValue.L, MaximumValue.L, ViewSize.L, LiveTracking.L, LiveTrackingProc.L, *ControlRef)
GetControl32BitMaximum(ControlRef.L)
GetControl32BitMinimum(ControlRef.L)
GetControl32BitValue(ControlRef.L)
SetControl32BitValue(ControlRef.L, NewValue.L)
ShowControl(ControlRef.L)
EndImport
#kControlDownButtonPart = 21
#kControlUpButtonPart = 20
Structure Rect
Top.W
Left.W
Bottom.W
Right.W
EndStructure
ProcedureC ScrollBarCallback(ControlRef.L, PartCode.L)
Protected CurrentPosition.L
Select PartCode
Case #kControlUpButtonPart
CurrentPosition = GetControl32BitValue(ControlRef)
If CurrentPosition > GetControl32BitMinimum(ControlRef)
SetControl32BitValue(ControlRef.L, CurrentPosition)
EndIf
Case #kControlDownButtonPart
CurrentPosition = GetControl32BitValue(ControlRef)
If CurrentPosition < GetControl32BitMaximum(ControlRef)
SetControl32BitValue(ControlRef.L, CurrentPosition)
EndIf
EndSelect
GrabImage(0, 1, GetControl32BitValue(ControlRef), 0, GadgetWidth(0) - 4, ImageHeight(0))
SetGadgetState(0, ImageID(1))
EndProcedure
CompilerCase #PB_OS_Windows
Procedure WindowCallback(WindowHandle.I, Msg.I, WParam.I, LParam.I)
Protected ScrollCode.L
If LParam = GadgetID(1)
If Msg = #WM_HSCROLL
ScrollCode = WParam & $FFFF
If ScrollCode <> #SB_THUMBPOSITION And ScrollCode <> #SB_ENDSCROLL
GrabImage(0, 1, GetGadgetState(1), 0, GadgetWidth(0) - 4, ImageHeight(0))
SetGadgetState(0, ImageID(1))
EndIf
EndIf
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
CompilerEndSelect
If LoadImage(0, #PB_Compiler_Home + "/examples/sources/Data/PureBasicLogo.bmp")
OpenWindow(0, 200, 100, 172, 100, "Live tracking", #PB_Window_SystemMenu)
ImageGadget(0, 5, 5, WindowWidth(0) - 9, ImageHeight(0), 0, #PB_Image_Border)
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Define Bounds.Rect
Define ScrollBarRef.L
Bounds\Left = 5
Bounds\Top = WindowHeight(0) - 20
Bounds\Right = WindowWidth(0) - 5
Bounds\Bottom = WindowHeight(0) - 5
If CreateScrollBarControl(WindowID(0), @Bounds, 0, 0, GadgetWidth(0), GadgetWidth(0), #True, @ScrollBarCallback(), @ScrollBarRef) = 0
ShowControl(ScrollBarRef)
GrabImage(0, 1, GetControl32BitValue(ScrollBarRef), 0, GadgetWidth(0) - 4, ImageHeight(0))
EndIf
CompilerElse
ScrollBarGadget(1, 5, WindowHeight(0) - 20, WindowWidth(0) - 10, 15, 0, ImageWidth(0), WindowWidth(0) - 10)
GrabImage(0, 1, GetGadgetState(1), 0, GadgetWidth(0) - 4, ImageHeight(0))
CompilerEndIf
SetGadgetState(0, ImageID(1))
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Linux
g_signal_connect_data_(GadgetID(1), "change-value", @ScrollBarCallback(), 0, 0, 0)
CompilerCase #PB_OS_Windows
SetWindowCallback(@WindowCallback(), 0)
CompilerEndSelect
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf