Page 1 of 2

ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Mon Sep 19, 2022 11:05 pm
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.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Tue Sep 20, 2022 1:55 am
by BarryG
For us to help, you need to post a small snippet of code that we can run that shows the problem.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Tue Sep 20, 2022 9:27 am
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.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Tue Sep 20, 2022 2:20 pm
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.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Tue Sep 20, 2022 11:32 pm
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.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Wed Sep 21, 2022 12:30 pm
by jacdelad
There's still the option to create your own gadget with a canvas

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Wed Sep 21, 2022 3:48 pm
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....

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Wed Sep 21, 2022 5:46 pm
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

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Wed Sep 21, 2022 5:56 pm
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 


Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Thu Sep 22, 2022 3:16 pm
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.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Fri Sep 23, 2022 2:36 pm
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!

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Sat Sep 24, 2022 2:00 pm
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()

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Sat Sep 24, 2022 5:16 pm
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


Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Sun Sep 25, 2022 10:05 pm
by RE42
Thanks for your efforts, but unfortunately I can't benefit from it, sorry. However, now I'm using a TrackBarGadget.

Re: ScrollBarGadget stops Repeat Loop - how to prevent?

Posted: Mon Sep 26, 2022 4:02 am
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.