Toolbar once more ...

Just starting out? Need help? Post your questions and find answers here.
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Toolbar once more ...

Post by kpeters58 »

I can disable toolbar buttons with DisbleToolbarButton, but apparently one cannot (as far as the PB help goes) query that state.

GetToolbarButtonState only queries the buttons current toggle state.


Is there really no cross-platform way to get that info? Am not interested in a pure Windows solution.
PB 5.73 on Windows 10 & OS X High Sierra
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: Toolbar once more ...

Post by wombats »

macOS:

Code: Select all

EnableExplicit

Procedure ToolbarButtonEnabled(Toolbar, Item)
  Protected state
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_MacOS
      Protected ItemArray, ToolbarItem
      ItemArray = CocoaMessage(0, ToolBarID(Toolbar), "items")
      ToolbarItem = CocoaMessage(0, ItemArray, "objectAtIndex:", item)
      state = CocoaMessage(0, ToolbarItem, "isEnabled")
  CompilerEndSelect
  ProcedureReturn state
EndProcedure

OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

TextGadget(0, 10, 10, WindowWidth(0) - 20, 25, "")
TextGadget(1, 10, 30, WindowWidth(0) - 20, 25, "")
TextGadget(2, 10, 50, WindowWidth(0) - 20, 25, "")

CreateImage(0, 16, 16)
StartDrawing(ImageOutput(0))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(0, 0, 255))
StopDrawing()

CreateImage(1, 16, 16)
StartDrawing(ImageOutput(1))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(255, 0, 0))
StopDrawing()

CreateImage(2, 16, 16)
StartDrawing(ImageOutput(2))
Box(0, 0, OutputWidth(), OutputHeight(), RGB(0, 255, 0))
StopDrawing()

CreateToolBar(0, WindowID(0))

ToolBarImageButton(0, ImageID(0))
ToolBarImageButton(1, ImageID(1))
ToolBarImageButton(2, ImageID(2))

DisableToolBarButton(0, 1, 1)

Define i
For i = 0 To 2
  If ToolbarButtonEnabled(0, i)
    SetGadgetText(i, "Item " + Str(i) + " is enabled.")
  Else
    SetGadgetText(i, "Item " + Str(i) + " is disabled.")
  EndIf
Next

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Last edited by wombats on Sat Mar 09, 2019 12:16 am, edited 1 time in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Toolbar once more ...

Post by RASHAD »

Cross platform

Code: Select all

UsePNGImageDecoder()

Global Dim TBS(10)

Procedure _DisableToolBarButton(TB,button,state)
  DisableToolBarButton(TB,button,state)
  If state = 1
    TBS(button) = 1
  Else
    TBS(button) = 0
  EndIf
EndProcedure

Procedure _GetToolBarButtonState(TB,button)
  If TBS(button) = 1
    Debug "Button "+Str(button)+" : Disabled"
  Else
    Debug "Button "+Str(button)+" : Enabled"
  EndIf
EndProcedure

