- The idea is to emulate 2D screen scrollarea with two scrollbarGadgets and without any OS-specific commands.
- I use a threaded procedure to get scrollbar positions dynamiclly.
When you use the scrollbar, the screen content moves and the animation continues too.

Code: Select all
EnableExplicit
Procedure DrawScrollingScreen()
Global *ScrollingScreenCallback
Global ScrollingScreenX.i
Global ScrollingScreenY.i
Global ScrollingScreenScrollbarX.i
Global ScrollingScreenScrollbarY.i
Global ScrollingScreenDrawMutex.i
;try to draw 2D screen (use Mutex to secure screen output)
If *ScrollingScreenCallback And TryLockMutex(ScrollingScreenDrawMutex)
ScrollingScreenX=GetGadgetState(ScrollingScreenScrollbarX)
ScrollingScreenY=GetGadgetState(ScrollingScreenScrollbarY)
CallFunctionFast(*ScrollingScreenCallback)
UnlockMutex(ScrollingScreenDrawMutex)
EndIf
EndProcedure
Procedure SetScrollingScreenCallback(*DrawProcedure)
Global *ScrollingScreenCallback
Global ScrollingScreenCloseMutex.i
Global ScrollingScreenX.i
Global ScrollingScreenY.i
Global ScrollingScreenScrollbarX.i
Global ScrollingScreenScrollbarY.i
Global ScrollingScreenDelay
If *DrawProcedure<>0
;mode 1: set callback procedure
*ScrollingScreenCallback=*DrawProcedure
Else
;mode 2: execute threaded callback procedure (use Mutex to secure closing screen)
While TryLockMutex(ScrollingScreenCloseMutex)=0
If (ScrollingScreenX<>GetGadgetState(ScrollingScreenScrollbarX) Or ScrollingScreenY<>GetGadgetState(ScrollingScreenScrollbarY))
;fast drawing refresh (because the scrollbar moved)
DrawScrollingScreen()
Delay(10)
Else
;normal drawing refresh (because the scrollbar didn't move)
DrawScrollingScreen()
Delay(ScrollingScreenDelay)
EndIf
Wend
UnlockMutex(ScrollingScreenCloseMutex)
EndIf
EndProcedure
Procedure SetScrollingScreenFramerate(framerate)
Global ScrollingScreenDelay
ScrollingScreenDelay=1000/framerate
If ScrollingScreenDelay<0 : ScrollingScreenDelay=0 : EndIf
If ScrollingScreenDelay>1000 : ScrollingScreenDelay=1000 : EndIf
EndProcedure
Procedure CloseScrollingScreen()
Global ScrollingScreenScrollbarX.i
Global ScrollingScreenScrollbarY.i
Global ScrollingScreenThread.i
Global ScrollingScreenCloseMutex.i
If ScrollingScreenThread<>0 And IsThread(ScrollingScreenThread)
UnlockMutex(ScrollingScreenCloseMutex)
While IsThread(ScrollingScreenThread)
WaitWindowEvent(10)
Wend
ScrollingScreenThread=0
EndIf
If ScrollingScreenScrollbarX<>0 And IsGadget(ScrollingScreenScrollbarX)
FreeGadget(ScrollingScreenScrollbarX)
FreeGadget(ScrollingScreenScrollbarY)
ScrollingScreenScrollbarX=0
ScrollingScreenScrollbarY=0
EndIf
CloseScreen()
EndProcedure
Procedure OpenScrollingScreen(WindowID, x, y, Width, Height, ScreenWidth, ScreenHeight, ScrollbarThickness=16, FlipMode=#PB_Screen_WaitSynchronization)
Global ScrollingScreenDrawMutex.i
Global ScrollingScreenCloseMutex.i
Global ScrollingScreenScrollbarX.i
Global ScrollingScreenScrollbarY.i
Global ScrollingScreenThread.i
Global ScrollingScreenDelay=100
If ScrollingScreenDrawMutex=0
ScrollingScreenDrawMutex=CreateMutex()
EndIf
If ScrollingScreenCloseMutex=0
ScrollingScreenCloseMutex=CreateMutex()
EndIf
If Not TryLockMutex(ScrollingScreenCloseMutex)
CloseScrollingScreen()
LockMutex(ScrollingScreenCloseMutex)
EndIf
Protected sh=height-ScrollbarThickness
Protected sw=width-ScrollbarThickness
OpenWindowedScreen(WindowID(0), x, y, sw, sh, 0, 0, 0, FlipMode)
ScrollingScreenScrollbarX=ScrollBarGadget(#PB_Any, 0, sh, sw, ScrollbarThickness, 0, ScreenHeight, sw)
ScrollingScreenScrollbarY=ScrollBarGadget(#PB_Any, sw, 0, ScrollbarThickness, sh, 0, ScreenWidth, sh, #PB_ScrollBar_Vertical)
ScrollingScreenThread=CreateThread(@SetScrollingScreenCallback(), #Null)
EndProcedure
DisableExplicit
; ********************
; EXAMPLE
; ********************
InitSprite()
OpenWindow(0, 0, 0, 400, 300, "Windowed Scrolling Screen")
OpenScrollingScreen(WindowID(0), 0, 0, 400, 300, 1024, 1024)
Procedure DrawColoredDots()
;screen scrolling variables (needed)
Global ScrollingScreenX.i
Global ScrollingScreenY.i
;{/// CUSTOM DRAWING INIT
Static CreateDots
If Not CreateDots
CreateDots=#True
Structure dot
x.i
y.i
radius.i
color.i
EndStructure
Global NewList dot.dot()
For i=0 To 100
AddElement(dot())
dot()\x=Random(1024)
dot()\y=Random(1024)
dot()\radius=Random(32)
dot()\color=RGB(Random(255), Random(255), Random(255))
Next
EndIf
;}
;{/// CUSTOM DRAWING
StartDrawing(ScreenOutput())
ForEach dot()
Circle(dot()\x-ScrollingScreenX, dot()\y-ScrollingScreenY, dot()\radius, dot()\color)
dot()\x-2+Random(4)
dot()\y-2+Random(4)
Next
StopDrawing()
FlipBuffers()
ClearScreen(RGB(0, 0, 0))
;}
EndProcedure
;screen drawing callback (needed)
SetScrollingScreenCallback(@DrawColoredDots())
;screen average framerate (optional)
SetScrollingScreenFramerate(50)
Repeat
DrawScrollingScreen()
Until WaitWindowEvent()=#PB_Event_CloseWindow
;screen closing (needed)
CloseScrollingScreen()