Home  Contents

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.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# In this program, we lay out widgets
# using absolute positioning
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Fixed"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 300, 280
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)
               
        begin       
            bardejov = Gdk::Pixbuf.new "bardejov.jpg"
            rotunda = Gdk::Pixbuf.new "rotunda.jpg"
            mincol = Gdk::Pixbuf.new "mincol.jpg"
        rescue IOError => e
            puts e
            puts "cannot load images"
            exit
        end
        
        image1 = Gtk::Image.new bardejov
        image2 = Gtk::Image.new rotunda
        image3 = Gtk::Image.new mincol
        
        fixed = Gtk::Fixed.new
        
        fixed.put image1, 20, 20
        fixed.put image2, 40, 160
        fixed.put image3, 170, 50
  
        add fixed
        
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

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

 modify_bg Gtk::STATE_NORMAL, Gdk::Color.new(6400, 6400, 6440)

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

 bardejov = Gdk::Pixbuf.new "bardejov.jpg"

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

 image1 = Gtk::Image.new bardejov
 image2 = Gtk::Image.new rotunda
 image3 = Gtk::Image.new mincol

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

 fixed = Gtk::Fixed.new

We create the Fixed container.

 fixed.put image1, 20, 20

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

 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.


#!/usr/bin/ruby

# ZetCode Ruby 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
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Buttons"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 260, 150
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        vbox = Gtk::VBox.new false, 5
        hbox = Gtk::HBox.new true, 3
        
        valign = Gtk::Alignment.new 0, 1, 0, 0
        vbox.pack_start valign
        
        ok = Gtk::Button.new "OK"
        ok.set_size_request 70, 30
        close = Gtk::Button.new "Close"
        
        hbox.add ok
        hbox.add close
        
        halign = Gtk::Alignment.new 1, 0, 0, 0
        halign.add hbox
        
        vbox.pack_start halign, false, false, 3

        add vbox
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

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.

 valign = Gtk::Alignment.new 0, 1, 0, 0

This will put the child widget to the bottom.

 vbox.pack_start valign

Here we place the Alignment widget into the vertical box.

 hbox = Gtk::HBox.new true, 3 
 ...
 ok = Gtk::Button.new "OK"
 ok.set_size_request 70, 30
 close = Gtk::Button.new "Close"
  
 hbox.add ok
 hbox.add close

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

 halign = Gtk::Alignment.new 1, 0, 0, 0
 halign.add hbox

 vbox.pack_start 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.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# In this program we create a skeleton of
# a calculator. We use the Table widget. 
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Calculator"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 300, 250
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        vbox = Gtk::VBox.new false, 2
        
        mb = Gtk::MenuBar.new
        filemenu = Gtk::Menu.new
        file = Gtk::MenuItem.new "File"
        file.set_submenu filemenu
        mb.append file

        vbox.pack_start mb, false, false, 0

        table = Gtk::Table.new 5, 4, true

        table.attach Gtk::Button.new("Cls"), 0, 1, 0, 1
        table.attach Gtk::Button.new("Bck"), 1, 2, 0, 1
        table.attach Gtk::Label.new, 2, 3, 0, 1
        table.attach Gtk::Button.new("Close"), 3, 4, 0, 1

        table.attach Gtk::Button.new("7"), 0, 1, 1, 2
        table.attach Gtk::Button.new("8"), 1, 2, 1, 2
        table.attach Gtk::Button.new("9"), 2, 3, 1, 2
        table.attach Gtk::Button.new("/"), 3, 4, 1, 2

        table.attach Gtk::Button.new("4"), 0, 1, 2, 3
        table.attach Gtk::Button.new("5"), 1, 2, 2, 3
        table.attach Gtk::Button.new("6"), 2, 3, 2, 3
        table.attach Gtk::Button.new("*"), 3, 4, 2, 3

        table.attach Gtk::Button.new("1"), 0, 1, 3, 4
        table.attach Gtk::Button.new("2"), 1, 2, 3, 4
        table.attach Gtk::Button.new("3"), 2, 3, 3, 4
        table.attach Gtk::Button.new("-"), 3, 4, 3, 4

        table.attach Gtk::Button.new("0"), 0, 1, 4, 5
        table.attach Gtk::Button.new("."), 1, 2, 4, 5
        table.attach Gtk::Button.new("="), 2, 3, 4, 5
        table.attach Gtk::Button.new("+"), 3, 4, 4, 5

        vbox.pack_start Gtk::Entry.new, false, false, 0
        
        vbox.pack_end table, true, true, 0
        
        add vbox

    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

