3.2. An Upgraded Hello World

    1	#!/usr/bin/env gst
    2
    3	" example helloworld.st"
    4
    5	Eval [
    6		PackageLoader fileInPackage: 'GTK'.
    7	]
    8
    9	Object subclass: HelloWorld2 [
   10		| box1 button1 button2 window |
   11
   12		" Our new improved callback.  The data passed to this method
   13		  is printed to stdout. "
   14		hello: aWidget string: aString [
   15			('Hello again - ', aString, ' was pressed') printNl
   16		]
   17
   18		" another callback "
   19		delete: aWidget event: aGdkEvent [
   20			GTK.Gtk mainQuit.
   21			^ false
   22		]
   23
   24		show [
   25			" create a new window "
   26			window := GTK.GtkWindow new:GTK.Gtk gtkWindowToplevel.
   27
   28			" This is a new call, which just sets the title of our
   29			  new window to 'Hello Buttons!' "
   30			window setTitle: 'Hello Buttons!'.
   31 
   32			" Here we just set a handler for delete_event that immediately
   33			  exits GTK. "
   34			window connectSignal: 'delete_event' to: self selector: #delete:event: userData: nil.
   35 
   36			" Sets the border width of the window. "
   37			window setBorderWidth: 10.
   38
   39			" We create a box to pack widgets into.  This is described in detail
   40			  in the 'packing' section. The box is not really visible, it
   41			  is just used as a tool to arrange widgets. "
   42			box1 := GTK.GtkHBox new: false spacing: 0.
   43     
   44			" Put the box into the main window. "
   45			window add: box1.
   46
   47			" Creates a new button with the label 'Hello World'. "
   48			button1 := GTK.GtkButton newWithLabel: 'Hello World'.
   49 
   50			" When the button receives the 'clicked' signal, it will call the
   51			  function hello passing it None as its argument.  The hello
   52			  function is defined above. "
   53			button1 connectSignal: 'clicked' to: self selector: #hello:string: userData: 'button 1'.
   54 
   55			" Instead of add, we pack this button into the invisible
   56			  box, which has been packed into the window. "
   57			box1 packStart: button1 expand: true fill: true padding: 0.
   58
   59			" Always remember this step, this tells GTK that our preparation for
   60			  this button is complete, and it can now be displayed. "
   61			button1 show.
   62
   63			" Do these same steps again to create a second button "
   64			button2 := GTK.GtkButton newWithLabel: 'Button 2'.
   65
   66			" Call the same callback method with a different argument,
   67			  passing a pointer to 'button 2' instead. "
   68			button2 connectSignal: 'clicked' to: self selector: #hello:string: userData: 'button 2'.
   69
   70			box1 packStart: button2 expand: true fill: true padding: 0.
   71
   72			" The order in which we show the buttons is not really important, but I
   73			  recommend showing the window last, so it all pops up at once. "
   74			button2 show.
   75			box1 show.
   76			window show.
   77		]
   78	].
   79
   80	Eval [
   81		hello := HelloWorld2 new.
   82		hello show.
   83		GTK.Gtk main
   84	]

Running helloworld2.st produces the window illustrated in Figure 3.1, “Upgraded Hello World Example”.

Figure 3.1. Upgraded Hello World Example

Upgraded Hello World Example

You'll notice this time there is no easy way to exit the program, you have to use your window manager or command line to kill it. A good exercise for the reader would be to insert a third "Quit" button that will exit the program. You may also wish to play with the options to packStart:expand:fill:padding: while reading the next section. Try resizing the window, and observe the behavior.

A short commentary on the code differences from the first helloworld program is in order.

As noted above there is no "destroy" event handler in the upgraded helloworld.

Lines 14-16 define a callback method which is similar to the hello callback in the first helloworld. The difference is that the callback prints a message including data passed in.

Line 30 sets a title string to be used on the titlebar of the window (see Figure 3.1, “Upgraded Hello World Example”).

Line 42 creates a horizontal box (GTK.GtkHBox) to hold the two buttons that are created in lines 48 and 64. Line 45 adds the horizontal box to the window container.

Lines 53 and 68 connect the callback method to the "clicked" signal of the buttons. Each button sets up a different string to be passed to the callback method when invoked.

Lines 57 and 70 pack the buttons into the horizontal box. Lines 74 and 76 ask GTK to display the buttons.

Lines 81-82 ask GTK to display the box and the window respectively.