GtkRoutines.e contains a large sequence named 'control' which contains method prototypes for each of 240+ controls.
Controls (a.k.a. 'widgets') are created by class: <create(GtkWindow)> for example, where GtkWindow is a class.
An enumerated list of all control classes appears at the top of GtkRoutines.e, and they are the same as those used by the GTK docs. These class names are the ONLY ones you can send to the create() function. Never try numbers or strings. Spelling counts. Don't put them in quotes!
Methods can be one of three types: (1) create, (2) set, or (3) get.
constant win = create(GtkWindow)Parameters which follow the class name vary, and are usually optional. See the demo programs and the GTK docs.
set(win,"title","My Program") set(win,"Border Width",10) set(win,"default size",300,200)The type and number of parameters must be determined by looking at the GTK documentation.
Supplying too many parameters, like:
set(win,"title","My Program", "well isn't that swell?",1,2,3)won't usually cause any problem, the excess parameters are discarded. You'll get an error message if you get silly and try to send more than 10.
Too few parameters may cause problems, because unfilled values default to zero:
set(win,"default size")will set the window size to 0x0, i.e: nothing, which will make it kinda hard to see! No error message to help out in this case.
Mismatched parameter types will usually give an error message, but sometimes a crash. Again, read the GTK docs!
get(win,"title") -- returns a string if title was set, 0 otherwise
get(win,"Border Width") -- returns integer
get(win,"default size") -- returns sequence {x,y} e.g: {300,200}
Sending the wrong number of parameters to the get() function will
very likely cause problems! Usually a machine-level exception.
Fortunately, this is easy to avoid, as there normally AREN'T ANY
parameters, just the handle & the property.
A few commonly-used functions have simpler ways to call them:
set(win,"add",panel) = add(win,panel) set(win,"show all") = show_all(win)These shortcuts also allow you to send {lists} of items to the function, rather than calling the routine over and over, once for each item. For example:
add(panel,{img1,btn1,btn2,btn3})
or
add(panel,btnarray) -- where btnarray could be a list of handles to any number of objects, of mixed types
GTK provides a pack_start and a pack_end function, I've combined these into one:
pack(panel,btn1) -- pack (top to bottom, or left to right) or pack(panel,-btn1) -- the neg. sign means "pack at end/bottom of container"
There are some GTK controls which have multiple ways to create or set them. An example would be an image, which can be created from:
EuGTK tries to figure out which you want by examining the param you send to it:
constant img = create(GtkImage) --it seems you want an empty container which can hold an image --at a later time. constant img = create(GtkImage,"~/demos/thumbnails/BabyTux.jpg") -- looks like you want to create this from the file named, if -- such file exists. If not, you'll get a 'broken' image. constant img = create(GtkImage,"gtk-ok",GTK_ICON_SIZE_DIALOG) -- looks like you want a stock image, in the size given.For creating other, less-often-used images from types such as Pixbuf, try creating an 'empty' image, and then, as a separate step, setting it.
This also applies to GtkButtons and a few other controls.
connect(win,"destroy","Quit")where win is the handle, "destroy" [ALWAYS A STRING] is a signal, a.k.a. the name of an event. "Quit" is what to do in that event: call function Quit which is built-in to EuGTK.
BTW, if you do not specify this for your program's main window, GTK may keep on plugging away in the background, even after all the windows are closed, using up memory and processor cycles. You don't want this!
The built-in "Quit" function ends your program and shuts down the GTK processing loop. Most other connections will be made to Euphoria functions YOU will write. Any Euphoria function used for this purpose must be:
You often do not need to type a new line of code to connect an object to a signal, the commonly-used ones have a way to do that within the 'create()' line:
(A) constant btn1 = create(GtkButton,"gtk-ok","Foo")
(B) constant btn1 = create(GtkButton,"gtk-ok",call_back(routine_id("Foo")),42)
where you are making a new button with the stock OK image, connecting it to
your Euphoria function Foo(), and (optionally) sending the integer 42 along
as the data parameter to that function.
You can only pass integers or pointers as the data item, not strings or floating point numbers. (See Data passing below for other ways to pass data from controls to your functions.)
Your Foo() function could look like this:
global function Foo(atom ctl, atom data)ctl will be filled in with the handle of the control (btn1) which dispatched the call, and data will be the integer sent by that control (42), or null if left blank.
- BUT - if you plan to compile your program, then
The link by call_back(routine_id()) method (B) is the only one which will work. Something about late binding or whatever...
You can also connect controls to signals by typing a separate line:
constant btn1 = create(GtkButton,"gtk-ok")
connect(btn1,"clicked",call_back(routine_id("Foo")),42)
Where 'clicked' is a signal that the button can respond to. See GTK docs.
Note that you can connect more than one signal.. they will be
executed in order. See test108 for an example.
If you find that you need to be able to disconnect a signal, use this method, but save the signal_id:
integer sigid = connect(btn1,"clicked",....)then later, you can disconnect the signal by calling:
disconnect(btn1,sigid)Note: do not use this to disable a control, because it does not change the appearance to show that the control is disabled. For that, use
set(btn1,"sensitive",FALSE)
For more flexibility, you can use each control's "data" space to pass info. This uses a kind of associative list, storing name/value pairs. For example:
constant btn = create(GtkButton...
set(btn,"data","flavor","Apple") -- (1)
set(btn,"data","price","3.99") -- (2)
global function Foo(atom ctl)
sequence pie = get(ctl,"data","flavor")
atom price = to_number(get(ctl,"data","price"))
printf(1,"%s pie is $%2.2f",{pie,price})
return 1
end function
==> Apple pie is $3.99
(1) Where "flavor" is a variable name of your choice, and "Apple" is the dataAnother way, especially useful if you have several data items to pass, is to use the serialize/deserialize functions in Eu. See test41c for an example. This allows you to pass whole Eu sequences of (mixed) strings & numbers, without regard for data conversions.