Monday, April 15, 2013

Menus And toolbars in Ruby GTK

Menus And toolbars

In this part of the Ruby 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 you have to remember all those 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.
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a simple menu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

def initialize
super

set_title "Simple menu"
signal_connect "destroy" do
Gtk.main_quit
end

init_ui

set_default_size 250, 200
set_window_position Gtk::Window::POS_CENTER

show_all
end

def init_ui

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

mb = Gtk::MenuBar.new

filemenu = Gtk::Menu.new
filem = Gtk::MenuItem.new "File"
filem.set_submenu filemenu

exit = Gtk::MenuItem.new "Exit"
exit.signal_connect "activate" do
Gtk.main_quit
end

filemenu.append exit

mb.append filem

vbox = Gtk::VBox.new false, 2
vbox.pack_start mb, false, false, 0

add vbox
end
end

Gtk.init
window = RubyApp.new
Gtk.main
This is a small example with minimal menubar functionality.
mb = Gtk::MenuBar.new
MenuBar widget is created. This is a container for the menus.
filemenu = Gtk::Menu.new
filem = Gtk::MenuItem.new "File"
filem.set_submenu filemenu
Toplevel MenuItem is created.
exit = Gtk::MenuItem.new "Exit"
exit.signal_connect "activate" do
Gtk.main_quit
end

filemenu.append exit
Exit MenuItem is created and appended to the File MenuItem.
mb.append filem
Toplevel MenuItem is appended to the MenuBarwidget.
vbox = Gtk::VBox.new false, 2
vbox.pack_start 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.
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a submenu
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

def initialize
super

set_title "Submenu"
signal_connect "destroy" do
Gtk.main_quit
end

init_ui

set_default_size 250, 200
set_window_position Gtk::Window::POS_CENTER

show_all
end

def init_ui

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

mb = Gtk::MenuBar.new

filemenu = Gtk::Menu.new
filem = Gtk::MenuItem.new "File"
filem.set_submenu filemenu

mb.append filem

imenu = Gtk::Menu.new

importm = Gtk::MenuItem.new "Import"
importm.set_submenu imenu

inews = Gtk::MenuItem.new "Import news feed..."
ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
imail = Gtk::MenuItem.new "Import mail..."

imenu.append inews
imenu.append ibookmarks
imenu.append imail

filemenu.append importm

exit = Gtk::MenuItem.new "Exit"
exit.signal_connect "activate" do
Gtk.main_quit
end

filemenu.append exit

vbox = Gtk::VBox.new false, 2
vbox.pack_start mb, false, false, 0

add vbox
end
end

Gtk.init
window = RubyApp.new
Gtk.main
Submenu creation.
imenu = Gtk::Menu.new
A submenu is a Menu.
importm = Gtk::MenuItem.new "Import"
importm.set_submenu imenu
It is a submenu of a menu item, which belogs to toplevel file menu.
inews = Gtk::MenuItem.new "Import news feed..."
ibookmarks = Gtk::MenuItem.new "Import bookmarks..."
imail = Gtk::MenuItem.new "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.
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a menu with
# images, accelerators and a separator
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

def initialize
super

set_title "Image menu"
signal_connect "destroy" do
Gtk.main_quit
end

init_ui

set_default_size 250, 200
set_window_position Gtk::Window::POS_CENTER

show_all
end

def init_ui

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

mb = Gtk::MenuBar.new

filemenu = Gtk::Menu.new
filem = Gtk::MenuItem.new "File"
filem.set_submenu filemenu

agr = Gtk::AccelGroup.new
add_accel_group agr

newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
key, mod = Gtk::Accelerator.parse "N"
newi.add_accelerator("activate", agr, key,
mod, Gtk::ACCEL_VISIBLE)
filemenu.append newi

openm = Gtk::ImageMenuItem.new Gtk::Stock::OPEN, agr
key, mod = Gtk::Accelerator.parse "O"
openm.add_accelerator("activate", agr, key,
mod, Gtk::ACCEL_VISIBLE)
filemenu.append openm

sep = Gtk::SeparatorMenuItem.new
filemenu.append sep

exit = Gtk::ImageMenuItem.new Gtk::Stock::QUIT, agr
key, mod = Gtk::Accelerator.parse "Q"
exit.add_accelerator("activate", agr, key,
mod, Gtk::ACCEL_VISIBLE)

exit.signal_connect "activate" do
Gtk.main_quit
end
filemenu.append exit

mb.append filem

vbox = Gtk::VBox.new false, 2
vbox.pack_start mb, false, false, 0

add vbox
end
end

