standard pb toolbar with radio and toggle buttons

Share your advanced PureBasic knowledge/code with the community.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

standard pb toolbar with radio and toggle buttons

Post by blueznl »

you have to adapt the following a little, but it shows the concept:

Code: Select all

Structure TBBUTTONINFO
  cbSize.l
  dwMask.l
  idCommand.l
  iImage.l
  fsState.b
  fsStyle.b
  cx.w
  lParam.l
  pszText.l
  cchText.l
EndStructure
;
#TBIF_IMAGE   = $01
#TBIF_TEXT    = $02
#TBIF_STATE   = $04
#TBIF_STYLE   = $08
#TBIF_LPARAM  = $10
#TBIF_COMMAND = $20
#TBIF_SIZE    = $40
#TB_SETBUTTONINFOA = 1024+66

Procedure x_toolbartogglebutton(toolbar_h.l, buttonid.l, image_h.l, state.l)
  ;
  ;  *** add a toggle (check) button to a toolbar
  ;
  ; in:      toolbar_h.l - handle of the toolbar 
  ;          buttonid.l  - buttonid and message send when pressed
  ;          image_h.l   - windows handle of image
  ;          state.l     - 0 not pressed 1 pressed
  ; retval:  none
  ; out:     none
  ;
  ; it's a bit of a kludge :-) first add a regular button
  ; 
  ToolBarImageButton(buttonid,image_h)
  ;
  ; then use sendmessage_() to change its type and status
  ; 
  buttoninfo.TBBUTTONINFO
  buttoninfo\cbSize = SizeOf(buttoninfo)
  buttoninfo\dwMask = #TBIF_STYLE
  buttoninfo\fsStyle = #TBSTYLE_CHECK
  SendMessage_(toolbar_h, #TB_SETBUTTONINFOA, buttonid, @buttoninfo)
  SendMessage_(toolbar_h, #TB_CHECKBUTTON, buttonid, state)
EndProcedure

Procedure x_toolbarradiobutton(toolbar_h.l, buttonid.l, image_h.l, state.l)
  ;
  ; *** add a radio button (group) to a toolbar
  ;
  ; see x_toolbarcheckbutton
  ;
  ToolBarImageButton(buttonid,image_h)
  buttoninfo.TBBUTTONINFO
  buttoninfo\cbSize = SizeOf(buttoninfo)
  buttoninfo\dwMask = #TBIF_STYLE
  buttoninfo\fsStyle = #TBSTYLE_CHECKGROUP
  SendMessage_(toolbar_h, #TB_SETBUTTONINFOA, buttonid, @buttoninfo)
  SendMessage_(toolbar_h, #TB_CHECKBUTTON, buttonid, state)
EndProcedure
now just create a normal toolbar and add buttons... parameters are samples, replace as needed

Code: Select all

tb_main_h = CreateToolBar(#w_main,w_main_whnd)
x_toolbarradiobutton(tb_main_h,#m_main_refresh_0_1,i_icon_0_1_h,0)
x_toolbarradiobutton(tb_main_h,#m_main_refresh_1,i_icon_1_h,1)
x_toolbarradiobutton(tb_main_h,#m_main_refresh_10,i_icon_10_h,0)
x_toolbarradiobutton(tb_main_h,#m_main_refresh_60,i_icon_60_h,0)
ToolBarSeparator()
x_toolbartogglebutton(tb_main_h,#m_main_refresh_no_scroll,i_icon_no_scroll_h,0)
ToolBarImageButton(#m_main_refresh_refresh,i_icon_refresh_h)
ToolBarSeparator()
ToolBarImageButton(#m_main_file_quit,i_icon_exit_h)
i'll add a complete working example if anyone wants it
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

Code: Select all

Procedure x_toolbar_togglebutton(toolbar_h.l,buttonid.l,image_h.l,state.l)
  ;
  ;  *** add a toggle (check) button to a toolbar
  ;
  ; in:      toolbar_h.l - handle of the toolbar 
  ;          buttonid.l  - buttonid and message send when pressed
  ;          image_h.l   - windows handle of image
  ;          state.l     - 0 not pressed 1 pressed
  ; retval:  none
  ; out:     none
  ;
  ; it's a bit of a kludge :-) first add a regular button
  ; 
  ToolBarImageButton(buttonid,image_h)
  ;
  ; then use sendmessage_() to change its type and status
  ; 
  buttoninfo.TBBUTTONINFO
  buttoninfo\cbSize = SizeOf(buttoninfo)
  buttoninfo\dwMask = #TBIF_STYLE
  buttoninfo\fsStyle = #TBSTYLE_CHECK
  SendMessage_(toolbar_h,#TB_SETBUTTONINFOA,buttonid,@buttoninfo)
  SendMessage_(toolbar_h,#TB_CHECKBUTTON,buttonid,state)
EndProcedure

Procedure x_toolbar_radiobutton(toolbar_h.l,buttonid.l,image_h.l,state.l)
  ;
  ; *** add a radio button (group) to a toolbar
  ;
  ; see x_toolbarcheckbutton
  ;
  ToolBarImageButton(buttonid,image_h)
  buttoninfo.TBBUTTONINFO
  buttoninfo\cbSize = SizeOf(buttoninfo)
  buttoninfo\dwMask = #TBIF_STYLE
  buttoninfo\fsStyle = #TBSTYLE_CHECKGROUP
  SendMessage_(toolbar_h,#TB_SETBUTTONINFOA,buttonid,@buttoninfo)
  SendMessage_(toolbar_h,#TB_CHECKBUTTON,buttonid,state)
EndProcedure

Procedure x_toolbar_setbuttonstate(toolbar_h.l,buttonid.l,state.l)
  ;
  ; *** push a button (for example to select a radio button)
  ;
  ; select a button that is 'checked' or 'pressed'
  ; can be used to select one button of a radio group (automatically deselecting other members)
  ; or set value of a toggle button
  ;
  SendMessage_(toolbar_h,#TB_CHECKBUTTON,buttonid,state)
EndProcedure

Procedure.l x_toolbar_getbuttonstate(toolbar_h.l,buttonid.l)
  ProcedureReturn SendMessage_(toolbar_h,#TB_GETSTATE,buttonid,0) & $1
EndProcedure

Procedure x_toolbar_disablebutton(toolbar_h.l,buttonid.l)
  SendMessage_(toolbar_h,#TB_ENABLEBUTTON,buttonid,0)
EndProcedure

Procedure x_toolbar_enablebutton(toolbar_h.l,buttonid.l)
  SendMessage_(toolbar_h,#TB_ENABLEBUTTON,buttonid,1)
EndProcedure
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

Re: standard pb toolbar with radio and toggle buttons

Post by NoahPhense »

blueznl wrote:i'll add a complete working example if anyone wants it
We're suckers for examples.. ;) lets see one

- np
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

you asked for it!

(the additional files for icons and the x_lib can be found via the link below, i've moved the toolbar button functions into the x_lib, don't worry, it's just a regular pb source file, no fancy libraries for me as i'm not good enough 8) )

Code: Select all

; purebasic survival guide - pb3.81 vd3.82
; toolbar_1.pb - 29.03.2004 ejn (blueznl)
; http://www.xs4all.nl/~bluez/datatalk/pure1.htm
;
; - toolbars
; - menus
; - togglebuttons
; - radiobuttons
; - binairy inclusion of icons (made with snicoedit)
; - this is part of something i'm working on, not all code in here makes sense :-)
;
IncludeFile "x_lib.pb"
;
x_init()
;
; enumeration is your best friend! let's use it here to give all menus, windows etc. unique numbers
; any constants / vars starting with w_ deal with windows, m_ are menus, g_ are gadgets
; constant naming reflects place in the window / menu structure
;
Enumeration
  #w_main
  #m_main
  #m_main_file_open
  #m_main_file_remember
  #m_main_file_quit
  #m_main_refresh_0
  #m_main_refresh_1
  #m_main_refresh_2
  #m_main_refresh_3
  #m_main_refresh_no_scroll
  #m_main_refresh_refresh
  #i_icon_refresh
  #i_icon_no_scroll
  #i_icon_exit
  #i_icon_0
  #i_icon_1
  #i_icon_2
  #i_icon_3
EndEnumeration
;
; *** icons (included image data)
;
; icons are small and in this case i want them to be part of the executable, not in an external file
; the image data is stored at the end of the executable, see the labels
; don't forget to 'global' them before using
;
i_icon_refresh_h = CatchImage(#i_icon_refresh, ?i_icon_refresh_data)
i_icon_no_scroll_h = CatchImage(#i_icon_no_scroll, ?i_icon_no_scroll_data)
i_icon_exit_h = CatchImage(#i_icon_exit, ?i_icon_exit_data)
i_icon_0_h = CatchImage(#i_icon_0, ?i_icon_0_data)
i_icon_1_h = CatchImage(#i_icon_1, ?i_icon_1_data)
i_icon_2_h = CatchImage(#i_icon_2, ?i_icon_2_data)
i_icon_3_h = CatchImage(#i_icon_3, ?i_icon_3_data)
;

Procedure main()
  Protected done.l, event.l, event_window.l
  Protected w_main_x.l, w_main_l.l, w_main_h.l, w_main_w.l
  Protected file.s, refresh_speed.l, no_scroll.l
  Global i_icon_refresh_h.l, i_icon_no_scroll_h.l, i_icon_exit_h.l
  Global i_icon_0_h.l, i_icon_1_h.l, i_icon_2_h.l, i_icon_3_h.l
  Global tb_main_h.l
  ;
  ; *** main loop
  ;
  ; some application defaults
  ;
  w_main_x = 100
  w_main_y = 200
  w_main_w = 300
  w_main_h = 300
  file.s = "none"
  refresh_speed = 1
  no_scroll = 0
  ;
  ; ok, let's do a window, toolbar and menu by hand, not using the vd :-) first the window...
  ;
  w_main_whnd.l = OpenWindow(#w_main,w_main_x,w_main_y,w_main_w,w_main_h,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_TitleBar,"Survival Guide - Toolbar 1")
  ;
  ; now a menu
  ;
  CreateMenu(#m_main,w_main_whnd)
  MenuTitle("&File")
  MenuItem(#m_main_file_open,"&Open")
  MenuItem(#m_main_file_remember,"&Remember")
  MenuBar()
  MenuItem(#m_main_file_quit,"&Quit")
  MenuTitle("&Refresh")
  MenuItem(#m_main_refresh_no_scroll,"&No scroll")
  MenuItem(#m_main_refresh_refresh,"&Refresh now")
  MenuBar()
  MenuItem(#m_main_refresh_0,"0.1 sec")
  MenuItem(#m_main_refresh_1,"1 sec")
  MenuItem(#m_main_refresh_2,"10 sec")
  MenuItem(#m_main_refresh_3,"60 sec")
  ;
  ; and a toolbar
  ;
  tb_main_h = CreateToolBar(#w_main,w_main_whnd)
  ;
  ; the help file is a bit misleading regarding the parameters for ToolBarStandardButton and ToolBarImageButton
  ; the first parameter is the message being send, the second parameter the button image
  ; (i wouldn't mind if this stuff would be part of the vd, including data / catch etc.!)
  ;
  ToolBarStandardButton(#m_main_file_open,#PB_ToolBarIcon_Open)
  ToolBarSeparator()
  x_toolbar_radiobutton(tb_main_h,#m_main_refresh_0,i_icon_0_h,0)
  x_toolbar_radiobutton(tb_main_h,#m_main_refresh_1,i_icon_1_h,0)
  x_toolbar_radiobutton(tb_main_h,#m_main_refresh_2,i_icon_2_h,0)
  x_toolbar_radiobutton(tb_main_h,#m_main_refresh_3,i_icon_3_h,0)
  ToolBarSeparator()
  x_toolbar_togglebutton(tb_main_h,#m_main_refresh_no_scroll,i_icon_no_scroll_h,0)
  ToolBarImageButton(#m_main_refresh_refresh,i_icon_refresh_h)
  ToolBarSeparator()
  ToolBarImageButton(#m_main_file_quit,i_icon_exit_h)
  ;
  ; got all the info, now let the toolbar and menu reflect settings
  ;
  If file <> ""
    SetWindowText_(w_main_whnd,"Survival Guide - Toolbar 1: "+file)    ; file being viewed goes into the titlebar
  EndIf
  Select refresh_speed
    Case 0
      x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_0,1)
      SetMenuItemState(#m_main,#m_main_refresh_0,1)
    Case 1
      x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_1,1)
      SetMenuItemState(#m_main,#m_main_refresh_1,1)
    Case 2
      x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_2,1)
      SetMenuItemState(#m_main,#m_main_refresh_2,1)
    Case 3
      x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_3,1)
      SetMenuItemState(#m_main,#m_main_refresh_1,60)
  EndSelect
  x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_refresh,scroll_lock)
  ;
  done.l = #False
  While done = #False
    event = WaitWindowEvent()
    event_window = EventWindowID()
    ; 
    Select event
      Case #PB_EventMenu                            ; *** menu's, toolbars, keyboard shortcuts
        menuid = EventMenuID()
        Select menuid
          Case #m_main_file_quit                    ;     file / quit was selected from the menu
            done = #True
            ;
          Case #m_main_refresh_refresh
            ;
          Case #m_main_refresh_no_scroll
            no_scroll = 1-no_scroll
            x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_no_scroll,no_scroll)
            SetMenuItemState(#m_main,#m_main_refresh_no_scroll,no_scroll)
            ;
          Case #m_main_refresh_0
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,0)
            refresh_speed = 0
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,1)
            x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_0,1)
          Case #m_main_refresh_1
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,0)
            refresh_speed = 1
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,1)
            x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_1,1)
          Case #m_main_refresh_2
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,0)
            refresh_speed = 2
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,1)
            x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_2,1)
          Case #m_main_refresh_3
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,0)
            refresh_speed = 3
            SetMenuItemState(#m_main,#m_main_refresh_0+refresh_speed,1)
            x_toolbar_setbuttonstate(tb_main_h,#m_main_refresh_3,1)
          Default
            ; Debug "menuid: "+Str(menuid)
            ;
        EndSelect
        ;
      Case #PB_EventGadget                          ; *** purebasic gadgets
        ;
      Case #PB_EventCloseWindow                     ; *** windows close buttons
        done = #True                            
        ;
      Case #WM_SIZE
        ;
        ; small bugfix for pb3.81: toolbars are not auto resized, this fixes that...
        ; should be fixed in 3.89+ (?)
        ;
        SendMessage_(tb_main_h, #TB_AUTOSIZE, 0, 0)
        ;        
      Default                                       ; *** any other events
        ; Debug "windows event - event: "+Str(event)
        ;
    EndSelect
  Wend
EndProcedure

main()
End

;
; *** included image data (icons)
;

i_icon_no_scroll_data:
IncludeBinary "pause.ico"

i_icon_exit_data:
IncludeBinary "exit.ico"

i_icon_refresh_data:
IncludeBinary "refresh.ico"

i_icon_0_data:
IncludeBinary "0_1.ico"

i_icon_1_data:
IncludeBinary "1.ico"

i_icon_2_data:
IncludeBinary "10.ico"

i_icon_3_data:
IncludeBinary "60.ico"
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
TerryHough
Enthusiast
Enthusiast
Posts: 781
Joined: Fri Apr 25, 2003 6:51 pm
Location: NC, USA
Contact:

Post by TerryHough »

Hmm...

x_toolbar_radiobutton
doesn't seem to be in the x_lib I just downloaded from your site.

Edited later: Ignore, I jumped into the post at the wrong place and didn't read the first post carefully first.
ebs
Enthusiast
Enthusiast
Posts: 530
Joined: Fri Apr 25, 2003 11:08 pm

Post by ebs »

@blueznl,

Very handy code!

I have one suggestion:
The routines for the ToggleButton and RadioButton are almost identical.
You can combine them into one generic routine and save some code.
You can either call the generic routine directly, or use two "wrapper" routines to make things neater.

Thanks again for the useful code!
Eric

Code: Select all

; generic routine for toggle or radio button
; use ButtonStyle = #TBSTYLE_CHECKGROUP for radio button
; use ButtonStyle = #TBSTYLE_CHECK for toggle button
Procedure ToolBarToggleRadioButton(hToolBar.l, ButtonStyle.l, ButtonID.l, hImage.l, State.l)
  ; add a regular button
  ToolBarImageButton(ButtonID, hImage)
  ; change its type and state
  buttoninfo.TBBUTTONINFO
  buttoninfo\cbSize = SizeOf(buttoninfo)
  buttoninfo\dwMask = #TBIF_STYLE
  buttoninfo\fsStyle = ButtonStyle
  SendMessage_(hToolBar, #TB_SETBUTTONINFOA, ButtonID, @buttoninfo)
  SendMessage_(hToolBar, #TB_CHECKBUTTON, ButtonID, State) 
EndProcedure

; wrapper routine for radio button
Procedure ToolBarRadioButton(hToolBar.l, ButtonID.l, hImage.l, State.l)
  ToolBarToggleRadioButton hToolBar, #TBSTYLE_CHECKGROUP, ButtonID, hImage, State  
EndProcedure

; wrapper routine for toggle button
Procedure ToolBarToggleButton(hToolBar.l, ButtonID.l, hImage.l, State.l)
  ToolBarToggleRadioButton hToolBar, #TBSTYLE_CHECK, ButtonID, hImage, State  
EndProcedure

; you can call the button routine directly, like this...
; two radio buttons
ToolBarToggleRadioButton(tb_main_h, #TBSTYLE_CHECKGROUP, #m_main_refresh_0_1, i_icon_0_1_h, 1)
ToolBarToggleRadioButton(tb_main_h, #TBSTYLE_CHECKGROUP, #m_main_refresh_1, i_icon_0_1_h, 0)
ToolBarSeparator()
; toggle button
ToolBarToggleRadioButton(tb_main_h, #TBSTYLE_CHECK, #m_main_refresh_no_scroll, i_icon_0_1_h, 0)

; ...or you can use the wrapper routines 
; this looks just like blueznl's original code
; two radio buttons
ToolBarRadioButton(tb_main_h, #m_main_refresh_0_1, i_icon_0_1_h, 1)
ToolBarRadioButton(tb_main_h, #m_main_refresh_1, i_icon_0_1_h, 0)
ToolBarSeparator()
; toggle button
ToolBarToggleButton(tb_main_h, #m_main_refresh_no_scroll, i_icon_0_1_h, 0)

User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

terry, i think my isp just put a backup back, i'll refresh the site

should be ok in a few minutes (i'm re-uploading the updated site)

ebs: yeah, i know code in itself is pretty easy once you see it, took me quite some time to figure it out, i choose current naming for the procedures to keep my code readable (even though that's a matter of preference :-))
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
NoahPhense
Addict
Addict
Posts: 1999
Joined: Thu Oct 16, 2003 8:30 pm
Location: North Florida

..

Post by NoahPhense »

Thanks for the code.. very kewl btw.. Will be using it in next project.


- np
halo
Enthusiast
Enthusiast
Posts: 104
Joined: Mon Jan 26, 2004 2:49 am

Post by halo »

Where are the required files? I can't find anything on your site.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6161
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
pantsonhead
User
User
Posts: 39
Joined: Fri Mar 26, 2004 1:47 pm
Location: London, UK
Contact:

Post by pantsonhead »

That's an excellent code snippet.

Thanks blueznl, just what I needed :)
Dare2
Moderator
Moderator
Posts: 3321
Joined: Sat Dec 27, 2003 3:55 am
Location: Great Southern Land

Post by Dare2 »

Thank you. Great stuff.
@}--`--,-- A rose by any other name ..
Post Reply