Menus & toolbars

In this part of the Visual Basic GTK# programming tutorial, we will work with menus & toolbars.

A menubar is one of the most common parts of the GUI application. It is a group of commands located in various menus. While in console applications we have to remember many arcane commands, here we have most of the commands grouped into logical parts. These are accepted standards that further reduce the amount of time spending to learn a new application.

Simple menu

In our first example, we will create a menubar with one file menu. The menu will have only one menu item. By selecting the item the application quits.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This program shows a simple
' menu. It has one action, which
' will terminate the program, when
' selected. 
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports Gtk


Public Class GtkVBApp
    Inherits Window
 
    Public Sub New
        
        MyBase.New("Simple menu")
        
        Me.InitUI
        
        Me.SetDefaultSize(250, 200)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
    
        Dim mb As New MenuBar

        Dim filemenu As New Menu
        Dim fileItem As New MenuItem("File")
        fileItem.Submenu = filemenu
       
        Dim exitItem As New MenuItem("Exit")
        AddHandler exitItem.Activated, AddressOf Me.OnActivated
        filemenu.Append(exitItem)

        mb.Append(fileItem)

        Dim vbox As New VBox(False, 2)
        vbox.PackStart(mb, False, False, 0)

        Me.Add(vbox)

    End Sub
    
    Sub OnActivated(ByVal sender As Object, _ 
            ByVal args As EventArgs)
        Application.Quit
    End Sub
   
    Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class

This is a small example with minimal menubar functionality.

Dim mb As New MenuBar

MenuBar widget is created. This is a container for the menus.

Dim filemenu As New Menu
Dim fileItem As New MenuItem("File")
fileItem.Submenu = filemenu

Toplevel MenuItem is created.

Dim exitItem As New MenuItem("Exit")
AddHandler exitItem.Activated, AddressOf Me.OnActivated
filemenu.Append(exitItem)

Exit MenuItem is created and appended to the File MenuItem.

mb.Append(fileItem)

Toplevel MenuItem is appended to the MenuBar widget.

Dim vbox As New VBox(False, 2)
vbox.PackStart(mb, False, False, 0)

Unlike in other toolkits, we have to take care of the layout management of the menubar ourselves. We put the menubar into the vertical box.

Simple menu
Figure: Simple menu

Submenu

Our final example demonstrates how to create a submenu in GTK#.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This program creates a submenu
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports Gtk


Public Class GtkVBApp
    Inherits Window
 
    Public Sub New
        
        MyBase.New("Submenu")
        
        Me.InitUI
        
        Me.SetDefaultSize(250, 200)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll    
        
    End Sub
    
    Private Sub InitUI
    
        Dim mb As New MenuBar

        Dim filemenu As New Menu
        Dim ifile As New MenuItem("File")
        ifile.Submenu = filemenu

        // submenu creation
        Dim imenu As New Menu

        Dim iimport As New MenuItem("Import")
        iimport.Submenu = imenu

        Dim inews As New MenuItem("Import news feed...")
        Dim ibookmarks As New MenuItem("Import bookmarks...")
        Dim imail As New MenuItem("Import mail...")

        imenu.Append(inews)
        imenu.Append(ibookmarks)
        imenu.Append(imail)

        // exit menu item
        Dim iexit As New MenuItem("Exit")
        AddHandler iexit.Activated, AddressOf Me.OnActivated

        filemenu.Append(iimport)
        filemenu.Append(iexit)
        mb.Append(ifile)

        Dim vbox As New VBox(False, 2)
        vbox.PackStart(mb, False, False, 0)
        
        Me.Add(vbox)

    End Sub
    
    Sub OnActivated(ByVal sender As Object, _
            ByVal args As EventArgs)
        Application.Quit
    End Sub
   
    Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class

Submenu creation.

Dim imenu As New Menu

A submenu is a Menu.

Dim iimport As New MenuItem("Import")
iimport.Submenu = imenu

It is a submenu of a menu item, which belogs to toplevel file menu.

