Monday, April 15, 2013

Layout management in Ruby GTK

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

No comments:

Post a Comment