We use the Table widget to create a calculator skeleton.

 table = Gtk::Table.new 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 Gtk::Button.new("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.pack_end 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.


#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This is a more complicated layout example.
# We use Alignment and Table widgets. 
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

    def initialize
        super
    
        set_title "Windows"
        signal_connect "destroy" do 
            Gtk.main_quit 
        end
        
        init_ui

        set_default_size 300, 250
        set_window_position Gtk::Window::POS_CENTER
        
        show_all
    end
    
    def init_ui
    
        set_border_width 15
        
        table = Gtk::Table.new 8, 4, false
        table.set_column_spacings 3

        title = Gtk::Label.new "Windows"

        halign = Gtk::Alignment.new 0, 0, 0, 0
        halign.add title
        
        table.attach(halign, 0, 1, 0, 1, Gtk::FILL,
            Gtk::FILL, 0, 0)
            
        frame = Gtk::Frame.new
        table.attach(frame, 0, 2, 1, 3, Gtk::FILL | Gtk::EXPAND,
            Gtk::FILL | Gtk::EXPAND, 1, 1)

        activate = Gtk::Button.new "Activate"
        activate.set_size_request 50, 30
        table.attach(activate, 3, 4, 1, 2, Gtk::FILL,
            Gtk::SHRINK, 1, 1)
        
        valign = Gtk::Alignment.new 0, 0, 0, 0
        close = Gtk::Button.new "Close"
        close.set_size_request 70, 30
        valign.add close
        table.set_row_spacing 1, 3
        table.attach(valign, 3, 4, 2, 3, Gtk::FILL,
            Gtk::FILL | Gtk::EXPAND, 1, 1)
            
        halign2 = Gtk::Alignment.new 0, 1, 0, 0
        help = Gtk::Button.new "Help"
        help.set_size_request 70, 30
        halign2.add help
        table.set_row_spacing 3, 6
        table.attach(halign2, 0, 1, 4, 5, Gtk::FILL,
            Gtk::FILL, 0, 0)
        
        ok = Gtk::Button.new "OK"
        ok.set_size_request 70, 30
        table.attach(ok, 3, 4, 4, 5, Gtk::FILL,
            Gtk::FILL, 0, 0)
                          
        add table
    end
end

Gtk.init
    window = RubyApp.new
Gtk.main

The code example shows, how we can create a similar window in Ruby GTK.

 table = Gtk::Table.new 8, 4, false
 table.set_column_spacings 3

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

 title = Gtk::Label.new "Windows"

 halign = Gtk::Alignment.new 0, 0, 0, 0
 halign.add title

 table.attach(halign, 0, 1, 0, 1, Gtk::FILL,
     Gtk::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.

 frame = Gtk::Frame.new
 table.attach(frame, 0, 2, 1, 3, Gtk::FILL | Gtk::EXPAND,
     Gtk::FILL | Gtk::EXPAND, 1, 1)

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

 valign = Gtk::Alignment.new 0, 0, 0, 0
 close = Gtk::Button.new "Close"
 close.set_size_request 70, 30
 valign.add close
 table.set_row_spacing 1, 3
 table.attach(valign, 3, 4, 2, 3, Gtk::FILL,
     Gtk::FILL | Gtk::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 Ruby GTK tutorial, we mentioned layout management of widgets.