Chapter 2. Getting Started

Table of Contents

2.1. Hello World in GNU Smalltalk GTK
2.2. Theory of Signals and Callbacks
2.3. Events
2.4. Stepping Through Hello World

To begin our introduction to GNU Smalltalk GTK, we'll start with the simplest program possible. This program (base.st) will create a 200x200 pixel window and has no way of exiting except to be killed by using the shell.

	1	#!/usr/bin/env gst
	2
	3	Eval [
	4		PackageLoader fileInPackage: 'GTK'.
	5		window := GTK.GtkWindow new: GTK.Gtk gtkWindowToplevel.
	6		window show.
	7		GTK.Gtk main
	8	]

You can run the above program using:

  gst base.st

If base.st is made executable and can be found in your PATH, it can be run using:

  base.st

Line 1 will invoke GNU Smalltalk to run base.st in this case. Line 4 loads the package GTK which contains all the classes need for creating GTK widgets. In this case the program creates a new instance of the GtkWindow class and it then invokes the method main to start the GTK+ event processing loop.

A window similar to Figure 2.1, “Simple GNU Smalltalk GTK Window” should popup on your display.

Figure 2.1. Simple GNU Smalltalk GTK Window

Simple GNU Smalltalk GTK Window

The first line allows the program base.st to be invoked from a Linux or Unix shell program assuming that GNU Smalltalk is found your PATH. This line will be the first line in all the example programs.

Lines 4 import the GTK package and initializes the GTK+ environment. The GTK module defines the GNU Smalltalk interfaces to the GTK+ functions that will be used in the program. For those familiar with GTK+ the initialization includes calling the gtk_init() function. This sets up a few things for us such as the default visual and color map, default signal handlers, and checks the arguments passed to your application on the command line, looking for one or more of the following:

It removes these from the argument list, leaving anything it does not recognize for your application to parse or ignore. These are a set of standard arguments accepted by all GTK+ applications.

Line 5 creates a top level window and directs GTK+ to display it (line 6). The GTK.GtkWindow is created in line 11 with the argument GTK.Gtk WINDOW_TOPLEVEL that specifies that we want the window to undergo window manager decoration and placement. Rather than create a window of 0x0 size, a window without children is set to 200x200 by default so you can still manipulate it.

Lines 7 calls the GTK main function that, in turn, invokes the GTK+ main event processing loop to handle mouse and keyboard events as well as window events. When control reaches this point, GTK+ will sleep waiting for X events (such as button or key presses), timeouts, or file IO notifications to occur. In our simple example, however, events are ignored.

2.1. Hello World in GNU Smalltalk GTK

Now for a program with a widget (a button). It's the GNU Smalltalk GTK version of the classic hello world program (helloworld.st ).

	1	#!/usr/bin/env gst
	2
	3	" example helloworld.st"
	4
	5	Eval [
	6		PackageLoader fileInPackage: 'GTK'.
	7	]
	8
	9	Object subclass: HelloWorld [
   10		| button window |
   11
   12		" This is a callback function.
   13		  More on callbacks below. "
   14		hello [
   15   		'Hello World' printNl
   16		]
   17
   18 		delete [
   19     		" If you return false in the 'delete_event' signal handler,
   20       	  GTK will emit the 'destroy' signal. Returning true means
   21       	  you don't want the window to be destroyed.
   22       	  This is useful for popping up 'are you sure you want to quit?'
   23       	  type dialogs. "
   24     		'delete event occurred' printNl.
   25
   26     		" Change false to true and the main window will not be destroyed
   27       	  with a 'delete_event'."
   28     		^ false
   29		]
   30
   31 		destroy [
   32     		'destroy signal occurred' printNl.
   33     		GTK.Gtk mainQuit
   34		]
   35
   36 		show [
   37     		" create a new window "
   38     		window := GTK.GtkWindow new:GTK.Gtk gtkWindowToplevel.
   39 
   40     		" When the window is given the 'delete_event' signal (this is given
   41       	  by the window manager, usually by the 'close' option, or on the
   42       	  titlebar), we ask it to call the delete_event function
   43       	  as defined above. The data passed to the callback
   44       	  function is nil and is ignored in the callback function. "
   45			window connectSignal: 'delete_event' to: self selector: #delete userData: nil.
   46 
   47     		" Here we connect the 'destroy' event to a signal handler.  
   48       	  This event occurs when we call destroy on the window,
   49       	  or if we return false in the 'delete_event' callback. "
   50     		window connectSignal: 'destroy' to: self selector: #destroy userData: nil.
   51 
   52     		" Sets the border width of the window. "
   53     		window setBorderWidth: 10.
   54 
   55     		" Creates a new button with the label 'Hello World'. "
   56     		button := GTK.GtkButton newWithLabel: 'Hello World'.
   57 
   58     		" When the button receives the 'clicked' signal, it will call the
   59       	  function hello passing it None as its argument.  The hello
   60       	  function is defined above. "
   61     		button connectSignal: 'clicked' to: self selector: #hello userData: nil.
   62 
   63     		" This will cause the window to be destroyed by calling
   64       	  destroy when 'clicked'.  Again, the destroy signal could come from
   65       	  here, or the window manager. "
   66     		button connectSignal: 'clicked' to: self selector: #destroy userData: window.
   67 
   68     		" This packs the button into the window (a GTK container). "
   69     		window add: button.
   70 
   71     		" The final step is to display this newly created widget. "
   72     		button show.
   73 
   74     		" and the window "
   75     		window show.
   76		]
   77	].
   78
   79	" If the program is run directly or passed as an argument to the python
   80	  interpreter then create a HelloWorld instance and show it"
   81	Eval [
   82		hello := HelloWorld new.
   83		hello show.
   84 		" All GTK applications must have a GTK.Gtk main. Control ends here
   85   	  and waits for an event to occur (like a key press or mouse event)."
   86 		GTK.Gtk main
   87	]

Figure 2.2, “Hello World Example Program” shows the window created by helloworld.st.

Figure 2.2. Hello World Example Program

Hello World Example Program

The classes and functions that are defined in the GTK package are named as GTK.*. For example, the helloworld.st program uses:

  False
  GTK.Gtk mainquit
  GTK.GtkWindow
  GTK.GtkButton

from the GTK package.