Gtk.init
window = RubyApp.new
Gtk.main
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.
agr = Gtk::AccelGroup.new
add_accel_group agr
To work with accelerators, we create a global AccelGroupobject. It will be used later.
newi = Gtk::ImageMenuItem.new Gtk::Stock::NEW, agr
key, mod = Gtk::Accelerator.parse "N"
newi.add_accelerator("activate", agr, key,
mod, Gtk::ACCEL_VISIBLE)
filemenu.append newi
ImageMenuItem is created. The image comes from the stock of images. We create also a Ctrl+N accelerator.
sep = Gtk::SeparatorMenuItem.new
filemenu.append sep
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.
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows a toolbar
# widget
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window

def initialize
super

set_title "Toolbar"
signal_connect "destroy" do
Gtk.main_quit
end

init_ui

set_default_size 250, 200
set_window_position Gtk::Window::POS_CENTER

show_all
end

def init_ui

toolbar = Gtk::Toolbar.new
toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

newtb = Gtk::ToolButton.new Gtk::Stock::NEW
opentb = Gtk::ToolButton.new Gtk::Stock::OPEN
savetb = Gtk::ToolButton.new Gtk::Stock::SAVE
sep = Gtk::SeparatorToolItem.new
quittb = Gtk::ToolButton.new Gtk::Stock::QUIT

toolbar.insert 0, newtb
toolbar.insert 1, opentb
toolbar.insert 2, savetb
toolbar.insert 3, sep
toolbar.insert 4, quittb

quittb.signal_connect "clicked" do
Gtk.main_quit
end

vbox = Gtk::VBox.new false, 2
vbox.pack_start toolbar, false, false, 0

add(vbox)
end
end

Gtk.init
window = RubyApp.new
Gtk.main

The example shows a toolbar and four tool buttons.
toolbar = Gtk::Toolbar.new
A Toolbar widget is created.
toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS
On toolbar, we show only icons. No text.
newtb = Gtk::ToolButton.new Gtk::Stock::NEW
A ToolButton with an image from stock is created. The image comes from the built-in stock of images.
sep = Gtk::SeparatorToolItem.new
This is a separator. It can be used to put toolbar buttons into logical groups.
toolbar.insert 0, newtb
toolbar.insert 1, opentb
...
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.
#!/usr/bin/ruby

# ZetCode Ruby GTK tutorial
#
# This example shows how to
# activate/deactivate a ToolButton
#
# author: jan bodnar
# website: www.zetcode.com
# last modified: June 2009

require 'gtk2'


class RubyApp < Gtk::Window


def initialize
super

set_title "Undo redo"
signal_connect "destroy" do
Gtk.main_quit
end

@count = 2

init_ui

set_default_size 250, 200
set_window_position Gtk::Window::POS_CENTER

show_all
end

def init_ui

toolbar = Gtk::Toolbar.new
toolbar.set_toolbar_style Gtk::Toolbar::Style::ICONS

@undo = Gtk::ToolButton.new Gtk::Stock::UNDO
@redo = Gtk::ToolButton.new Gtk::Stock::REDO
sep = Gtk::SeparatorToolItem.new
quit = Gtk::ToolButton.new Gtk::Stock::QUIT

toolbar.insert 0, @undo
toolbar.insert 1, @redo
toolbar.insert 2, sep
toolbar.insert 3, quit

@undo.signal_connect "clicked" do
on_undo
end

@redo.signal_connect "clicked" do
on_redo
end

quit.signal_connect "clicked" do
Gtk.main_quit
end

vbox = Gtk::VBox.new false, 2
vbox.pack_start toolbar, false, false, 0

self.add vbox

end

def on_undo

@count = @count - 1

if @count <= 0
@undo.set_sensitive false
@redo.set_sensitive true
end
end


def on_redo
@count = @count + 1

if @count >= 5
@redo.set_sensitive false
@undo.set_sensitive true
end
end
end

Gtk.init
window = RubyApp.new
Gtk.main
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.
@count = 2
The @count variable decides, which button is activated or deactivated.
@undo = Gtk::ToolButton.new Gtk::Stock::UNDO
@redo = Gtk::ToolButton.new Gtk::Stock::REDO
We have two tool buttons. Undo and redo tool buttons. Images come from the stock resources.
@undo.signal_connect "clicked" do
on_undo
end
Clicking on the undo button, we trigger the on_undo method.
if @count <= 0
@undo.set_sensitive false
@redo.set_sensitive true
end
To activate or deactivate a widget, we use the set_sensitive method
Undo redo
Figure: Undo redo
In this chapter of the Ruby GTK tutorial, we showed, how to work with menus & toolbars.

No comments:

Post a Comment