Contents
Vala GTK+ Example
/* GTK+ in Vala sample code */
using GLib;
using Gtk;
public class GtkSample : Gtk.Window {
construct {
this.title = "Sample Window";
this.create_widgets ();
}
public void create_widgets () {
this.destroy += Gtk.main_quit;
var button = new Button.with_label ("Hello World");
button.clicked += btn => {
title = btn.label;
};
add (button);
}
static int main (string[] args) {
Gtk.init (ref args);
var sample = new GtkSample ();
sample.show_all ();
Gtk.main ();
return 0;
}
}
Compile and Run
$ valac --pkg gtk+-2.0 -o gtksample GtkSample.vala $ ./gtksample
GtkTreeView and GtkBuilder Example
This example uses the GtkBuilder API to create the interface from XML declarations. The interface file is attached to this page: main_window.ui
/* GtkTreeView and GtkBuilder in Vala sample code */
using GLib;
using Gtk;
public class BuilderExample : Gtk.Builder {
string uifile = "main_window.ui";
public bool create_widgets () {
try {
add_from_file (uifile);
Gtk.Widget window = (Gtk.Widget) get_object ("window");
setup_treeview ((Gtk.TreeView) get_object ("treeview1"));
window.show_all ();
window.destroy += Gtk.main_quit;
} catch (GLib.Error err) {
var msg = new Gtk.MessageDialog (
null, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.CANCEL,
"Failed to load UI\n" + err.message);
msg.run();
return false;
}
return true;
}
public void setup_treeview (Gtk.TreeView view) {
/* use liststore to hold accountname, accounttype, balance and color attribute */
/* for more info how gtkTreeview works take a look in the GTK API */
var listmodel = new Gtk.ListStore(4, typeof(string), typeof(string), typeof(string), typeof(string));
view.set_model(listmodel);
view.insert_column_with_attributes (-1, "Account Name", new Gtk.CellRendererText(), "text", 0, null);
view.insert_column_with_attributes (-1, "Type", new Gtk.CellRendererText(), "text", 1, null);
var cell = new Gtk.CellRendererText ();
cell.set ("foreground_set", true, null);
view.insert_column_with_attributes (-1, "Balance", cell, "text", 2, "foreground", 3, null);
Gtk.TreeIter iter;
listmodel.append (out iter);
listmodel.set (iter, 0, "My Visacard", 1, "card", 2, "102,10", 3, "red", -1);
listmodel.append (out iter);
listmodel.set (iter, 0, "My Mastercard", 1, "card", 2, "10,20", 3, "red", -1);
}
public static int main (string[] args) {
Gtk.init (ref args);
var mainapp = new BuilderExample ();
if (mainapp.create_widgets ()) {
Gtk.main ();
}
return 0;
}
}
Compile and Run
$ valac --pkg gtk+-2.0 -o builderexample BuilderExample.vala $ ./builderexample
(A more complete example can be found at my SVN repo at http://svn.tielie.com/filedetails.php?repname=repos+1&path=%2Ftestapps%2Ftestgio%2Ftestgio.vala&rev=0&sc=0")
GtkFileChooser subclass example
/* Custom FileChooserDialog in Vala sample code */
using GLib;
using Gtk;
class OpenFileDialog : Gtk.FileChooserDialog {
public static string? CWD = null;
construct {
this.set_title ("Open file");
this.set_action (FileChooserAction.OPEN);
this.add_button (STOCK_CANCEL, ResponseType.CANCEL);
this.add_button (STOCK_OPEN, ResponseType.OK);
this.set_default_response (ResponseType.OK);
if (CWD != null) {
this.set_current_folder (CWD);
}
}
public override void response (int resp) {
if ((ResponseType) resp == ResponseType.OK) {
CWD = this.get_current_folder ();
}
}
public static void main (string[] args) {
Gtk.init (ref args);
for (int i = 0; i < 2; i++) {
var ofd = new OpenFileDialog ();
if (ofd.run () == ResponseType.OK) {
stdout.printf ("filename = %s\n".printf (ofd.get_filename ()));
}
ofd.destroy ();
}
}
}
Compile and Run
$ valac --pkg gtk+-2.0 -o openfiledialog OpenFileDialog.vala $ ./openfiledialog
Custom GtkWidget example
//
// Johan Dahlin 2008
//
// A quite simple Gtk.Widget subclass which demonstrates how to subclass
// and do realizing, sizing and drawing. Based on widget.py in PyGTK
//
using GLib;
using Gtk;
using Cairo;
public class ValaWidget : Gtk.Widget {
private static const string text = "Hello World!\n";
private static const int _BORDER_WIDTH = 10;
private Pango.Layout _layout;
construct {
this._layout = this.create_pango_layout (ValaWidget.text);
}
// The realize method is responsible for creating GDK (windowing system)
// resources. In this example we will create a new gdk.Window which we
// then draw on
public override void realize ()
{
// First set an internal flag telling that we're realized
this.set_flags (Gtk.WidgetFlags.REALIZED);
// Create a new gdk.Window which we can draw on.
// Also say that we want to receive exposure events by setting
// the event_mask
var attrs = Gdk.WindowAttr ();
attrs.window_type = Gdk.WindowType.CHILD;
attrs.width = this.allocation.width;
attrs.wclass = Gdk.WindowClass.INPUT_OUTPUT;
attrs.event_mask = this.get_events() | Gdk.EventMask.EXPOSURE_MASK;
this.window = new Gdk.Window (this.get_parent_window (), attrs, 0);
// Associate the gdk.Window with ourselves, Gtk+ needs a reference
// between the widget and the gdk window
this.window.set_user_data (this);
// Attach the style to the gdk.Window, a style contains colors and
// GC contextes used for drawing
this.style = this.style.attach (this.window);
// The default color of the background should be what
// the style (theme engine) tells us.
this.style.set_background (this.window, Gtk.StateType.NORMAL);
this.window.move_resize (this.allocation.x, this.allocation.y,
this.allocation.width, this.allocation.height);
}
// The unrealized method is responsible for freeing the GDK resources
public override void unrealize ()
{
// De-associate the window we created in realize with ourselves
this.window.set_user_data (null);
}
// The size_request method Gtk+ is calling on a widget to ask
// it the widget how large it wishes to be. It's not guaranteed
// that gtk+ will actually give this size to the widget
public override void size_request (Gtk.Requisition requisition)
{
int width, height;
// In this case, we say that we want to be as big as the
// text is, plus a little border around it.
this._layout.get_size (out width, out height);
requisition.width = width / Pango.SCALE + this._BORDER_WIDTH*4;
requisition.height = height / Pango.SCALE + this._BORDER_WIDTH*4;
}
// The size_allocate is called by when the actual size is known
// and the widget is told how much space could actually be allocated
public override void size_allocate (Gdk.Rectangle allocation)
{
// Save the allocated space
this.allocation = (Gtk.Allocation)allocation;
// If we're realized, move and resize the window to the
// requested coordinates/positions
if ((this.get_flags () & Gtk.WidgetFlags.REALIZED) == 0)
return;
this.window.move_resize (this.allocation.x, this.allocation.y,
this.allocation.width, this.allocation.height);
}
// The do_expose_event is called when the widget is asked to draw itself
// Remember that this will be called a lot of times, so it's usually
// a good idea to write this code as optimized as it can be, don't
// Create any resources in here.
public override bool expose_event (Gdk.EventExpose event)
{
// In this example, draw a rectangle in the foreground color
var cr = Gdk.cairo_create (this.window);
Gdk.cairo_set_source_color (cr, this.style.fg[this.state]);
cr.rectangle (this._BORDER_WIDTH,
this._BORDER_WIDTH,
this.allocation.width - 2*this._BORDER_WIDTH,
this.allocation.height - 2*this._BORDER_WIDTH);
cr.set_line_width (5.0);
cr.set_line_join (Cairo.LineJoin.ROUND);
cr.stroke ();
// And draw the text in the middle of the allocated space
int fontw, fonth;
this._layout.get_pixel_size (out fontw, out fonth);
cr.move_to ((this.allocation.width - fontw)/2,
(this.allocation.height - fonth)/2);
Pango.cairo_update_layout (cr, this._layout);
Pango.cairo_show_layout (cr, this._layout);
return true;
}
static int main (string[] args) {
Gtk.init (ref args);
Gtk.Window win = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
win.set_border_width (5);
win.set_title ("Widget test");
win.destroy += Gtk.main_quit;
Gtk.Frame frame = new Gtk.Frame ("Example Vala Widget");
win.add (frame);
ValaWidget w = new ValaWidget ();
frame.add (w);
win.show_all ();
Gtk.main ();
return 0;
}
}
Compile and Run
$ valac --pkg gtk+-2.0 -o valawidget ValaWidget.vala $ ./valawidget
