ScrollBarGadget stops Repeat Loop - how to prevent?

Just starting out? Need help? Post your questions and find answers here.
RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

Hello, I use a ScrollBarGadget, but the repeat loop stops when I click on the ScrollBarGadget. It would be nice, especially with a ScrollBarGadget, if the loop wouldn't stop then, for example when tones are played back, whose volume should then be changed via the ScrollBarGadget. I otherwise work with BindEventGadget. Is there a way to force the loop to continue when clicking on a ScrollBarGadget or is this not possible for technical reasons? Thanks for info.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by BarryG »

For us to help, you need to post a small snippet of code that we can run that shows the problem.
RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

Sorry, I had forgotten to write, that my described problem probably always appeares if a ScrollBarGadget is clicked. Please have a look at the example PureBasiic has published in the help for this purpose. Also there the loop stops when ScrollBarGadget is clicked. Is that caused by Windows? I'm using Windows 10 Home. Is there a way to force the loop to run, although a ScrollBarGadget is clicked? Thanks.
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by Axolotl »

Hey RE42,

you may stumble upon the normal behavior of windows. Perhaps the following example will help. I added a thread to do some tasks in parallel. This is only a kind of proof of concept. Bear in mind, that direct access to gadgets inside a thread works only on windows. But that is a different story.....