If OpenWindow(0, 100, 200, 195, 260, "ToolBar example", #PB_Window_SystemMenu | #PB_Window_SizeGadget)

  If CreateToolBar(0, WindowID(0))
    ToolBarImageButton(0, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/New.png"))
    ToolBarImageButton(1, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Open.png"))
    ToolBarImageButton(2, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Save.png"))
    
    ToolBarSeparator()

    ToolBarImageButton(3, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Cut.png"))
    ToolBarToolTip(0, 3, "Cut")
    
    ToolBarImageButton(4, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Copy.png"))
    ToolBarToolTip(0, 4, "Copy")
    
    ToolBarImageButton(5, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Paste.png"))
    ToolBarToolTip(0, 5, "Paste")
    
    ToolBarSeparator()

    ToolBarImageButton(6, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Find.png"))
    ToolBarToolTip(0, 6, "Find a document")
  EndIf

  If CreateMenu(0, WindowID(0))
    MenuTitle("Project")
      MenuItem(0, "New")
      MenuItem(1, "Open")
      MenuItem(2, "Save")
  EndIf
  
  _DisableToolBarButton(0, 2, 1) ; Disable the button '2'
  _GetToolBarButtonState(0,1)
  _GetToolBarButtonState(0,2)
    
  Repeat
    Event = WaitWindowEvent()

    Select Event
    
      Case #PB_Event_Menu
        MessageRequester("Information", "ToolBar or Menu ID: "+Str(EventMenu()), 0)
      
      Case #PB_Event_CloseWindow  ; If the user has pressed on the close button
        Quit = 1
        
    EndSelect

  Until Quit = 1
  
EndIf

End   ; All resources are automatically freed
   
Egypt my love
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Re: Toolbar once more ...

Post by kpeters58 »

That can pass as an acceptable workaround...

Thanks again, Rashad!
PB 5.73 on Windows 10 & OS X High Sierra
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Toolbar once more ...

Post by RASHAD »

Welcome :)

Code: Select all

UsePNGImageDecoder()

Global Dim TBS(10)

Macro MyDisableToolBarButton(TB,button,state)
  DisableToolBarButton(TB,button,state)
  TBS(button) = state
EndMacro

Macro GetToolBarButtonState(TB,button)
  If TBS(button) = 1
    Debug "Button "+Str(button)+" : Disabled"
  Else
    Debug "Button "+Str(button)+" : Enabled"
  EndIf
EndMacro

If OpenWindow(0, 100, 200, 195, 260, "ToolBar example", #PB_Window_SystemMenu | #PB_Window_SizeGadget)

  If CreateToolBar(0, WindowID(0))
    ToolBarImageButton(0, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/New.png"))
    ToolBarImageButton(1, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Open.png"))
    ToolBarImageButton(2, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Save.png"))
    
    ToolBarSeparator()

    ToolBarImageButton(3, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Cut.png"))
    ToolBarToolTip(0, 3, "Cut")
    
    ToolBarImageButton(4, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Copy.png"))
    ToolBarToolTip(0, 4, "Copy")
    
    ToolBarImageButton(5, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Paste.png"))
    ToolBarToolTip(0, 5, "Paste")
    
    ToolBarSeparator()

    ToolBarImageButton(6, LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/ToolBar/Find.png"))
    ToolBarToolTip(0, 6, "Find a document")
  EndIf

  If CreateMenu(0, WindowID(0))
    MenuTitle("Project")
      MenuItem(0, "New")
      MenuItem(1, "Open")
      MenuItem(2, "Save")
  EndIf
  
  MyDisableToolBarButton(0, 2, 1) ; Disable the button '2'
  GetToolBarButtonState(0,1)
  GetToolBarButtonState(0,2)
    
  Repeat
    Event = WaitWindowEvent()

    Select Event
    
      Case #PB_Event_Menu
        MessageRequester("Information", "ToolBar or Menu ID: "+Str(EventMenu()), 0)
      
      Case #PB_Event_CloseWindow  ; If the user has pressed on the close button
        Quit = 1
        
    EndSelect

  Until Quit = 1
  
EndIf

End   ; All resources are automatically freed
   
Egypt my love
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Toolbar once more ...

Post by Shardik »

While RASHAD's examples work truely cross-platform, you always have to take care for a correctly dimensioned array to contain the button states. I have therefore taken wombat's MacOS API solution with additional CompilerCase parts and the respective API codes for Linux (currently works only with Gtk3!) and Windows. I have tested my example successfully with PB 5.46 in ASCII and Unicode mode on these operating systems:
- Linux Mint 18.3 Sylvia x64 with Cinnamon
- MacOS 10.13.6 'High Sierra'
- Windows 7 SP1 x64

Code: Select all

EnableExplicit

UsePNGImageDecoder()

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
    gtk_widget_is_sensitive(*Widget.GtkWidget)
  EndImport
CompilerEndIf

Define i.I

Procedure IsToolBarButtonEnabled(ToolBarID.I, ButtonIndex.I)
  CompilerSelect #PB_Compiler_OS
    CompilerCase #PB_OS_Linux
      Protected *ToolItem.GtkToolItem
      *ToolItem = gtk_toolbar_get_nth_item_(ToolBarID(ToolBarID), ButtonIndex)
      ProcedureReturn gtk_widget_is_sensitive(*ToolItem)
    CompilerCase #PB_OS_Windows
      Protected ButtonInfo.TBBUTTON
      SendMessage_(ToolBarID(ToolBarID), #TB_GETBUTTON, ButtonIndex,
        @ButtonInfo)
      ProcedureReturn (ButtonInfo\fsState & #TBSTATE_ENABLED) >> 2
    CompilerCase #PB_OS_MacOS
      Protected ItemArray.I
      Protected ToolbarItem.I
      ItemArray = CocoaMessage(0, ToolBarID(ToolbarID), "items")
      ToolbarItem = CocoaMessage(0, ItemArray, "objectAtIndex:", ButtonIndex)
      ProcedureReturn CocoaMessage(0, ToolbarItem, "isEnabled")
  CompilerEndSelect
EndProcedure

OpenWindow(0, 200, 100, 200, 70, "ToolBar example")

If CreateToolBar(0, WindowID(0))
  ToolBarImageButton(0, LoadImage(0, #PB_Compiler_Home +
    "examples/sources/Data/ToolBar/New.png"))
  ToolBarImageButton(1, LoadImage(0, #PB_Compiler_Home +
    "examples/sources/Data/ToolBar/Open.png"))
  ToolBarImageButton(2, LoadImage(0, #PB_Compiler_Home +
    "examples/sources/Data/ToolBar/Save.png"))
EndIf

; ----- Disable 2nd ToolBar button
DisableToolBarButton(0, 1, #True)

; ----- Display ToolBar button states
For i = 0 To 2
  Debug "ToolBar button " + Str(i) + ": " + IsToolBarButtonEnabled(0, i)
Next i

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      Debug "ToolBar button " + Str(EventMenu()) + " was pressed"
  EndSelect
ForEver
Oma
Enthusiast
Enthusiast
Posts: 312
Joined: Thu Jun 26, 2014 9:17 am
Location: Germany

Re: Toolbar once more ...

Post by Oma »

Thanks all.
Under Linux it should work even from Gtk2.18.
I just tested it on Gtk2.24.32.
PureBasic 5.4-5.7, Linux: (X/L/K)Ubuntus+Mint - Windows XP (32Bit)
PureBasic Linux-API-Library & Viewer: http://www.chabba.de
User avatar
Shardik
Addict
Addict
Posts: 2058
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Toolbar once more ...

Post by Shardik »

Oma wrote:Under Linux it should work even from Gtk2.18.
I just tested it on Gtk2.24.32.
RASHAD's non-API example works with GTK 2 and 3. My API example doesn't work with GTK 2.24.30 on Linux Mint 18.3 'Sylvia' with PB 5.46. And this is not caused by the GTK framework but by PureBasic 5.46 because PureBasic changed the underlying gadgets in the ToolBar for GTK 3. You may check this with my ToolBar widget mapper. In GTK 2 PureBasic utilizes a GtkButton and in GTK 3 a GtkToolButton instead of the GtkButton. Therefore when using GTK 2, PureBasic 5.46 displays the following warning and error and the detection of the toolbar button state doesn't work:
PureBasic 5.46 IDE with subsystem gtk2 wrote:Gtk (WARNING): Mixing deprecated and non-deprecated GtkToolbar API is not allowed
Gtk (Critical): IS_gtk_widget_is_sensitive: assertion 'GTK_IS_WIDGET (widget)' failed
These are the underlying GTK widgets in PureBasic 5.46:
GTK 2
Image

GTK 3
Image

But you are right for PureBasic 5.70. In PureBasic 5.70 the GTK 2 subsystem was changed to utilize GtkToolButton instead of GtkButton, so in PureBasic 5.70 the widget mapper displays the same structure for GTK 2 and GTK 3... :wink:
wombats
Enthusiast
Enthusiast
Posts: 716
Joined: Thu Dec 29, 2011 5:03 pm

Re: Toolbar once more ...

Post by wombats »

Thanks for covering GTK and Windows, Shardik. I tried to do it with the Qt subsystem, but I can't see a way for QtScript() to access the toolbar items.
Post Reply