Scrolling Windowed Screen [win]

Share your advanced PureBasic knowledge/code with the community.
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Scrolling Windowed Screen [win]

Post by eddy »

- I did my tests with PB4.40b6 x86
- 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.

Image

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()
Last edited by eddy on Sun Nov 08, 2009 2:01 am, edited 1 time in total.
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scrolling Windowed Screen [cross-platform]

Post by eddy »

Did someone test this on mac / linux ?
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
jamirokwai
Enthusiast
Enthusiast
Posts: 798
Joined: Tue May 20, 2008 2:12 am
Location: Cologne, Germany
Contact:

Re: Scrolling Windowed Screen [cross-platform]

Post by jamirokwai »

eddy wrote:Did someone test this on mac / linux ?
Yes. The App dies on line 135 - Startdrawing(Screenoutput()) with "invalid memory access" after displaying some circles in a window. I used PB4.40b6 x86, Mac OS X 10.6.1.
Regards,
JamiroKwai
infratec
Always Here
Always Here
Posts: 7623
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Scrolling Windowed Screen [cross-platform]

Post by infratec »

Hi eddy,

it isn't working in Linux. (Kubuntu 9.04 PureBASIC 4.40b6)

The reason is, that open a windowed screen opens a second window which is a total
separate window. :(

So you will have no luck with windowed screens in Linux.

Best regards,

Bernd
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Re: Scrolling Windowed Screen [win]

Post by eddy »

I see
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
Post Reply