Dim inews As New MenuItem("Import news feed...")
Dim ibookmarks As New MenuItem("Import bookmarks...")
Dim imail As New MenuItem("Import mail...")

imenu.Append(inews)
imenu.Append(ibookmarks)
imenu.Append(imail)

Submenu has its own menu items.

Submenu
Figure: Submenu

Image menu

In the next example, we will further explore the menus. We will add images and accelerators to our menu items. Accelerators are keyboard shortcuts for activating a menu item.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This program shows image
' menu items, a shorcut and a separator
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
 
    Public Sub New
        
        MyBase.New("Image menu")
        
        Me.InitUI
        
        Me.SetDefaultSize(250, 200)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
    
        Dim mb As New MenuBar

        Dim filemenu As New Menu
        Dim ifile As New MenuItem("File")
        ifile.Submenu = filemenu
       
        Dim agr As New AccelGroup
        Me.AddAccelGroup(agr)

        Dim inew As New ImageMenuItem("gtk-new", agr)
        filemenu.Append(inew)
        
        Dim iopen As New ImageMenuItem(Stock.Open, agr)
        filemenu.Append(iopen)

        Dim isep As New SeparatorMenuItem
        filemenu.Append(isep)

        Dim iexit As New ImageMenuItem(Stock.Quit, agr)
        AddHandler iexit.Activated, AddressOf Me.OnActivated
        filemenu.Append(iexit)

        mb.Append(ifile)

        Dim vbox As New VBox(False, 2)
        vbox.PackStart(mb, False, False, 0)
               
        Me.Add(vbox)

    End Sub
    
    Sub OnActivated(ByVal sender As Object, _
            ByVal args As EventArgs)
        Application.Quit
    End Sub
   
    Sub OnDelete(ByVal sender As Object, _ 
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class

Our example shows a toplevel menu item with three sublevel menu items. Each of the menu items has a image and an accelerator. The accelerator for the quit menu item is active.

Dim agr As New AccelGroup
Me.AddAccelGroup(agr)

To work with accelerators, we create a global AccelGroup object. It will be used later.

Dim inew As New ImageMenuItem("gtk-new", agr)
filemenu.Append(inew)

ImageMenuItem is created. The image comes from the stock of images. There is a bug in the GTK#. The Stock.New clashes with the Visual Basic New keyword.

Dim isep As New SeparatorMenuItem
filemenu.Append(isep)

These lines create a separator. It is used to put menu items into logical groups.

Image menu
Figure: Image menu

Menus group commands that we can use in application. Toolbars provide a quick access to the most frequently used commands.

Simple toolbar

Next we create a simple toolbar.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This program creates a 
' toolbar
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports Gtk

 
Public Class GtkVBApp
    Inherits Window
 
    Public Sub New
        
        MyBase.New("Toolbar")
        
        Me.InitUI
        
        Me.SetDefaultSize(250, 200)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
    
        Dim toolbar As New Toolbar
        toolbar.ToolbarStyle = ToolbarStyle.Icons

        Dim newtb As New ToolButton("gtk-new")
        Dim opentb As New ToolButton(Stock.Open)
        Dim savetb As New ToolButton(Stock.Save)
        Dim sep As New SeparatorToolItem
        Dim quittb As New ToolButton(Stock.Quit)

        toolbar.Insert(newtb, 0)
        toolbar.Insert(opentb, 1)
        toolbar.Insert(savetb, 2)
        toolbar.Insert(sep, 3)
        toolbar.Insert(quittb, 4)

        AddHandler quittb.Clicked, AddressOf Me.OnClicked
         
        Dim vbox As New VBox(False, 2)
        vbox.PackStart(toolbar, False, False, 0)

        Me.Add(vbox)

    End Sub
    
    Sub OnClicked(ByVal sender As Object, _
            ByVal args As EventArgs)
        Application.Quit
    End Sub
   
    Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class

The example shows a toolbar and four tool buttons.

Dim toolbar As New Toolbar

A Toolbar widget is created.

toolbar.ToolbarStyle = ToolbarStyle.Icons

On toolbar, we show only icons. No text.

Dim opentb As New ToolButton(Stock.Open)

A ToolButton with an image from stock is created.

Dim sep As New SeparatorToolItem 

This is a separator. It can be used to put toolbar buttons into logical groups.

toolbar.Insert(newtb, 0)
toolbar.Insert(opentb, 1)
...

Toolbar buttons are inserted into the toolbar widget.

Toolbar
Figure: Toolbar

Undo redo

The following example demonstrates, how we can deactivate toolbar buttons on the toolbar. It is a common practise in GUI programming. For example the save button. If we save all changes of our document to the disk, the save button is deactivated in most text editors. This way the application indicates to the user, that all changes are already saved.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This program disables/enables
' toolbuttons on a toolbar
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com

Imports Gtk
 
Public Class GtkVBApp
    Inherits Window
 
    Private Dim clicks As Integer = 2
    Private Dim undo As ToolButton
    Private Dim redo As ToolButton
 
    Public Sub New
        
        MyBase.New("Undo redo")
        
        Me.InitUI
        
        Me.SetDefaultSize(250, 200)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
    
        Dim toolbar As New Toolbar
        toolbar.ToolbarStyle = ToolbarStyle.Icons

        undo = New ToolButton(Stock.Undo)
        undo.Label = "Undo"
        redo = New ToolButton(Stock.Redo)
        redo.Label = "Redo"
        
        Dim sep As New SeparatorToolItem
        Dim quit As New ToolButton(Stock.Quit)

        toolbar.Insert(undo, 0)
        toolbar.Insert(redo, 1)
        toolbar.Insert(sep, 2)
        toolbar.Insert(quit, 3)

        AddHandler undo.Clicked, AddressOf Me.OnCount
        AddHandler redo.Clicked, AddressOf Me.OnCount
        AddHandler quit.Clicked, AddressOf Me.OnClicked
         
        Dim vbox As New VBox(False, 2)
        vbox.PackStart(toolbar, False, False, 0)

        Me.Add(vbox)

    End Sub
    
    Private Sub OnCount(ByVal sender As Object, _
            ByVal args As EventArgs)
        
        If "Undo".Equals(sender.Label)
            clicks += 1
        Else 
            clicks -= 1
        End If
  
        If clicks <= 0 
            undo.Sensitive = True
            redo.Sensitive = False
        End If

        If clicks >= 5 
            undo.Sensitive = False
            redo.Sensitive = True
        End If
       
    End Sub
    
    Sub OnClicked(ByVal sender As Object, _
            ByVal args As EventArgs)
        Application.Quit
    End Sub
   
    Sub OnDelete(ByVal sender As Object, _
            ByVal args As DeleteEventArgs)
        Application.Quit
    End Sub

    Public Shared Sub Main
    
        Application.Init
        Dim app As New GtkVBApp
        Application.Run
        
    End Sub
 
End Class

Our example creates undo and redo buttons from the GTK# stock resources. After several clicks each of the buttons is deactivated. The buttons are grayed out.

Private Dim clicks As Integer = 2

The clicks variable decides, which button is activated or deactivated.

undo = New ToolButton(Stock.Undo)
undo.Label = "Undo"
redo = New ToolButton(Stock.Redo)
redo.Label = "Redo"

We have two tool buttons. Undo and redo tool buttons. Images come from the stock resources.

AddHandler undo.Clicked, AddressOf Me.OnCount
AddHandler redo.Clicked, AddressOf Me.OnCount

We plug a method for the Clicked event for both tool buttons.

If clicks <= 0 
    undo.Sensitive = True
    redo.Sensitive = False
End If

To activate a widget, we set its Sensitive property to true. To deactivate it, we set it to false.

Undo redo
Figure: Undo redo

In this chapter of the Visual Basic GTK# tutorial we showed how to work with menus & toolbars.