Layout management

In this chapter we will show how to lay out our widgets in windows or dialogs.

When we design the GUI of our application, we decide what widgets we will use and how we will organize those widgets in the application. To organize our widgets, we use specialized non visible widgets called layout containers. In this chapter, we will mention Alignment, Fixed, VBox and Table.

Fixed

The Fixed container places child widgets at fixed positions and with fixed sizes. This container performs no automatic layout management. In most applications, we don't use this container. There are some specialized areas, where we use it. For example games, specialized applications that work with diagrams, resizable components that can be moved (like a chart in a spreadsheet application), small educational examples.

' ZetCode Mono Visual Basic GTK# tutorial
'
' In this program, we lay out widgets
' using absolute positioning
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk

 
Public Class GtkVBApp
    Inherits Window

    Private Dim rotunda As Gdk.Pixbuf 
    Private Dim bardejov As Gdk.Pixbuf 
    Private Dim mincol As Gdk.Pixbuf
   
    Public Sub New
        
        MyBase.New("Fixed")
        
        Me.InitUI
        
        Me.SetDefaultSize(300, 280)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll 
        
    End Sub
    
    Private Sub InitUI
    
        Me.ModifyBg(StateType.Normal, New Gdk.Color(40, 40, 40))
        
        Try 
            bardejov = New Gdk.Pixbuf("bardejov.jpg")
            rotunda = New Gdk.Pixbuf("rotunda.jpg")
            mincol = New Gdk.Pixbuf("mincol.jpg")
        Catch e As Exception
            Console.WriteLine("Cannot load images")
            Console.WriteLine(e.Message)
            Environment.Exit(1)
        End Try
        
        Dim image1 As New Image(bardejov)
        Dim image2 As New Image(rotunda)
        Dim image3 As New Image(mincol)
        
        Dim fixed As New Fixed
        
        fixed.Put(image1, 20, 20)
        fixed.Put(image2, 40, 160)
        fixed.Put(image3, 170, 50)
  
        Me.Add(fixed)

    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

In our example, we show three small images on the window. We explicitly specify the x, y coordinates, where we place these images.

vbnc -r:/usr/lib/mono/gtk-sharp-2.0/gtk-sharp.dll -r:/usr/lib/mono/gtk-sharp-2.0/gdk-sharp.dll 
      absolute.vb

We also use the gdk-sharp assembly in this example.

Me.ModifyBg(StateType.Normal, New Gdk.Color(40, 40, 40))

For better visual experience, we change the background color to dark gray.

bardejov = New Gdk.Pixbuf("bardejov.jpg")

We load the image from the disk to the Gdk.Pixbuf object.

Dim image1 As New Image(bardejov)
Dim image2 As New Image(rotunda)
Dim image3 As New Image(mincol)

The Image is a widget that is used to display images. It takes Gdk.Pixbuf object in the constructor.

Dim fixed As New Fixed

We create the Fixed container.

fixed.Put(image1, 20, 20)

We place the first image at x=20, y=20 coordinates.

Me.Add(fixed)

Finally, we add the Fixed container to the Window.

Fixed
Figure: Fixed

Buttons

The Alignment container controls the alignment and the size of its child widget.

' ZetCode Mono Visual Basic GTK# tutorial
'
' In this program, we position two buttons
' in the bottom right corner of the window.
' We use horizontal and vertical boxes.
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk


Public Class GtkVBApp
    Inherits Window
   
    Public Sub New
        
        MyBase.New("Buttons")
        
        Me.InitUI
        
        Me.SetDefaultSize(260, 150)
        Me.SetPosition(WindowPosition.Center)
        AddHandler Me.DeleteEvent, AddressOf Me.OnDelete

        Me.ShowAll
        
    End Sub
    
    Private Sub InitUI
    
        Dim vbox As New VBox(False, 5)
        Dim hbox As New HBox(True, 3)
        
        Dim valign As New Alignment(0, 1, 0, 0)
        vbox.PackStart(valign)
        
        Dim ok As New Button("OK")
        ok.SetSizeRequest(70, 30)
        Dim close As New Button("Close")
        
        hbox.Add(ok)
        hbox.Add(close)
        
        Dim halign As New Alignment(1, 0, 0, 0)
        halign.Add(hbox)
        
        vbox.PackStart(halign, False, False, 3)

        Me.Add(vbox)

    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