Code: Select all

  EnableExplicit 

  Global THREAD = 0 
  Global ExitApp = #False 
  Global counter 

  Procedure DebugInThread(*Value) 
    Protected cnt  
    While ExitApp = #False 
      Delay(200) 
      Debug "Thread: " + cnt 
      cnt + 1 
    Wend  
  EndProcedure 


  If OpenWindow(0, 0, 0, 305, 140, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    TextGadget       (2,  10, 25, 250,  20, "ScrollBar Standard  (start=50, page=30/100)",#PB_Text_Center)
    ScrollBarGadget  (0,  10, 42, 250,  20, 0, 100, 30)
    SetGadgetState   (0,  50)   ; set 1st scrollbar (ID = 0) to 50 of 100
    TextGadget       (3,  10,115, 250,  20, "ScrollBar Vertical  (start=100, page=50/300)",#PB_Text_Right)
    ScrollBarGadget  (1, 270, 10,  25, 120 ,0, 300, 50, #PB_ScrollBar_Vertical)
    SetGadgetState   (1, 100)   ; set 2nd scrollbar (ID = 1) to 100 of 300
;   Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

    AddWindowTimer(0, 1, 250) 
    THREAD = CreateThread(@DebugInThread(), 0) 

    Repeat 
      Select WaitWindowEvent() 
        Case  #PB_Event_CloseWindow 
          ExitApp = #True 
          WaitThread(THREAD, 1000) 
          Break 
        Case  #PB_Event_Timer 
          Debug "Timer: " + counter 
          counter + 1 
        Case  #PB_Event_Gadget 
          Select EventGadget()
            Case 0
              Debug "Info: The ScrollBar 0 has been used ! (" + GetGadgetState(0) + ")" 
             ;MessageRequester("Info","The ScrollBar 0 has been used ! (" + GetGadgetState(0) + ")" ,#PB_MessageRequester_Ok)
            Case 1
              Debug "Info: The ScrollBar 1 has been used ! (" + GetGadgetState(1) + ")" 
             ;MessageRequester("Info","The ScrollBar 1 has been used ! (" + GetGadgetState(1) + ")" ,#PB_MessageRequester_Ok) 
          EndSelect 
      EndSelect
    ForEver 
    RemoveWindowTimer(0, 1) 
  EndIf
Happy coding and stay healthy.
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

Hi Axolotl,

Sorry for my late reply, but I was at work in between. Thanks for your effort with the code. That's interesting, but in any case it remains that the repeat loop stops as soon as the ScrollBarGadget is clicked. So it can't be realized for example that you move the slider and at the same time a timer realizes to play back one sound after the other. With a TrackBarGadget, however, this is possible, but unfortunately in PureBasic the kind of TrackBarGadget is missing, which points vertically to the left (I would need just that one). But I can live with the fact that the SccrollBarGadet is in my case a little less comfortable to use. Thanks again. Happy coding and healthiness for you too.
User avatar
jacdelad
Addict
Addict
Posts: 1432
Joined: Wed Feb 03, 2021 12:46 pm
Location: Planet Riesa
Contact:

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by jacdelad »

There's still the option to create your own gadget with a canvas
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Axolotl
Enthusiast
Enthusiast
Posts: 435
Joined: Wed Dec 31, 2008 3:36 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by Axolotl »

Hey RE42,

well. The thing is that PureBasic is using the standard windows controls with there behaviour.

I would very much like to recommend that one also learn the basics of the operating system used.
IMHO, this can be done also with pure c-code program examples. I actually started with C once (many years ago) under windows 3.11. And I still benefit today from the basics I learned.
If one has understood that it is a message-based system, which constantly sends messages, then one understands, also individual controls better.
For example: The timer message has a very low priority. This means that many messages come before it... etc.
Sorry, but that's just my opinion, you definitely don't have to share it. :oops:

And Jacdelad is right, you can create your own Gadget and fire all the events you want....
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by firace »

Alternatively here's a TrackBarGadget pointing to the left (windows only)
Hope this helps :)

Code: Select all

OpenWindow(0, 0, 0, 320, 200, "TrackBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TrackBarGadget(2, 270, 10, 20, 170, 0, 10, #PB_TrackBar_Vertical | #PB_TrackBar_Ticks | #TBS_LEFT )
SetGadgetState(2, 8)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by firace on Wed Sep 21, 2022 5:58 pm, edited 1 time in total.
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by firace »

Would this code help? Works for me. (Make sure to enable 'threaded executable' in compiler options)

The idea is to have a repeat loop with a delay in the threaded procedure instead of a window timer.

The code is from my personal library - feel free to remove anything that's not relevant to your requirements

EDIT: removed some irrelevant parts

Code: Select all

Procedure BindVScrollDatas()
    SetGadgetText(111," " + GetGadgetState(1))
EndProcedure

Procedure Playstuff(*x)
  Repeat
    x + 1
    Debug x
    Delay(1000)
  ForEver
EndProcedure   


OpenWindow(0, 0, 0, 400, 400, "ScrollBarGadget", #PB_Window_ScreenCentered | #PB_Window_SystemMenu) 

ScrollBarGadget  (1, 365, 60,  15, 320 ,0, 300, 50, #PB_ScrollBar_Vertical)
TextGadget(111,0,0,0,0,"0",#WS_BORDER)
ResizeGadget(111,GadgetX(1)-40, 20 ,50,16)

CreateThread(@playstuff(),1)

BindGadgetEvent(1, @ BindVScrollDatas())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 

RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

Thank you very much for your code! It is great, but unfortunately so far I haven't managed to implement it like that in my own code. I'll keep trying and let you know when it works.
RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

@Axoloti and Jacdelad

Creating an own Gadget is also a good idea, but it's a slider. I'll think about it. Thanks!

@ firace
I didn't read carefully enough your explanation for TrackBarGadget pointing to the left. Great, I didn't know that possibility: Thanks!
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by mk-soft »

TrackBar Example with Canvas playfulness ... (TrackBar as Procent with 2 decimal point)

Code: Select all

;-TOP

#ProgramTitle = "TrackBar Example"
#ProgramVersion = "v1.01.3"

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  #MainMenuAbout
  #MainMenuExit
EndEnumeration

Enumeration Gadgets
  #MainCanvas
  #MainTrackBarV
  #MainTrackBarH
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

Macro LOWORD(dwValue) : dwValue & $FFFF : EndMacro;
Macro HIWORD(dwValue) : dwValue >> 16 : EndMacro;

Macro MAKELPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;
Macro MAKEWPARAM( loWord, hiWord) : (hiWord << 16 | loWord) : EndMacro;

Structure udtCanvasGadget
  Gadget.i
  BackColor.i
  BoxColor.i
  BoxSize.i
  LineColor.i
  TrackOffset.i
  TrackPosX.i
  TrackPosY.i
EndStructure

Global CanvasData.udtCanvasGadget

; ----

Procedure InitCanvas(Gadget, *Data.udtCanvasGadget)
  With *Data
    \Gadget = Gadget
    \BackColor = #White
    \BoxColor = #Red
    \BoxSize = 17
    \LineColor = #Gray
    CompilerSelect #PB_Compiler_OS
      CompilerCase #PB_OS_Windows
        \TrackOffset = 13
      CompilerCase #PB_OS_Linux
        \TrackOffset = 3
      CompilerCase #PB_OS_MacOS
        \TrackOffset = 12
    CompilerEndSelect
  EndWith
  
EndProcedure

Procedure DrawCanvas(*Data.udtCanvasGadget)
  Protected dx, dy, deltaX, deltaY, PosX, PosY, Size2
  With *Data
    If StartDrawing(CanvasOutput(\Gadget))
      dx = GadgetWidth(\Gadget)
      dy = GadgetHeight(\Gadget)
      deltaX = dx - 2 * \TrackOffset - 1
      deltaY = dy - 2 * \TrackOffset - 1
      PosX = \TrackPosX * deltaX / 10000 + \TrackOffset
      PosY = \TrackPosY * deltaY / 10000 + \TrackOffset
      Size2 = \BoxSize / 2
      Box(0, 0, dx, dy, \BackColor)
      LineXY(0, PosY, dx, PosY, \LineColor)
      LineXY(PosX, 0, PosX, dy, \LineColor)
      Box(PosX - Size2, PosY - Size2, \BoxSize, \BoxSize, \BoxColor)
      ;Circle(PosX, PosY, Size2, \BoxColor)
      StopDrawing()
    EndIf  
  EndWith
  
EndProcedure

Procedure DoEventTrackBar()
  Protected info.s, x, y
  x = GetGadgetState(#MainTrackBarH)
  y = 10000 - GetGadgetState(#MainTrackBarV)
  With CanvasData
    \TrackPosX = x
    \TrackPosY = y
  EndWith
  DrawCanvas(CanvasData)
  info = " X = " + Str(x) + " / Y = " + Str(y)
  StatusBarText(#MainStatusBar, 0, info)
EndProcedure

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
  ; Resize gadgets
  ResizeGadget(#MainCanvas, 10, 10, dx - 50, dy - 50)
  ResizeGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50)
  ResizeGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30)
  DrawCanvas(CanvasData)
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, #ProgramTitle , #MainStyle)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    MenuTitle("&File")
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      MenuItem(#PB_Menu_About, "")
    CompilerElse
      MenuItem(#MainMenuAbout, "About")
      MenuBar()
    CompilerEndIf
    
    MenuItem(#MainMenuExit, "E&xit")
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar) - MenuHeight()
    
    CanvasGadget(#MainCanvas, 10, 10, dx - 50, dy - 50)
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      TrackBarGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30, 0, 10000, #TBS_TOP)
      TrackBarGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50, 0, 10000, #PB_TrackBar_Vertical | #TBS_LEFT)
      SendMessage_(GadgetID(#MainTrackBarH), #WM_UPDATEUISTATE, MAKEWPARAM(#UIS_SET, #UISF_HIDEFOCUS), 0)
      SendMessage_(GadgetID(#MainTrackBarV), #WM_UPDATEUISTATE, MAKEWPARAM(#UIS_SET, #UISF_HIDEFOCUS), 0)
    CompilerElse
      TrackBarGadget(#MainTrackBarH, 10, dy - 40, dx - 50, 30, 0, 10000)
      TrackBarGadget(#MainTrackBarV, dx - 40, 10, 30, dy - 50, 0, 10000, #PB_TrackBar_Vertical)
    CompilerEndIf
    
    SetGadgetState(#MainTrackBarH, 5000)
    SetGadgetState(#MainTrackBarV, 10000 - 5000)
    
    InitCanvas(#MainCanvas, CanvasData)
    DoEventTrackBar()
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    BindGadgetEvent(#MainTrackBarV, @DoEventTrackBar())
    BindGadgetEvent(#MainTrackBarH, @DoEventTrackBar())
    
    AddWindowTimer(#Main, 1, 1000)
    
    ; Event Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              Break
              
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                PostEvent(#PB_Event_Menu, #Main, #MainMenuAbout)
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
            
          Case #MainMenuAbout
            MessageRequester("About", #ProgramTitle + #LF$ + #ProgramVersion, #PB_MessageRequester_Info)
              
          Case #MainMenuExit
            PostEvent(#PB_Event_CloseWindow, #Main, #Null)
            
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
        Case #PB_Event_Timer
          Select EventTimer()
            Case 1
              ;Debug "Timer 1"
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RASHAD »

Play Sound with changing volume using ScrooBarGadget() as per the original request

Code: Select all

Global  Quit , volume ,SoundFileName$

If InitSound() = 0
  MessageRequester("Error", "Sound system is not available",  0)
  End
EndIf

Procedure runsound(par)
  Repeat
    If SoundFileName$
      If LoadSound(0, SoundFileName$)
        PlaySound(0)
        Repeat       
          SoundVolume(0,volume)
        Until GetSoundPosition(0) >= SoundLength(0) Or Quit = 1
      Else
        MessageRequester("Error", "Can't load the sound.", 0)
      EndIf
    EndIf
  Until Quit = 1    
EndProcedure

If OpenWindow(0, 0, 0, 305, 140, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget       (1,  10, 20, 250,  24, "Volume = 50 ",#PB_Text_Center)
  ScrollBarGadget  (0,  10, 42, 250,  20, 0, 100, 1)
  SetGadgetState   (0,  50)
  
  ButtonGadget(2,10,105,60,24,"RUN")
  thread = CreateThread(@runsound(),30)
  volume = 50
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()
          Case 0
            volume = GetGadgetState(0)
            SetGadgetText(1,"Volume = "+Str(volume))
            
          Case 2
            SoundFileName$ = OpenFileRequester("Choose a .wav file", "", "Wave files|*.wav",0)              
        EndSelect
    EndSelect
  Until Quit = 1
EndIf
With instantaneous values

Code: Select all

Global  Quit , volume ,SoundFileName$

If InitSound() = 0
  MessageRequester("Error", "Sound system is not available",  0)
  End
EndIf

Procedure runsound(par)
  Repeat
    If SoundFileName$
      If LoadSound(0, SoundFileName$)
        PlaySound(0)
        Repeat       
          SoundVolume(0,volume)
        Until GetSoundPosition(0) >= SoundLength(0) Or Quit = 1
      Else
        MessageRequester("Error", "Can't load the sound.", 0)
      EndIf
    EndIf
  Until Quit = 1    
EndProcedure

Procedure sbgadget()
  volume = GetGadgetState(0)
  SetGadgetText(1,"Volume = "+Str(volume))
EndProcedure

If OpenWindow(0, 0, 0, 305, 140, "ScrollBarGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget       (1,  10, 20, 250,  24, "Volume = 50 ",#PB_Text_Center)
  ScrollBarGadget  (0,  10, 42, 250,  20, 0, 100, 1)
  SetGadgetState   (0,  50)
  
  ButtonGadget(2,10,105,60,24,"RUN")
  thread = CreateThread(@runsound(),30)
  volume = 50
  BindGadgetEvent(0,@sbGadget())
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Gadget
        Select EventGadget()            
          Case 2
            SoundFileName$ = OpenFileRequester("Choose a .wav file", "", "Wave files|*.wav",0)              
        EndSelect
    EndSelect
  Until Quit = 1
EndIf

Egypt my love
RE42
New User
New User
Posts: 6
Joined: Sun Jan 30, 2022 6:55 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by RE42 »

Thanks for your efforts, but unfortunately I can't benefit from it, sorry. However, now I'm using a TrackBarGadget.
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Post by Olli »

RE42 wrote:Please have a look at the example PureBasiic has published in the help for this purpose. Also there the loop stops when ScrollBarGadget is clicked.
In this way, you copy and paste this code here, between markups[code]and[/code]to share and describe the problem, which often is a coder coding problem.
Post Reply