Putting a trackbar in a statusbar

Share your advanced PureBasic knowledge/code with the community.
XCoder
User
User
Posts: 72
Joined: Tue Dec 31, 2013 9:18 pm

Putting a trackbar in a statusbar

Post by XCoder »

Recently I needed to put a trackbar gadget in a status bar. The purpose of the trackbar gadget was to zoom in on text in an editor gadget. This was not straightforward as I found that when the main window was resized, the trackbar gadget disappeared. I could not find how to do this on the PB forums so I toyed with PB to find a solution.

I am posting my solution here in case anybody else needs to do this.

Code: Select all

EnableExplicit

Enumeration
  #MainWindow
  #StatusBar
  #EditorGadget
  #TrackBarGadget
EndEnumeration

Global StatusRect.RECT, hEdit, hStatus
Global Maxrange, MaxD, sliderValue
Global EventID

Procedure MakeStatusBar()
  Protected hStatus
  hStatus = CreateStatusBar(#StatusBar, WindowID(#MainWindow))
  AddStatusBarField(90)
  AddStatusBarField(100)
  AddStatusBarField(200)
  AddStatusBarField(#PB_Ignore) ; automatically resize this field
  StatusBarText(#StatusBar, 0, "First bar field")
  StatusBarText(#StatusBar, 1, "Second bar field")
  ProcedureReturn hStatus
EndProcedure

Procedure SizeWindowHandler()
  Protected statusHeight
  Shared hStatus
  statusHeight= StatusBarHeight(#StatusBar)
  SendMessage_(hStatus, #SB_GETRECT, 2, StatusRect) ;2 refs the third panel in the statusbar
  ResizeGadget(#TrackBarGadget, #PB_Ignore, WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar)+5, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#EditorGadget, #PB_Ignore, #PB_Ignore, WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar))
  FreeStatusBar(#StatusBar) 
  hStatus = MakeStatusBar()
EndProcedure

OpenWindow(#MainWindow, 100, 200, 600, 400, "Gadget on status bar", #PB_Window_MinimizeGadget| #PB_Window_SizeGadget |#PB_Window_SizeGadget)

Maxrange=400 
MaxD=Maxrange/64 +1 
TrackBarGadget(#TrackBarGadget, 197, WindowHeight(#MainWindow)-20, 195, 20, 1, Maxrange )

hStatus = MakeStatusBar()
hEdit=EditorGadget(#EditorGadget,1,0,WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar)) 
SetGadgetText(#EditorGadget, "Use the slider to resize the text!") 

BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())

Repeat 
  EventID = WaitWindowEvent() 
  If EventID = #PB_Event_Gadget
    Select EventGadget()
        
      Case  #TrackBarGadget 
        sliderValue=GetGadgetState(#TrackBarGadget) 
        If SendMessage_(hEdit,#EM_SETZOOM,sliderValue,MaxD) = #False
          Debug "Error, Cannot set new zooming Range" 
        EndIf
        
    EndSelect
  EndIf 
Until EventID = #PB_Event_CloseWindow 
This solution is not perfect; I discovered that the status bar needs to be created after the TrackBar gadget has been created to make the trackbar gadget stay on top of the status bar. This led me to overcome the problem of the trackbar disappearing when the main window is resized by first resizing the Trackbar gadget then freeing the status bar and then recreating the status bar. This is a clumsy solution. I would be interested to know if anybody can improve on it. I think it is possible to avoid this in VB by making the trackbar control a child of the status window but I could not achieve this in PB.
infratec
Always Here
Always Here
Posts: 7619
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Putting a trackbar in a statusbar

Post by infratec »

You can use this:
viewtopic.php?f=27&t=72513
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Putting a trackbar in a statusbar

Post by breeze4me »

The simpler way is to use SetParent_() API.

Code: Select all

EnableExplicit

Enumeration
  #MainWindow
  #StatusBar
  #EditorGadget
  #TrackBarGadget
EndEnumeration

Global StatusRect.RECT, hEdit, hStatus
Global Maxrange, MaxD, sliderValue
Global EventID

Procedure SizeWindowHandler()
  ResizeGadget(#EditorGadget, #PB_Ignore, #PB_Ignore, WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar))
EndProcedure

OpenWindow(#MainWindow, 100, 200, 600, 400, "Gadget on status bar", #PB_Window_MinimizeGadget| #PB_Window_SizeGadget |#PB_Window_SizeGadget)

hStatus = CreateStatusBar(#StatusBar, WindowID(#MainWindow))
AddStatusBarField(90)
AddStatusBarField(100)
AddStatusBarField(200)
AddStatusBarField(#PB_Ignore) ; automatically resize this field
StatusBarText(#StatusBar, 0, "First bar field")
StatusBarText(#StatusBar, 1, "Second bar field")

Maxrange=400 
MaxD=Maxrange/64 +1 

hEdit=EditorGadget(#EditorGadget,1,0,WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar)) 
SetGadgetText(#EditorGadget, "Use the slider to resize the text!") 

SendMessage_(hStatus, #SB_GETRECT, 2, StatusRect) ;2 refs the third panel in the statusbar
TrackBarGadget(#TrackBarGadget, StatusRect\left, StatusRect\top, 195, StatusRect\bottom - StatusRect\top * 2, 1, Maxrange )

;for DPI awareness
;TrackBarGadget(#TrackBarGadget, DesktopUnscaledX(StatusRect\left), DesktopUnscaledY(StatusRect\top), DesktopUnscaledX(195), DesktopUnscaledY(StatusRect\bottom - StatusRect\top * 2), 1, Maxrange )

SetParent_(GadgetID(#TrackBarGadget), hStatus)

BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())

Repeat 
  EventID = WaitWindowEvent() 
  If EventID = #PB_Event_Gadget
    Select EventGadget()
        
      Case  #TrackBarGadget 
        sliderValue=GetGadgetState(#TrackBarGadget) 
        If SendMessage_(hEdit,#EM_SETZOOM,sliderValue,MaxD) = #False
          Debug "Error, Cannot set new zooming Range" 
        EndIf
        
    EndSelect
  EndIf 
Until EventID = #PB_Event_CloseWindow 
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Putting a trackbar in a statusbar

Post by RASHAD »

My 2 cents
Simple as I can

Code: Select all

LoadFont(0,"Arial",12,#PB_Font_Bold | #PB_Font_Italic )

If OpenWindow(0, 0, 0, 600, 400, "PureBasic - StatusBar Example", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
 
  CreateStatusBar(0, WindowID(0))
  AddStatusBarField(200)
  AddStatusBarField(200)
  AddStatusBarField(#PB_Ignore )
  
  StatusBarText(0,0,"")
  StatusBarText(0,1,"")
  StatusBarText(0,2,"",#PB_StatusBar_Center)
  
  SendMessage_(StatusBarID(0), #SB_SETMINHEIGHT, 30,0)
  SendMessage_(StatusBarID(0), #WM_SIZE, 0,0)
  
  SendMessage_(StatusBarID(0),#SB_GETRECT,0,r.RECT)
  
  ContainerGadget(0,r\left,r\top,r\right-r\left,r\bottom-r\top)
    TextGadget(10,0,0,r\right-r\left,r\bottom-r\top," Test 4 Status",#SS_CENTER|#SS_CENTERIMAGE)
    SetGadgetColor(10,#PB_Gadget_BackColor,$CCFEFC)
    SetGadgetColor(10,#PB_Gadget_FrontColor,$0000FF)
    SetGadgetFont(10,FontID(0))
  CloseGadgetList()  
  SetParent_(GadgetID(0),StatusBarID(0))
  
  SendMessage_(StatusBarID(0),#SB_GETRECT,1,r.RECT)
  TrackBarGadget(1,r\left,r\top,r\right-r\left,r\bottom-r\top,0,100)
  SetParent_(GadgetID(1),StatusBarID(0))
  
  SendMessage_(StatusBarID(0),#SB_GETRECT,2,r.RECT)
  StringGadget(2,r\left,r\top,r\right-r\left,r\bottom-r\top,"TEST")
  SetParent_(GadgetID(2),StatusBarID(0))
  
  Repeat
   
  Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Egypt my love
dige
Addict
Addict
Posts: 1406
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Putting a trackbar in a statusbar

Post by dige »

Cool stuff! :D Thx
"Daddy, I'll run faster, then it is not so far..."
XCoder
User
User
Posts: 72
Joined: Tue Dec 31, 2013 9:18 pm

Re: Putting a trackbar in a statusbar

Post by XCoder »

Thank you for these alternative solutions.

I see that some of the solutions set the trackbar as a child of the statusbar. I had tried to do this but for some reason it did not work. Unfortunately I did not keep the erroneous code so now I can't see where I was going wrong. Doh! Perhaps I was trying to use SetParent_() in the wrong place in my code.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Putting a trackbar in a statusbar

Post by RASHAD »

Another approach

Code: Select all

LoadFont(0,"Georgia",16,#PB_Font_Bold | #PB_Font_Italic )

If OpenWindow(0, 100, 150, 800, 400, "PureBasic - StatusBar Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered| #PB_Window_SizeGadget)

  If CreateStatusBar(0, WindowID(0))
    AddStatusBarField(750 )
  EndIf
  sbHwnd = StatusBarID(0)
  SendMessage_(sbHwnd, #SB_SETMINHEIGHT, 40, 0)
  SendMessage_(sbHwnd, #WM_SIZE, 0,0)
  UseGadgetList(sbHwnd)
  cont = ContainerGadget(#PB_Any,1,1,600,38)
    TextGadget(0,0,0,200,38," Test 4 Status",#WS_BORDER|#SS_NOTIFY | #SS_CENTER|#SS_CENTERIMAGE)
    GadgetToolTip(0," Current Status ")
    SetGadgetColor(0,#PB_Gadget_BackColor,$CCFEFC)
    SetGadgetColor(0,#PB_Gadget_FrontColor,$0000FF)
    SetGadgetFont(0,FontID(0))
    TrackBarGadget(1,200,0,150,38,0,100)    
    StringGadget(2,350,0,200,38,"TEST")
  CloseGadgetList()
  UseGadgetList(WindowID(0))
  ButtonGadget(10,10,10,80,24,"RUN")
Repeat   
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          Debug GetGadgetState(1)
          
        Case 10
          SetGadgetText(0,"New Text")
      EndSelect
        
  EndSelect
Until Quit = 1
  
EndIf 
Egypt my love
XCoder
User
User
Posts: 72
Joined: Tue Dec 31, 2013 9:18 pm

Re: Putting a trackbar in a statusbar

Post by XCoder »

Thanks, Rashid, for the other approach. This would allow more controls to be added to the statusbar, including a combo box.

I needed to ensure that the trackbar is always on the far right-hand side of the statusbar. I did this by applying the ResizeGadget() function to the trackbar in the procedure SizeWindowHandler() and including a penultimate statusbar field that has the argument #PB_Ignore:

Code: Select all

EnableExplicit

Enumeration
  #MainWindow
  #StatusBar
  #EditorGadget
  #TrackBarGadget
EndEnumeration

#Denominator=4

Global StatusRect.RECT, hEdit, hStatus
Global sliderValue, hTrackBar
Global EventID

Procedure MakeStatusBar()
  Protected hStatus
  hStatus = CreateStatusBar(#StatusBar, WindowID(#MainWindow))
  AddStatusBarField(90)
  StatusBarText(#StatusBar, 0, "First bar field")
  AddStatusBarField(100)
  StatusBarText(#StatusBar, 1, "Second bar field")
  AddStatusBarField(#PB_Ignore) ; automatically resize this field
  AddStatusBarField(200)
  ProcedureReturn hStatus
EndProcedure

Procedure SizeWindowHandler()
  ResizeGadget(#EditorGadget, #PB_Ignore, #PB_Ignore, WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar))
  ResizeGadget(#TrackBarGadget, WindowWidth(#MainWindow)-220, #PB_Ignore, #PB_Ignore, #PB_Ignore)
EndProcedure

OpenWindow(#MainWindow, 100, 200, 600, 400, "Gadget on status bar", #PB_Window_MinimizeGadget| #PB_Window_SizeGadget |#PB_Window_SizeGadget)
   
hStatus = MakeStatusBar()
SendMessage_(hStatus, #SB_GETRECT, 3, StatusRect) ; the number 3 refs the 4th statusbar field

hTrackBar = TrackBarGadget(#TrackBarGadget, WindowWidth(#MainWindow)-220, StatusRect\top, StatusRect\right - StatusRect\left-5, StatusRect\bottom - StatusRect\top * 2, 1, 20 )
SendMessage_(hTrackBar, #TBM_SETPOS, #True, 4)
SendMessage_(hTrackBar, #TBM_SETPAGESIZE, 0, 10)
SetParent_(GadgetID(#TrackBarGadget), hStatus)

hEdit=EditorGadget(#EditorGadget,1,0,WindowWidth(#MainWindow), WindowHeight(#MainWindow)-StatusBarHeight(#StatusBar))
SetGadgetText(#EditorGadget, "Use the slider to resize the text!") 


BindEvent(#PB_Event_SizeWindow, @SizeWindowHandler())

Repeat 
  EventID = WaitWindowEvent() 
  If EventID = #PB_Event_Gadget
    Select EventGadget()
        
      Case  #TrackBarGadget 
        sliderValue=GetGadgetState(#TrackBarGadget) 
        If SendMessage_(hEdit, #EM_SETZOOM, sliderValue, #Denominator) = #False
          Debug "Error, Cannot set new zooming Range" 
        EndIf
        
    EndSelect
  EndIf 
Until EventID = #PB_Event_CloseWindow 


Post Reply