In the code example, we place two buttons into the right bottom corner of the window. To accomplish this, we use one horizontal box and one vertical box and two alignment containers.

Dim valign As New Alignment(0, 1, 0, 0)

This will put the child widget to the bottom.

vbox.PackStart(valign)

Here we place the Alignment widget into the vertical box.

Dim hbox As New HBox(True, 3)
...
Dim ok As New Button("OK")
ok.SetSizeRequest(70, 30)
Dim close As New Button("Close")
 
hbox.Add(ok)
hbox.Add(close)

We create a horizontal box and put two buttons inside it.

Dim halign As New Alignment(1, 0, 0, 0)
halign.Add(hbox)

vbox.PackStart(halign, False, False, 3)

This will create an alignment container that will place its child widget to the right. We add the horizontal box into the alignment container and pack the alignment container into the vertical box. We must keep in mind that the alignment container takes only one child widget. That's why we must use boxes.

Buttons
Figure: Buttons

Calculator skeleton

The Table widget arranges widgets in rows and columns.

' ZetCode Mono Visual Basic GTK# tutorial
'
' In this program we create a skeleton of
' a calculator. We use the Table widget. 
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk

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

        Me.ShowAll 
        
    End Sub
    
    Private Sub InitUI
    
        Dim vbox As New VBox(False, 2)
        
        Dim mb As New MenuBar
        Dim filemenu As New Menu
        Dim file As MenuItem = New MenuItem("File")
        file.Submenu = filemenu
        mb.Append(file)

        vbox.PackStart(mb, False, False, 0)

        Dim table As New Table(5, 4, True)

        table.Attach(New Button("Cls"), 0, 1, 0, 1)
        table.Attach(New Button("Bck"), 1, 2, 0, 1)
        table.Attach(New Label(), 2, 3, 0, 1)
        table.Attach(New Button("Close"), 3, 4, 0, 1)

        table.Attach(New Button("7"), 0, 1, 1, 2)
        table.Attach(New Button("8"), 1, 2, 1, 2)
        table.Attach(New Button("9"), 2, 3, 1, 2)
        table.Attach(New Button("/"), 3, 4, 1, 2)

        table.Attach(New Button("4"), 0, 1, 2, 3)
        table.Attach(New Button("5"), 1, 2, 2, 3)
        table.Attach(New Button("6"), 2, 3, 2, 3)
        table.Attach(New Button("*"), 3, 4, 2, 3)

        table.Attach(New Button("1"), 0, 1, 3, 4)
        table.Attach(New Button("2"), 1, 2, 3, 4)
        table.Attach(New Button("3"), 2, 3, 3, 4)
        table.Attach(New Button("-"), 3, 4, 3, 4)

        table.Attach(New Button("0"), 0, 1, 4, 5)
        table.Attach(New Button("."), 1, 2, 4, 5)
        table.Attach(New Button("="), 2, 3, 4, 5)
        table.Attach(New Button("+"), 3, 4, 4, 5)

        vbox.PackStart(New Entry, False, False, 0)
        
        vbox.PackEnd(table, True, True, 0)
        
        Me.Add(vbox)

    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

We use the Table widget to create a calculator skeleton.

Dim table As New Table(5, 4, True)

We create a table widget with 5 rows and 4 columns. The third parameter is the homogenous parameter. If set to true, all the widgets in the table are of same size. The size of all widgets is equal to the largest widget in the table container.

table.Attach(New Button("Cls"), 0, 1, 0, 1)

We attach a button to the table container. To the top-left cell of the table. The first two parameters are the left and right sides of the cell, the last two parameters are the top and left sides of the cell.

vbox.PackEnd(table, True, True, 0)

We pack the table widget into the vertical box.

Calculator skeleton
Figure: Calculator skeleton

Windows

Next we will create a more advanced example. We show a window, that can be found in the JDeveloper IDE.

' ZetCode Mono Visual Basic GTK# tutorial
'
' This is a more complicated layout example.
' We use Alignment and Table widgets. 
'
' author jan bodnar
' last modified May 2009
' website www.zetcode.com


Imports Gtk

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

        Me.ShowAll 
        
    End Sub
    
    Private Sub InitUI
    
        Me.BorderWidth = 15
        
        Dim table As New Table(8, 4, False)
        table.ColumnSpacing = 3

        Dim title As New Label("Windows")

        Dim halign As New Alignment(0, 0, 0, 0)
        halign.Add(title)
        
        table.Attach(halign, 0, 1, 0, 1, AttachOptions.Fill, _
            AttachOptions.Fill, 0, 0)
            
        Dim frame As New Frame
        table.Attach(frame, 0, 2, 1, 3, AttachOptions.Fill Or AttachOptions.Expand, _
            AttachOptions.Fill Or AttachOptions.Expand, 1, 1)

        Dim activate As New Button("Activate")
        activate.SetSizeRequest(50, 30)
        table.Attach(activate, 3, 4, 1, 2, AttachOptions.Fill, _
            AttachOptions.Shrink, 1, 1)
        
        Dim valign As New Alignment(0, 0, 0, 0)
        Dim close As New Button("Close")
        close.SetSizeRequest(70, 30)
        valign.Add(close)
        table.SetRowSpacing(1, 3)
        table.Attach(valign, 3, 4, 2, 3, AttachOptions.Fill, _
            AttachOptions.Fill Or AttachOptions.Expand, 1, 1)
            
        Dim halign2 As New Alignment(0, 1, 0, 0)
        Dim help As New Button("Help")
        help.SetSizeRequest(70, 30)
        halign2.Add(help)
        table.SetRowSpacing(3, 6)
        table.Attach(halign2, 0, 1, 4, 5, AttachOptions.Fill, _
            AttachOptions.Fill, 0, 0)
        
        Dim ok As New Button("OK")
        ok.SetSizeRequest(70, 30)
        table.Attach(ok, 3, 4, 4, 5, AttachOptions.Fill, _
            AttachOptions.Fill, 0, 0)
                          
        Me.Add(table)

    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 code example shows, how we can create a similar window in GTK#.

Dim table As New Table(8, 4, False)
table.ColumnSpacing = 3

The example is based on the Table container. There will be 3px space between columns.

Dim title As New Label("Windows")

Dim halign As New Alignment(0, 0, 0, 0)
halign.Add(title)

table.Attach(halign, 0, 1, 0, 1, AttachOptions.Fill, _
    AttachOptions.Fill, 0, 0)

This code creates a label that is aligned to the left. The label is placed in the first row of the Table container.

Dim frame As New Frame
table.Attach(frame, 0, 2, 1, 3, AttachOptions.Fill Or AttachOptions.Expand, _
    AttachOptions.Fill Or AttachOptions.Expand, 1, 1)

The frame view widget spans two rows and two columns. We make the widget non editable and hide the cursor.

Dim valign As New Alignment(0, 0, 0, 0)
Dim close As New Button("Close")
close.SetSizeRequest(70, 30)
valign.Add(close)
table.SetRowSpacing(1, 3)
table.Attach(valign, 3, 4, 2, 3, AttachOptions.Fill, _
    AttachOptions.Fill Or AttachOptions.Expand, 1, 1)

We put the close button next to the frame widget into the fourth column. (we count from zero) We add the button into the alignment widget, so that we can align it to the top.

Windows
Figure: Windows

In this part of the Visual Basic GTK# tutorial, we mentioned layout management of widgets.